Remoting Week: Configuring Remoting

Summary: Richard Siddaway explains how to configure remoting.

Hey, Scripting Guy! Question Hey, Scripting Guy! I’ve just starting learning WindowsPowerShell, and I understand how to use it as a scripting language and shell on the local machine. How do I work with remote machines?


Hey, Scripting Guy! Answer Hello AP,

Honorary Scripting Guy, Richard Siddaway, here today filling in for my good friend, The Scripting Guy. This is the third part in a series of five posts about remoting. The series includes:

  1. Remoting Recap
  2. Remoting Sessions
  3. Configuring Remoting
  4. Remoting security
  5. Non-domain remoting

In the first post, you saw how Windows PowerShell supplies a number of options for individual cmdlets to access remote machines. This was followed in the second post by a look at using Windows PowerShell sessions to give you a reusable connection to the remote machine for efficiency.

In this third post, you will learn about three things:

  • Overcoming the second hop issue
  • Using HTTPS instead of HTTP for your WSMAN connection
  • Configuring endpoints

Overcoming second hop

First off, what’s the second hop issue?

Imagine this scenario…

You’re working on your local machine (Win81) and you need to perform some tasks on two remote machines (Win12R2 and W08R2SQL08).

You can create sessions to both remote machines:

$sessw12 = New-PSSession -ComputerName Win12R2

$sessw08 = New-PSSession -ComputerName W08R2SQL08

And you can run commands against both machines:

Invoke-Command -Session $sessw12 -ScriptBlock {Get-Service}

Invoke-Command -Session $sessw08 -ScriptBlock {Get-Service}

Invoke-Command -Session $sessw12, $sessw08 -ScriptBlock {Get-Service}

Now, if you try to access W08R2SQL08 through a remote session from Win12R2, what will happen?

Invoke-Command -Session $sessw12 -ScriptBlock {Get-Service -ComputerName w08r2sql08}

Cannot open Service Control Manager on computer ‘w08r2sql08’. This operation might require other privileges.

    + CategoryInfo          : NotSpecified: (:) [Get-Service], InvalidOperationException

    + FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.GetServiceCommand

    + PSComputerName        : Win12R2

So you perform a quick test:

Get-Service -ComputerName w08r2sql08

And you discover that it works!

You have just tripped over the second hop issue. You aren’t allowed to remote into one machine and run commands from that machine against other machines. It is essentially a permissions issue in that your credentials haven’t been delegated to the second machine, so it doesn’t have the rights to perform those actions.

There is one caveat to this that I’ve discovered. If the machine you are remoting to is a domain controller, you will be able to run some, but not all, commands against another machine. I haven’t fully explored this, but because it’s not a best practice to use your domain controllers in this manner, I’ll say no more.

How do we overcome this?

The answer is that you have to delegate your permissions to the second machine. This is achieved by using CredSSP.  You get three cmdlets for working with CredSSP:




Enabling CredSSP has to be performed on the local and the remote machine. On the local machine, you enable the client role:

£> Enable-WSManCredSSP -Role Client -DelegateComputer -Force

cfg         :

lang        : en-GB

Basic       : true

Digest      : true

Kerberos    : true

Negotiate   : true

Certificate : true

CredSSP     : true

The Force parameter stops you from being prompted for confirmation. You could use wildcard characters for delegated computers, which could be * for all machines in the domain—or even * for all machines. You can verify the settings:

£> Get-WSManCredSSP

The machine is configured to allow delegating fresh credentials to the following target(s): wsman/

This computer is not configured to receive credentials from a remote client computer.

On the remote machine, you enable the server role:

£> Enable-WSManCredSSP -Role server -Force

cfg               :

lang              : en-US

Basic             : false

Kerberos          : true

Negotiate         : true

Certificate       : false

CredSSP           : true

CbtHardeningLevel : Relaxed

Compare the information from the two commands. The client has all options enabled, but the server is more limited in its authentication options. Again, you can verify the settings:

£> Get-WSManCredSSP

The machine is not configured to allow delegating fresh credentials.

This computer is configured to receive credentials from a remote client computer.

Now re-create the remote session to use CredSSP:

$cred = Get-Credential

$sessw12 = New-PSSession -ComputerName win12r2 -Authentication credssp -Credential $cred

You can then use the session as normal against the remote machine:

Invoke-Command -Session $sessw12 -ScriptBlock {get-service}

You can also utilize the second hop and your CredSSP configuration to access other machines from the target machine:

Invoke-Command -Session $sessw12 -ScriptBlock {get-service -ComputerName w08r2sql08}

Now comes the big question. Just because I can, does it mean I should?

I would recommend against routinely working over the second hop. It weakens the security in your domain because credential delegation is blocked by default. If you find yourself using CredSSP, I would recommend thinking about if there is a better way. If not, use it with care, and remember to disable CredSSP after you have finished.


The second topic on the list is using HTTPS instead of HTTP. This also raises a fair amount of discussion, and I would only see a need for this in a minority of cases. There are a number of steps you need to go through to enable remoting over HTTPS:

  • Obtain an SSL certificate for the server, and make sure it is issued to the FQDN of the host server
  • Install the SSL certificate in the computer’s certificate store (not in the user’s store)
  • Create a new WSMAN listener for HTTPS as follows:

> New-WSManInstance -ResourceURI winrm/config/Listener -SelectorSet @{Transport=’HTTPS’, Address=”IP:″} -ValueSet @{Hostname=””, CertificateThumbprint=”XXXXXXX”}

…where XXXXXXX is the thumbprint of the certificate.

You then connect to the remote server from your client:

$sess = New-PSSession –ComputerName = Win12R2 –UseSSL

Configuring endpoints

The final topic for this part of the series is configuring endpoints. This is another area where you have a lot of options; but in reality, you won’t be using many of them. In my experience, and that of my co-authors of PowerShell in Depth, 99.99% of the time, the standard remoting endpoint configurations will be what you want. The configuration options are for the odd time you step outside of the norm.

How are the standard endpoints configured?

£> Get-PSSessionConfiguration

Name          : microsoft.powershell

PSVersion     : 4.0

StartupScript :

RunAsUser     :

Permission    : BUILTINAdministrators AccessAllowed, BUILTINRemote Management Users AccessAllowed

This is the standard endpoint that you connect to for remoting. The other standard endpoints in later versions of Windows are:




The names explain their purposes rather well. The full configuration of the default endpoint is:

Architecture                  : 64

Filename                      : %windir%system32pwrshplugin.dll

ResourceUri                   :

MaxConcurrentCommandsPerShell : 1000

Capability                    : {Shell}

xmlns                         :

MaxConcurrentUsers            : 5

Name                          : microsoft.powershell

SupportsOptions               : true

ProcessIdleTimeoutSec         : 0

ExactMatch                    : False

RunAsUser                     :

IdleTimeoutms                 : 7200000

OutputBufferingMode           : Block

PSVersion                     : 4.0

SecurityDescriptorSddl        : O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;RM)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)

MaxShellsPerUser              : 25

AutoRestart                   : false

MaxShells                     : 25                                    

MaxIdleTimeoutms              : 2147483647

Uri                           :

SDKVersion                    : 2

XmlRenderingType              : text

RunAsPassword                 :

MaxProcessesPerShell          : 15

ParentResourceUri             :

Enabled                       : true

UseSharedProcess              : false

MaxMemoryPerShellMB           : 1024

lang                          : en-US

Permission                    : BUILTINAdministrators AccessAllowed, BUILTINRemote Management Users AccessAllowed

Having said that, what can you do? You can:

  • Create a restricted language endpoint (only a small subset of the Windows PowerShell language is available)
  • Create a No-Language endpoint (you can’t use any of the Windows PowerShell language; you can only run cmdlets)
  • Restrict who can access the endpoint
  • Restrict which modules can be loaded into the endpoint
  • Define the environment variables to load into the endpoint
  • Define the aliases to be available through the endpoint
  • Define the execution policy
  • Define the Windows PowerShell version
  • Define scripts to run on connection to the endpoint
  • Define the session type:
    Empty: Nothing is loaded.
    Default: Windows PowerShell core commands plus your definitions are loaded.
    Restricted: Seven basic commands, plus what you’ve defined are loaded.

Create the definition file for the endpoint by using New-PSSessionConfigurationFile. You then create the endpoint by using Register-PSSessionConfiguration.

For more information, see the Help files for:





Also, you can discover more about configuring remoting and some other edge cases in Chapter 10 of PowerShell in Depth by myself, Don Jones, and Jeffery Hicks.

Bye for now.


Thanks, Richard. This is a very informative series.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Comments (2)

  1. Paul Bendall says:

    I like remoting and find it very powerful. The second hop is a problem I often face, for example remote to a machine and you want to map a drive. CredSSP helps overcomes this but introduces some significant security issues that must be understood and addressed. One of the major problems with CredSSP is how to pass credentials from the workstation to the server, by default it expects you to provide credentials interactively, meaning it is pretty useless for scripts. Why can't PowerShell / WSMAN support delegation of credentials (kerberos token of the user, in the same way as RDP) rather than having to provide username and password for fresh credentials? (see-…/powershell-remoting-user-profiles-delegation-and-dpapi for more info)

    I think it is also worth pointing out that remoting in this way can also use certificate mapping to remote local user accounts. That means a users certificate on the workstation can be mapped to a local user account on the remote server, authentication is done through passing the certificate thumbprint rather than username and password. The remote session is then running in the context of the user account on the target remote server. Why can't we in Windows world through PowerShell and WSMan have a service and delegation mode akin to *nix SSH?


  2. jrv says:

    @Paul –

    As you have pointed out initially.  CredSSP and delegation create a security hole.  It appears that CredSSP was really intended to be used mostly for non-domain computers.  

    The real issue is delegation.   A CredSSP session is similar to anRDP session.  It is allowed to access a third system and does not appear to be a rem ote session.  As a result the CredSSP session is limited when accessing ther third system. This has been noted by Microsoft as "by design" for security reasons.

    In secure domains CredSSP is disabled by policy.  What is useful to Admins is even more useful to hackers.