Cannot get CredSSP authentication to work in PowerShell

In attempting to create a PowerShell script using remoting I ran into what I believe is the double-hop problem. In that article, Perriman gives a succinct description of the problem as well as the specific steps to resolve the issue (almost trivial if you know the commands, but for someone less familiar like myself, that information was invaluable!).

I ran Enable-WSManCredSSP Server on my Win7 server without incident, but attempting to run Enable-WSManCredSSP Client –DelegateComputer <FQDN of the server> on my Win7 client generated this error:

Enable-WSManCredSSP : The client cannot connect to the destination specified
in the request. Verify that the service on the destination is running and
is accepting requests.
Consult the logs and documentation for the WS-Management service running
on the destination, most commonly IIS or WinRM. If the destination
is the WinRM service, run the following com mand on the destination
to analyze and configure the WinRM service: "winrm quickconfig".

Running winrm quickconfig confirmed my server was running WinRM:

WinRM already is set up to receive requests on this machine.
WinRM already is set up for remote management on this machine.

And Get-WSManCredSSP confirmed my server was ready to accept credentials from a client:

The machine is not configured to allow delegating fresh credentials.
This computer is configured to receive credentials from a remote client computer.

I also found Boessen's article on WinRM wherein he describes general WinRM setup and found one tidbit to get a useful data point in diagnosis; this command run on the client uses the winrs tool to remotely access the server:

winrs -r:http://<FQDN of my server>:5985 -u:<myDomain>\msorens "dir c:\"

That command returned the expected result, the contents of the root directory on the server, without incident, confirming that my FQDN is correct and that WinRM is enabled.

Boessen indicates port 5985 is the default for Win7; this command run on the server confirms a value of 5985:

get-item wsman:\localhost\listener\listener*\port

The question: Why am I unable to execute the Enable-WSManCredSSP command on the client side?


2011.06.07 Update

I found a solution to the above question: invoking Enable-PSRemoting, advertised to configure a computer to receive remote commands, allowed the Enable-WSManCredSSP on the client to work successfully! Curious, but its man page indicates it does a number of different actions, so I assume one of those inadvertantly did what I needed.

But then I reached another roadblock when I attempted to use CredSSP authentication. Here is the command:

Invoke-Command { Write-Host "hello, world" } -computername $serverName `
-credential $testCred  -Authentication Credssp

And here is the response:

Connecting to remote server failed with the following error message:
The WinRM client cannot process the request. A computer policy does not allow
the delegation of the user credentials to the target computer. Use gpedit.msc
and look at the following policy: Computer Configuration
-> Administrative Templates -> System -> Credentials Delegation
-> Allow Delegating Fresh Credentials.  Verify that it is enabled and
configured with an SPN appropriate for the target computer. For example,
for a target computer name "myserver.domain.com", the SPN can be one of
the following: WSMAN /myserver.domain.com or WSMAN/*.domain.com.
For more information, see the about_Remote_Troubleshooting Help topic.

I verified the settings just as this remarkably helpful error message suggested, and it looks to me like it is configured properly.

The new question: What does this remote connection attempt with CredSSP fail?


In answering please keep the following in mind: Let me dispell in advance any notion that I know what I am doing here, any appearance to the contrary notwithstanding.:-) Windows admin is not my area of expertise!


Solution 1:

I came back to this after a brief hiatus to look again with fresh eyes (both mine and a co-worker) and decided to go back to the basics again:

On the client I executed (in administrator shell):

enable-wsmancredssp -role client -delegatecomputer devremvm03 -force

On the server I executed (in administrator shell):

enable-wsmancredssp -role server -force

Both returned normal output indicating CredSSP was now "true".

I then used the following exerciser code to walk through increasing levels of complexity:

$block = {
  Write-Host ("hello, world: {0}, {1}" -f $env:USERNAME, (hostname))
}
$username = "test_user"
$password = "..."   
$adjPwd = $password | ConvertTo-SecureString -asPlainText -Force
$testCred = (New-Object System.Management.Automation.PSCredential($username,$adjPwd))    

switch ($choice)
{
  "basic"       { Invoke-Command $block }
  "remote"      { Invoke-Command $block -computername $serverName }
  "credentialA" { Invoke-Command $block -computername $serverName -credential $testCred  }
  "credentialB" { Invoke-Command $block -computername $serverName -credential $testCred  -Authentication Credssp}
  "session"     { 
      $testSession = New-PSSession -computername $serverName -credential $testCred -Authentication Credssp
      if ($testSession) { Invoke-Command $block -Session $testSession; Remove-PSSession $testSession }
      }
}

All of that is in my run.ps1 script so the transcript went as follows (and this ran in a non-administrator shell):

PS C:\> .\run.ps1 basic
hello, world: msorens, MyLocalMachine
PS C:\> .\run.ps1 remote MyRemoteServer
hello, world: msorens, MyRemoteServer
PS C:\> .\run.ps1 credentialA MyRemoteServer
hello, world: test_user, MyRemoteServer
PS C:\> .\run.ps1 credentialB MyRemoteServer
hello, world: test_user, MyRemoteServer
PS C:\> .\run.ps1 session MyRemoteServer
hello, world: test_user, MyRemoteServer

Previously, only basic, remote, and credentialA worked. Now all 5 work. Whew!

Solution 2:

When I had to do this, this is what I did to get it working (there may also have been some GPO settings, but it looks like you've got those covered).

To enable the CLIENT to use CredSSP to connect to any machine in the domain:

Enable-WSManCredSSP -Role Client -DelegateComputer "*.my.domain.com" -Force | out-null
#the following is used because -delegatecomputer (above) doesn't appear to actually work properly.
Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\Credssp\PolicyDefaults\AllowFreshCredentialsDomain -Name WSMan -Value "WSMAN/*.my.domain.com"

Then I ran the following on each target machine (server) to enable the CredSSP authentication:

Connect-WSMan -ComputerName $computer 
Set-Item "WSMAN:\$computer\service\auth\credssp" -Value $true 

This of course requires that you're running the script with appropriate permissions. This worked for me -- I hope it helps you out.

Solution 3:

I got where I could live migrate a VM from one hyper-v 2012R2 server to another, but could not migrate it back. (I'm trying to use SAMBA 4.2 as my domain controller and wanted to see if I could live migrate with CredSSP as I couldn't use constrained delegation with Samba4).

Ultimately I went to the working hyper-v and copied the registry entries at hklm:\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation to the non-working hyper-v. Worked fine both ways after that.