mandag den 21. marts 2011

WinRM Remote Management and PowerShell certificates

So I was playing around with DNS. I am configurering that remote though PowerShell. After I had most things working tested against NS1 I wanted to start working on the secondary Zone’s on NS2 and NS3 and started getting

$PSSession = New-PSSession -auth CredSSP -cred $cred -ComputerName ns2 -UseSSL;

[ns2] Connecting to remote server failed with the following error message : The WinRM client received an HTTP server error status (500), but the remote service did not include any other information about the cause of the failure. For more information, see the about_Remote_Troubleshooting Help topic.
    + CategoryInfo          : OpenError: (System.Manageme....RemoteRunspace:RemoteRunspace) [], PSRemotingTransportException
    + FullyQualifiedErrorId : PSSessionOpenFailed

That’s weird, I know it was configured. Ive been playing around with certificates while configurering SCOM 2007 so I knew all the certificates might not be there, so I decided to reconfigure it all. Looking in the event log on the remote machine NS2 I also found

The WinRM service failed to initialize CredSSP.

Additional Data
The error received was 0x80338082.

User Action
Configure CertificateThumbprint setting under the WinRM configuration for the service. Use the thumbprint of a valid certificate and make sure that Network Service has access to the private key of the certificate.

Searching google for that error kept mentioning making sure to use the right certificate. Sure enough, the listener was using a certificate that wasn’t there. ( run “winrm enumerate winrm/config/listener” and check the CertificateThumbprint against the certificates in the local machine MY store )

so I decided to just run my initial powershell script

winrm delete winrm/config/listener?Address=*+Transport=HTTP
winrm delete winrm/config/listener?Address=*+Transport=HTTPS
winrm quickconfig -transport:http
winrm quickconfig -transport:https
Enable-WSManCredSSP -Role server

But no use, I was still getting the above error. Then I looked at the permissions of the certificates and sure enough “network services” didn’t have permissions. ( MMC –> CTRL+M –> Certificates –> Computer account ) ( Personal –> Certificates –> Right click certificate –> All tasks –> Manage Private Keys ..”  ) By the way several sites recommend using “Find Private Key tool” from WCF SDK. No need to do that, powershell is your friend here.

I was still getting the error. then it hit me … The Service also have a CertificateThumbprint ( run “winrm get winrm/config” )

So I wrapped it all up in a little script.

# Get local computer name and FQDN
$computername = get-content  env:computername
$objIPProperties = [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()
$fqdn = "{0}.{1}" -f $objIPProperties.HostName, $objIPProperties.DomainName
$fqdn = $fqdn.ToLower()

# works like a charm if only one certificate is in the the store.
winrm quickconfig -quiet -transport:http
winrm quickconfig -quiet -transport:https

# allow basic authentication
winrm p winrm/config/service '@{AllowUnencrypted="true"}'
winrm p winrm/config/service/auth '@{Basic="true"}'

# Get all local certificates with computer name/fqdn and grant network service permissions on it
$certs = dir cert:\LocalMachine\my
ForEach($cert in $certs){
    if( ($cert.Subject -eq ('CN=' + $computername)) -or ($cert.Subject -eq ('CN=' + $fqdn))){
        Write-Host ("fix permissions on " + $cert.Thumbprint + " " + $cert.Subject)
        $location = $cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
        $folderlocation = gc env:ALLUSERSPROFILE
        $folderlocation = $folderlocation + "\Microsoft\Crypto\RSA\MachineKeys\"
        $filelocation = $folderlocation + $location
        #icacls $filelocation /grant "Network service:(OI)(CI)(F)"
        icacls $filelocation /grant "Network service:(F)"
    }
}

# Force listener and service to use last known good certificate
winrm set winrm/config/Listener?Address=*+Transport=HTTPS ('@{CertificateThumbprint="' + $cert.Thumbprint + '"}')
winrm p winrm/config/service ('@{CertificateThumbprint="' + $cert.Thumbprint + '"}')

# if first time run, set the role to server
Enable-WSManCredSSP -Role server

Ingen kommentarer:

Send en kommentar