Recently I was working on a script in my lab and I run into the double-hop delegation problem. I love the idea of running server core servers and managing them from a client using Remote Server Administrator Tools and PowerShell remoting. In most cases, when I use Invoke-Command or Enter-PSSession to execute cmdlets on remote servers, I have no problems with delegation, because only one hop is involved. My plans break when I try to access a file share on a different server within the session. The problem is, that Windows by default doesn’t allow the remote server to delegate my credentials to yet another computer, even if I have permission to access its shared resource. This is the 2nd hop. If you’re someone just learning systems administration like me, you know how frustrating those ugly error messages are, especially when you’ve done everything exactly the way it is supposed to be done.
First of all, we have to make sure that PowerShell remoting is enabled for all computers, including the management client. In Windows Server 2012 it is enabled by default, but we have to run Enable-PSRemoting on clients to turn it on. If the client has only one network adapter connected to the domain network, that’s all we need. However, as in my case, the client is also connected to the internet via an external virtual switch. This connection has a public network profile and we have to use the SkipNetworkProfileCheck switch to make remoting work in this situation:
Enable-PSRemoting -SkipNetworkProfileCheck
For a thorough explanation, see help Enable-PSRemoting.
Next, we have to enable CredSSP authentication on the client and the remote server. Run these cmdlets from the client:
# enables the client side to delegate credentials to remote servers in the domain Enable-WSManCredSSP -Delegate *.domain.com -Role Client -Force # enables to view and edit the WSMan drive on the remote server Connect-WSMan Server1 # allows delegation for the remote server Set-Item WSMan:\Server1*\Service\Auth\CredSSP -Value $true
Then we have to configure a session. In my lab, I always save the password and the credential in variables, because I don’t like having to type these each time need them.
$pw = ConvertTo-SecureString -AsPlainText -Force -String "P@ssw0rd!" $cred = New-Object -TypeName System.Management.Automation.PSCredential -Argumentlist "contoso\Administrator",$pw $session = New-PSSession -ComputerName Server1.contoso.com -Credential $cred -Authentication Credssp
Next, we can run Invoke-Command using this session and see if we can access the file share:
Invoke-Command -Session $session -ScriptBlock {Test-Path \\Server2\Share1}
There is an explanation and example in the help file of Invoke-Command, see example 15. However, running Invoke-Command the way it’s used there, I always get an error telling me that the parameter set cannot be resolved. Strange.
I solved the problem by merging this example with this solution from ED Wilson.
And now, it should just work right? Nooooooo. When I try to create the session in the $session variable, I get this pretty error:
Thankfully, the solution is right there. We need to enable, edit and link a GPO to the domain: Computer Configuration -> Policies -> Administrative Templates -> System -> Credentials Delegation -> Allow delegating fresh credentials with NTLM-only server authentication.
Based on my experience, it’s not enough to sign out of the client to have the GPO applied, but you have to reboot the computer.
Then, when I run Invoke-Command to access the file share from the remote server, everything works fine. Just don’t forget that the naming in the GPO and New-PSSession has to correspond.


Leave a Reply