<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1678611822423757&amp;ev=PageView&amp;noscript=1">
Defrag This

| Read. Reflect. Reboot.

The Infamous Double-Hop Problem in PowerShell

Adam Bertram| August 16 2018

| IT insights

the-infamous-double-hop-problem-in-powershell

In this article, we will discuss how to get around the infamous double-hop problem in PowerShell. It's easier than you think.

When you're in a PowerShell Remoting session and attempt to access a resource outside of that remote computer, you may run into an Access Denied error message. You've already authenticated to the remote session with your username and password, and you have permission to access the network resource you're connecting to. It can be frustrating.

Below is an example of what you may run into.

Using PowerShell Remoting to Connect to a SRV1 Computer

In this example, we're using PowerShell Remoting to connect to the SRV1 computer. While in that session, we're then attempting to browse files on the root of the C drive on the SRV2 computer. It's not working out too well though.

PS> 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

This example isn't working because PowerShell isn't seamlessly passing the credential we authenticated with (in this case using Kerberos) to the remote resource. This isn't a bug but a security feature.

Learn how to automate IT tasks with PowerShell. Download this eBook. 

If you Google this error, you'll find lots of examples of people "solving" it by using CredSSP. This is supposed to be insecure and also requires additional configuration ahead of time. I recently discovered a new way to solve this problem which uses session configurations. This "new" way allows you to tie a credential to a PowerShell session configuration and reuse this configuration for all future connections.

Let's see how we can fix this without using CredSSP. First, we'll connect to the SRV1 computer again and register a session configuration on it using a a domain account. This ensures that when we connect using this session configuration, it will always authenticate with this user.

Invoke-Command -ComputerName SRV1 -ScriptBlock { Register-PSSessionConfiguration -Name Ipswitch -RunAsCredential 'lab.local\account' -Force }

Once we have the session configuration created, we can then just specify that session configuration using the ConfigurationName parameter. This then forces PowerShell to use the domain account I provided earlier. You can see below that I now can successfully browse to the network resource from within the remote SRV1 session.

PS> Invoke-Command -ComputerName 'SRV1' -ScriptBlock { Get-ChildItem -Path \\SRV2\c$ } -ConfigurationName Ipswitch.

    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
<snip>

Notice that we didn't have to use the Authenticate parameter to specify CredSSP. The only parameter we need to use is ConfigurationName and specify the name of the session configuration I had created on the SRV1 computer.

This method is a great alternative to using the known insecure method of using CredSSP. It allows you to use native tooling without a lot of workarounds. The only caveat is that you must always remember to use the ConfigurationName parameter every time. But, you'd have to remember to use the Authentication parameter every time anyway when using CredSSP.

If you wanted to, you could always use $PSDefaultParameterValues = @{'Invoke-Command:ConfigurationName'='Ipswitch' } to default that parameter value, but if you're like me you might forget you're using that parameter value for every Invoke-Command call!

Topics: IT insights

Leave a Reply

Your email address will not be published. Required fields are marked *

THIS POST WAS WRITTEN BY Adam Bertram

Adam Bertram is a 20-year veteran of IT. He’s currently an automation engineer, blogger, independent consultant, freelance writer, author, and trainer. Adam focuses on DevOps, system management, and automation technologies as well as various cloud platforms. He is a Microsoft Cloud and Datacenter Management MVP and efficiency nerd that enjoys teaching others a better way to leverage automation.

Free Trials

Getting started has never been easier. Download a trial today.

Download Free Trials

Contact Us

Let us know how we can help you. Focus on what matters. 

Send us a note

Subscribe to our Blog

Let’s stay in touch! Register to receive our blog updates.