Getting started with AWS Tools for PowerShell How to configure SSL on IIS with PowerShell

How to avoid the double-hop problem with PowerShell

IT pros who manage with PowerShell will run into the double-hop problem and use CredSSP to work around it. This tutorial offers a more streamlined way to avoid that roadblock.

PowerShell remoting works great to manage remote servers, until you run headfirst into the dreaded double-hop problem. 

In a typical scenario, you're working on one remote machine, then attempt to run a PowerShell command against a different server, but get hit with an access denied message. You can use CredSSP to get around this double-hop problem, but there's a better solution you can try.

Why the double-hop problem happens

After you connect to a remote computer with PowerShell remoting and attempt to issue commands to a resource outside that computer, you might receive this message:

Invoke-Command -ComputerName SRV1 -ScriptBlock { Get-ChildItem -Path \\SRV2\c$ }
Access is denied
    + CategoryInfo          : PermissionDenied: (\\SRV2\c$:String) [Get-ChildItem], UnauthorizedAccessException
    + FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
    + PSComputerName        : SRV1

Cannot find path '\\SRV2\c$' because it does not exist.
    + CategoryInfo          : ObjectNotFound: (\\SRV2\c$:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
    + PSComputerName        : SRV1

You might think it should have worked because you authenticated credentials on the remote computer and those credentials have permissions to access the second remote computer. However, Active Directory domains use Kerberos for authentication, which does not allow passing credentials beyond the first machine to prevent malicious activity.

Some administrators solve the double-hop problem with CredSSP, which is a less-secure method that requires some additional configuration work.

Some administrators solve the double-hop problem with CredSSP, which is a less-secure method that requires some additional configuration work. But there is another option. You can tie a credential to a PowerShell session configuration and reuse the configuration for all future connections.

Set new PowerShell session configurations to accept credentials

For this example, we will work with a server named SRV1 and create a new session configuration on this machine using the Register-PSSessionConfiguration cmdlet. The command below creates a session called Demo and uses the RunAsCredential parameter to run the session.

Invoke-Command -ComputerName SRV1 -ScriptBlock { Register-PSSessionConfiguration -Name Demo -RunAsCredential 'domain\mydomainaccount' -Force }

RunAsCredential parameter warning
PowerShell returns this warning about the RunAsCredential parameter.

This command creates a new session configuration on the remote computer and, when connected, forces it to always run with the credential provided.

Next, specify the configuration with the ConfigurationName parameter when running Invoke-Command. Use the same command as above, but with the Demo configuration. Use this session configuration the next time you run a command on a remote computer that connects to a third computer.

Invoke-Command -ComputerName 'SRV1' -ScriptBlock { Get-ChildItem -Path \\SRV2\c$ } -ConfigurationName Demo

    Directory: \\SRV1\c$

Mode    LastWriteTime         Length Name                 PSComputerName
----   -------------         ------ ----                  --------------
d-----  11/30/2016  11:35 AM    Program Files            SRV1
d-----  5/25/2017  11:32 AM     Windows                  SRV1

Instead of an access denied message, the command runs as expected. There's no need to use CredSSP roles on the client or the server to avoid the double-hop problem. The configuration will stay indefinitely on the remote server. Just use the ConfigurationName parameter each time you use Invoke-Command or Enter-PSSession.

Automatically invoke the ConfigurationName parameter

Now that we've solved this PowerShell remoting issue, you can make it work in a more streamlined fashion. With the $PSDefaultParameterValues automatic variable, you can avoid using the ConfigurationName parameter each time. You can program PowerShell to use a certain parameter when using a specific command.

Use the ConfigurationName parameter and specify the value of the session Demo every time you call Invoke-Command. To do that, create the $PSDefaultParameterValues hash table and assign it a key of Invoke-Command:ConfigurationName and a value of Demo as shown below.

$PSDefaultParameterValues = @{'Invoke-Command:ConfigurationName'='Demo' }

All these techniques should help you work more efficiently when using PowerShell to work with remote machines.

Next Steps

Build a PowerShell logging function for troubleshooting

What's new with PowerShell error handling?

Dig Deeper on IT operations and infrastructure management

Cloud Computing
Enterprise Desktop
Virtual Desktop