Remote PSSession Over SSL

One of the interesting features of *NIX based systems is the ability to remotely administer a server using SSH. However as you’ve probably noticed this blog is very much about Powershell. Turns out that you can indeed run a remote Powershell session to administer a Windows system remotely.

Now one of the issues that can come up is by default, Powershell remote access is setup to listen on HTTP. Since HTTP is insecure, WinRM expects Kerberos authentication, or that the computer be joined to a domain. Now if you don’t have Kerberos and you’re not a part of the domain, the following options are recommended:

ERROR: The WinRM client cannot process the request. If the
authentication scheme is different from Kerberos, or if the client
computer is not joined to a domain, then HTTPS transport must be used
or the destination machine must be added to the TrustedHosts
configuration setting.

When the local computer is not in a domain, the following procedure is required
for remoting.

1. Configure the computer for HTTPS transport or add the names of the
remote computers to the TrustedHosts list on the local computer.

For instructions, see “How to Add a Computer to the TrustedHosts
List” below.

2. Verify that a password is set on the workgroup-based computer. If a
password is not set or the password value is empty, you cannot run
remote commands.

To set password for your user account, use User Accounts in Control

3. Use the Credential parameter in all remote commands.

This is required even when you are submitting the credentials
of the current user.

Note that points 2 and 3 assume you’ve already got a working connection. While you can definitely add the user to the Trusted Hosts list as it mentions, you’re still sending information over an unsecured protocol. There’s always the option of requiring IPSec communication using Windows Advanced Firewall, but then you have the possibility of the IP of the machine changing. Finally you have to add an entry for each computer you want to give access to. Instead we will use the other method, which is enabling HTTPS transport for our Powershell session. Before going into the details, here are some requirements:

  • I describe how to do this with an admin user, but at the end I’ll note how to enable a non-admin user remote Powershell access
  • The HTTPS port (5986) will need to be open for connections
  • You will need access to the server physically or through remote desktop
  • A valid SSL certificate is required (trusted by your machine, has a certificate revocation list, the root cert authority needs to be trusted)

Finally as a word of caution, this will allow a machine to remotely run commands on the server. This has security implications, so make sure safeguards are in place (strong passwords, firewall settings, etc.). To start out, Powershell remote access needs to be enabled on the server. Login to the server as a user with the proper permissions, open up Powershell, then run the following command:

Note: As the help for Enable-PSRemoting notes:

To run this cmdlet on Windows Vista, Windows Server 2008, and later versions of Windows, you must start Windows PowerShell with the “Run as administrator” option.

> Enable-PSRemoting

Get-Help Enable-PSRemoting describes what the command behind the scenes:

— Runs the Set-WSManQuickConfig cmdlet, which performs the following tasks:

—– Starts the WinRM service.

—– Sets the startup type on the WinRM service to Automatic.

—– Creates a listener to accept requests on any IP address.

—– Enables a firewall exception for WS-Management communications.

— Enables all registered Windows PowerShell session configurations to receive instructions from a remote computer.

—– Registers the “Microsoft.PowerShell” session configuration, if it is not already registered.

—– Registers the “Microsoft.PowerShell32” session configuration on 64-bit computers, if it is not already registered.

—– Removes the “Deny Everyone” setting from the security descriptor for all the registered session configurations.

—– Restarts the WinRM service to make the preceding changes effective.

While the WinRM setup being done behind the scenes is nice, it still sets up the listener for the HTTP transport. Fortunately the winrm command can be used to manage transports, listening, etc. First a valid certificate thumbprint is needed to enable the HTTPS listener. The Microsoft Management Console (mmc) provides an easy way to do this. Run mmc through the Start -> Run... command:

MMC Main Window

Next, go to File -> Add/Remove Snap-in to get this window:

MMC Add/Remove Snap-in Window

Where you select Certificates as shown. Next click on the Add > button to bring up this window:

MMC Certificate Snap-in Wizard

Where you will want to select Computer Account as shown. Click Next, then Finish to accept the default of Local Computer. Finally click Okay at the Snap-ins window:

MMC Cert Snap-in Added

Find the certificate you want and double click it to view details. In this example I’ll use the certificate of a certificate authority server I have setup:

Certificate Detail

Take note of the hostname (in this example TACHIBANA-CA), as WinRM requires it match exactly when setting up the HTTPS transport. Now go to the Details tab:

Certificate Thumbprint

Selecting <All> from Show, then navigating down to the Thumbprint field. This thumbprint value is what is needed for the WinRM command to indicate the SSL certificate that is sent to the client. Now WinRM can be setup to use the HTTPS transport. Make sure the Hostname value matches the CN of the SSL certificate EXACTLY. That means if you have a wildcard CN like *, you have to enter * for the Hostname value:

PS C:\Users\Administrator> winrm create winrm/config/listener?Address=*+Transport=HTTPS `@`{Hostname=`"`TACHIBANA-CA`"`; CertificateThumbprint=`"`8c a0 57 4c 9b 24 24 f0 52 65 0e ce 64 04 83 26 2a 68 5a 86`"`}
    Address =
        ResourceURI =
            Selector: Address = *, Transport = HTTPS

Since this is run in Powershell, notice that the quotes and @ symbol are enclosed in backticks(`) for escaping. Also note that the “*” for the Address value. This indicates that WinRM will bind to all interfaces. A specific interface can be bound to by changing the * to an IP such as The HTTPS transport will bind to port 5986, so a firewall exception will need to be added. This can be done using the netsh command (note this is on Windows 2008 Server R2):

> netsh advfirewall firewall add rule name="WinRM (HTTPS)" protocol=TCP dir=in localport=5986 action=allow

Finally if you only plan to use the HTTPS transport, you can disable the HTTP transport using the following command:

> winrm set winrm/config/Listener?Address=*+Transport=HTTP `@`{Enabled=`"`ffalse`"`}
    Address = *
    Transport = HTTP
    Port = 5985
    Enabled = false
    URLPrefix = wsman
    ListeningOn = null

The ffalse is not a typo and could potentially be a bug. Try it with “false” to see if it works for you. With the setup complete, remote Powershell access can now be tested. On a client machine:

> Enter-PSSession -Computer TACHIBANA-CA -Credential TACHIBANA\Administrator -UseSSL
[TACHIBANA-CA]: PS C:\Users\Administrator\Documents>

The value of “-Computer” is set to the same Hostname we provided. “-Credential” indicates the user we wish to login as, in this case the Administrator of the TACHIBANA server. Finally “-UseSSL” lets Powershell know to use the HTTPS port (5986) instead of the HTTP port (5985) when connecting. To end the session when you’re done running commands:

[TACHIBANA-CA]: PS C:\Users\Administrator\Documents> Exit-PSSession

Hopefully this provides you with information needed to setup a remote Powershell session over HTTPS. Should any issues come up, be sure to checkout Get-Help about_Remote_Troubleshooting for some possible solutions.

Note: in order to get non-admin access to work:

To establish a PSSession or run a command on a remote computer, the user
must have permission to use the session configurations on the remote

By default, only members of the Administrators group on a computer have
permission to use the default session configurations. Therefore, only
members of the Administrators group can connect to the computer remotely.

To allow other users to connect to the local computer, give the user
Execute permissions to the default session configurations on the local

The following command opens a property sheet that lets you change the
security descriptor of the default Microsoft.PowerShell session
configuration on the local computer.

Set-PSSessionConfiguration Microsoft.Powershell -ShowSecurityDescriptorUI


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: