In this guide, you will learn how to use Enter-PSSession and Invoke-Command to securely manage remote Windows machines with PowerShell over HTTPS using a self-signed SSL certificate that we create with PowerShell.
Latest posts by Michael Pietroforte (see all)

Many PowerShell blogs like to mention that WinRM encrypts data and is therefore secure even if you only work with HTTP (which is the default configuration) and not with HTTPS. Indeed, Microsoft’s documentation for Invoke-Command confirms that WS-Management encrypts all transmitted PowerShell data. (An older version of WinRM on Windows Server 2003 R2 doesn’t encrypt.) Unfortunately, if not configured properly, PowerShell Remoting is insecure and it some cases you need to change the default configuration.

Allowing unencrypted PowerShell Remoting

First, it is possible to allow unencrypted WS-Management communication. This command configures the WinRM service to allow unencrypted traffic (you need an elevated console as for most things we do in this post):

winrm set winrm/config/service '@{AllowUnencrypted="true"}'

Allowing unencrypted WSMan traffic on the server

Allowing unencrypted WSMan traffic on the server

And this one does the same on the client side:

winrm set winrm/config/client '@{AllowUnencrypted="true"}'

Even though WS-Management encrypts all traffic by default, it is possible that someone (unknowingly) transmits unencrypted data because the default configuration has been changed. I guess this is why this Microsoft article about WinRM warns that “under no circumstances should unencrypted HTTP requests be sent through proxy servers.”

Allowing unencrypted WSMan traffic on the client

Allowing unencrypted WSMan traffic on the client

To check how your machines are configured, you can run this command:

winrm get winrm/config

Check WinRM configuration

Checking WinRM configuration

You can also view the configuration in PowerShell:

dir WSMan:\localhost\Service | ? Name -eq AllowUnencrypted
dir WSMan:\localhost\Client | ? Name -eq AllowUnencrypted

Why HTTPS with Invoke-Command and Enter-PSSession

The second and, in my view, bigger problem is that, if you are working with machines that are not in an Active Directory domain, you don’t have any trust relationship with the remote computers. You are then dealing only with symmetric encryption, so man-in-the-middle attacks are theoretically possible because the key has to be transferred first.

In a previous post, I explained that you have to add the remote machines that are not in an Active Directory domain to your TrustedHosts list on the client. However, you don’t improve security just by “defining” IP addresses or computer names as trustworthy. This is just an extra hurdle that Microsoft added so you know that you are about to do something risky.

This is where PowerShell Remoting via SSL comes in. For one, HTTPS traffic is always encrypted. Thus, you can always automate your tasks remotely, free of worry. And, because SSL uses asymmetric encryption and certificates, you can be sure that you are securely and directly connected to your remote machine and not to the computer of an attacker that intercepts and relays your traffic.

On the downside, configuring PowerShell Remoting for use with SSL is a bit more difficult than just running Enable-PSRemoting. Quite a few tutorials exist that explain how to use HTTPS with Enter-PSSession and Invoke-Command, and most of them make this task appear unnecessarily complicated.

The main problem is that you need an SSL certificate. If you just want to manage some standalone servers or workstations, you probably don’t like to acquire a publicly-signed certificate and want to work with a self-signed certificate instead.

Because many of these guides predate PowerShell 4, they recommend using IIS Manager or download tools such as OpenSSL or the Windows SDK, which contains makecert.exe and pvk2pfx.exe that you can use to create a self-signed certificate. I suppose these guides deter many admins from working with SSL and so they choose the easier way of running Invoke-Command and Enter-PSSession over HTTP.

However, you will now see that enabling SSL for WinRM on the client and on the server is not so difficult (although it is not as straightforward as with SSH), and you can do it all with PowerShell’s built-in cmdlets. You don’t even need the notorious winrm Windows command-line tool.

Enabling HTTPS for PowerShell Remoting

On the remote computer

The first thing we need to do is create an SSL certificate. (Note that this guide focuses on the usage of a self-signed certificate. If you have a publicly-signed certificate, things are easier and you can use Set-WSManQuickConfig -UseSSL.)

As mentioned above, since the release of PowerShell 4, we don’t require third-party tools for this purpose. The New-SelfSignedCertificate cmdlet is all we need:

$Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName "myHost"

It is important to pass the name of the computer that you want to manage remotely to the ‑DnsName parameter. If the computer has a DNS name, you should use the fully qualified domain name (FQDN).

If you want to, you can verify that the certificate has been stored correctly using the certificate add-in of the Microsoft Management Console (MMC). Type mmc on the Start screen and add the Certificates add-in for a computer account and the local computer. The certificate should be in the Personal\Certificates folder. The name of my test computer was “win81.”

Certificate in MMC on the remote computer

Certificate in MMC on the remote computer

We now have to export the certificate to a file because we will have to import it later on our local machine. You can do this with the MMC add-in, but we’ll do it in PowerShell:

Export-Certificate -Cert $Cert -FilePath C:\temp\cert

The file name doesn’t matter here.

We need the certificate to start the WS-Management HTTPS listener. But we should first enable PowerShell Remoting on the host:

Enable-PSRemoting -SkipNetworkProfileCheck -Force

As I’ve learned recently, -SkipNetworkProfileCheck ensures that PowerShell won’t complain if your network connection type is set to Public.

Enable-PSRemoting also starts a WS-Management listener, but only for HTTP. If you want to, you can verify this by reading the contents of the WSMan drive:

dir wsman:\localhost\listener

Listing WSMan listeners

Listing WSMan listeners

To ensure that nobody uses HTTP to connect to the computer, you can remove the HTTP listener this way:

Get-ChildItem WSMan:\Localhost\listener | Where -Property Keys -eq "Transport=HTTP" | Remove-Item -Recurse

This command removes all WSMan listeners:

Remove-Item -Path WSMan:\Localhost\listener\listener* -Recurse

Next, we add our WSMan HTTPS listener:

New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint –Force

Adding a WSMan HTTPS listener

Adding a WSMan HTTPS listener

We are using the $Cert variable that we defined before to read the Thumbprint, which allows the New-Item cmdlet to locate the certificate in our certificates store.

The last thing we have to do is configure the firewall on the host because the Enable-PSRemoting cmdlet only added rules for HTTP:

New-NetFirewallRule -DisplayName "Windows Remote Management (HTTPS-In)" -Name "Windows Remote Management (HTTPS-In)" -Profile Any -LocalPort 5986 -Protocol TCP

Notice here that we allow inbound traffic on port 5986. WinRM 1.1 (current version is 3.0) used the common HTTPS port 443. You can still use this port if the host is behind a gateway firewall that blocks port 5986:

Set-Item WSMan:\localhost\Service\EnableCompatibilityHttpsListener -Value true

Of course, you then have to open port 443 in the Windows Firewall. Note that this command won’t work if the network connection type on this machine is set to Public. In this case, you have to change the connection type to private:

Set-NetConnectionProfile -NetworkCategory Private

For security reasons, you might want to disable the firewall rule for HTTP that Enable-PSRemoting added:

Disable-NetFirewallRule -DisplayName "Windows Remote Management (HTTP-In)"

Our remote machine is now ready for PowerShell Remoting via HTTPS, and we can configure our local computer.

On the local computer

Things are a bit easier here. First, you have to copy the certificate file to which we exported our certificate. You can then import the certificate with this command:

Import-Certificate -Filepath "C:\temp\cert" -CertStoreLocation "Cert:\LocalMachine\Root"

Note that we need to store the certificate in the Trusted Root Certification Authorities folder here and not in the Personal folder as we did on the remote computer. Your computer “trusts” all machines that can prove their authenticity with the help of their private keys (stored on the host) and the certificates stored here.

Certificate in MMC on the local computer

Certificate in MMC on the local computer

By the way, this is why we don’t have to add the remote machine to the TrustedHosts list. In contrast to PowerShell Remoting over HTTP, we can be sure that the remote machine is the one it claims to be, which is the main point of using HTTPS instead of HTTP.

We are now ready to enter a PowerShell session on the remote machine via HTTPS:

Enter-PSSession -ComputerName myHost -UseSSL -Credential (Get-Credential)

The crucial parameter here is -UseSSL. Of course, we still have to authenticate on the remote machine with an administrator account.

You might receive this error message:

The SSL certificate is signed by an unknown certificate authority.

In that case you can just add the the -SkipCACheck parameter. (See comments below.)

The Invoke-Command cmdlet also supports the -UseSSL parameter:

Invoke-Command -ComputerName myHost -UseSSL -ScriptBlock {Get-Process} -Credential (Get-Credential)

If your remote host doesn’t have a DNS entry, you can add its IP to the hosts file on your local computer. To do so, open an elevated Notepad and then navigate to %systemroot%\system32\drivers\etc\. Of course, you can also do it the PowerShell if you are working on an elevated console:

Add-Content $Env:SystemRoot\system32\drivers\etc\hosts " myHost"

You will have to reboot after that. I have my own private DNS server in the cloud for such cases.


Admittedly, the post got a bit longer than I planned. However, once you know how it works, you can complete the entire procedure to configure PowerShell Remoting for HTTPS in a couple of minutes. You just create a self-signed SSL certificate on the host and start an HTTPS listener using this certificate. Then, you create the corresponding firewall rule and export the certificate. On the local computer, you only have to import the certificate.

HTTPS doesn’t just add another encryption layer; its main purpose is to verify the authenticity of the remote machine, thereby preventing man-in-the-middle attacks. Thus, you only need HTTPS if you do PowerShell Remoting through an insecure territory. Inside your local network, with trust relationships between Active Directory domain members, WSMan over HTTP is secure enough.

  1. Ivan Gonzalez 8 years ago

    Just in case you are not generating the certificate because you are simply copying among servers, for example, you will need to add an extra step just before adding the WSMan listener:

    $Cert = Get-PfxCertificate -FilePath .\your-pfx.pfx

    By the way; I do not know how to export the certificate using powershell, but it is easy to export using “mmc” and adding the snap-in “certification”

  2. Ivan Gonzalez 8 years ago

    Oh, and many thanks to write a clear and very good post thinking on those guys like us that like to script as much as possible instead using the GUIs.

  3. Ivan, the procedure I described is just doing this, that is, it copies the certificate from one machine to another. First the certificate is exported with Export-Certificate and then it is imported on the second machine with Import-Certificate. You don’t really need the MMC.

  4. Math 7 years ago


    Is possible to request certficate and store in Machine Container using certreq?

  5. Emiliano Cervantes 7 years ago

    If I’m managing virtual machines, does this still works?

    Also, I’m always reverting them so would these still apply??

    • Author

      I don’t see any reason why this shouldn’t work in in virtual machines. Of course, if you revert the VM to a previous state all your configurations are gone. So you have to make sure that you revert to a state the contains the certificate.

  6. Emiliano Cervantes 7 years ago

    How can I remove the WSMan HTTPS listener?

  7. Emiliano Cervantes 7 years ago

    After I use the cmdlet Enter-PSSession -ComputerName myHost -UseSSL -Credential (Get-Credential) the root changes starting with my host name
    Ex: PS C:\Administrator to [hostName]: PS C:\Administrator\Documents

    Now I’m trying to use Invoke-Command -ComputerName myHost -UseSSL -ScriptBlock {Get-Process} -Credential (Get-Credential) but it doesn’t work, I use the same “myHost” and the correct credentials but I get a denied access.

    What could be the problem or I’m I doing something wrong?

    • Author

      After you start a remote session with Enter-PSSession you can execute PowerShell commands as if you were working on a local console. Thus, you don’t need Invoke-Command and you can just run Get-Process. Also, you don’t need Enter-PSSession if you want to work with Invoke-Command. These two cmdlets represent two different ways to do PowerShell remoting. You don’t use them together.

      • Emiliano Cervantes 7 years ago


  8. Emiliano Cervantes 7 years ago

    Sorry if I’m wrong, but with this we can create a self-signed certificate, then we enable https and disable http, then we put the certificate in the machine, and finally we start the session, right?

    It’s just that for some reason I can’t enable https & I still can connect to the machine through http.

  9. Mark 7 years ago

    Thanks for the best tutorial on the subject! I’ve set up HTTPS PSRemoting in minutes following it and it works like a charm. I ‘m new to this and still have few questions.

    I need to control 5 workgroup machines (not on a domain) from a laptop. Do I need to issue SSL certificates on each one of them and import the whole bunch to my laptop, or is there, perhaps, a way to create a common certificate for multiple machines?
    These self-signed certificates expire in one year. How do I prolong or renew them? Or should they just be replaced when expired?

    • Author


      I didn’t try it, but I don’t see a reason why you can’t use the same certificate for multiple machines.

      You can use the -NotAfter parameter of the New-SelfSignedCertificate cmldet to specify an expiry date. This allows you to create a certificate that lasts longer than a year. I don’t think that you can extend certificates.

  10. Amir 6 years ago

    My client can connect to Server by using remote PS and do delete, copy ,… but i can not run any script or program on the server. It doesn’t give any error and seems to be executed but nothing happens actually on the server. What should i do?


  11. Amir 6 years ago

    Hi, i want to explane more about my previous post.

    I want to run remotely some programs on Azure windows server from a windows machine using powershell remote. I configured all the setting that you mentioned in your pages and i can connect to remote server and do copy, delete, add and get process and etc.. but i can not run any program such as .cmd , .txt, … on remote Azure VM. I dont get any error.

    I tried Invoke-item, Invoke-process, … for executing. I will appreciate if you help me.



    • Author

      What command this you use? Maybe your remote program just didn’t return anything? To see if you can execute remote programs you can try this command:

      Invoke-Command -ComputerName $MyRemoteComputer -ScriptBlock {c:\windows\system32\ping.exe}

      • Amir 6 years ago

        Yes, it is working but i want to run an *.exe file that has UI remotely something like Calc.exe. Is it so that windows power-shells remoting can not run exe with GUI? Is there any solution to that?



        • Author

          You can only run command-line tools with PowerShell remoting. To execute GUI tools remotely you have to use a Remote Desktop tool.

  12. Tory Netherton 6 years ago

    This walkthrough is really helpful Michael. Thank you for publishing it. I have a question about it. While following along (at the point where you export the cert) I received the following error:


    Google searches have not really turned up any useful answers, so I’m hoping maybe you can give me an idea as to why this would be happening.

    Any assistance is greatly appreciated.



    • Author

      Did the certificate appear the MMC span-in in the step before? You can also export the certificate from there.

      • Tory Netherton 6 years ago

        The cert did appear in the MMC. I know I could export it from there. I was hoping to put all of this into a script that I could run on each of the machines that I manage so that it would be easy to deploy. Unfortunately the error gives very little to help find the cause and the internet seems never to have heard of it.

        Thanks for the suggestion though.

        • Author

          Hmm strange. It appears to be an authorization problem. Do you also receive the error message when you export the cert from the MMC? It might be a configuration issue on your test machine. I would try it again on a freshly installed stand-alone machine.

  13. Tory Netherton 6 years ago

    No. No error when exporting via the MMC. This machine is freshly installed, but who knows, perhaps something is wrong with it. I will try on another. Thanks for the advice. I’ll let you know how it goes.

  14. Tory Netherton 6 years ago

    Tried a fresh machine. No such luck.

    I looked around for another CLI export option that I could call from PS. I didn’t find one that looked like it would work. Do you know of any?

    • Author

      If you just need a certificate you can use Makecert.exe. However, PowerShell definitely is the way to go now. I somehow think the problem is caused by the commands you use. Did you try to follow procedure exactly as described in this post without any modifications?

  15. I was trying to follow this article and enable Remoting over SSL on a PowerShell on CentOS 7.x. Please let know if there are any additional steps I need to take apart from installing an OMI provider for Centos 7.x?

    • Author

      I never worked with PowerShell on CentOS. I guess you are better off with PowerShe Core on Linux systems. You can then use SSH for remote connections.

  16. Jason Dunn 6 years ago


    I found your post to be the most insightful post on the internet so far. Thanks a lot.

    While configuring a new install of Windows Server 2016, I was having difficulties trying to connect remotely with PSSession. I have to admit that the intended parameter -UseSSL was a stumbling block for me for a while and caused lots of frustration. Your explanation of WinRM was straightforward and cleared everything up for me.

    I would like to add this for those who may also still have issues:

    $so = New-PsSessionOption –SkipCACheck -SkipCNCheck
    Enter-PSSession -ComputerName <ip_address_or_dns_name_of_server> -Credential <local_admin_username> -UseSSL -SessionOption $so

    This was helpful when WS 2016 wasn’t accepting my self signed certificate.

    Error: The SSL certificate is signed by an unknown certificate authority.

    Thanks again.

    • Author

      Jason, thanks! Does that that mean that only Windows Server 2016 doesn’t allow self-signed certificates? I never saw your error with PowerShell remote sessions.

  17. Jason Dunn 6 years ago

    Michael, I believe this is new in 2016 (confirmed using a Nano edition).

    Here is the error:

    Enter-PSSession : Connecting to remote server WINDOWSSERVER failed with the following error message
    : The server certificate on the destination computer (WINDOWSSERVER:5986) has the following errors:

    The SSL certificate is signed by an unknown certificate authority. For more information, see the
    about_Remote_Troubleshooting Help topic.
    At line:1 char:8
    + $WS = Enter-PSSession -ComputerName WINDOWSSERVER -Authentication Ne …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (WINDOWSSERVER:String) [Enter-PSSession], PSRemotingT
    + FullyQualifiedErrorId : CreateRemoteRunspaceFailed

  18. Varun 6 years ago

    Hi Michael,

    Self-signed certs don’t work anymore unless you SkipCACheck, SkipCNCheck (if using IPs) during sessions.

  19. Michael Waterman 6 years ago

    I also had the error: “Export-Certificate : Access is denied. 0x80070005 (WIN32: 5 ERROR_ACCESS_DENIED)”

    Turns out that the error was that the “cert” folder in the temp folder existed. Apparently the syntax creates a file, but can’t if a folder with the same name exists. Just delete the “cert” folder or use a different name.

    Hope this helps!

  20. tilak 6 years ago

    Hi Mike, Thanks for helping us through this post.

    I followed this blog post and others to make WinRm work for one remote host.

    However, while working on the 2nd server am quite unsuccessful.

    Both local host and remote host are in same domain. Both servers have their Certificates issues by same CA.

    One thing stucked me and I am thinking this could the reason why WinRm not working.

    When I list WinRM listeners, they are showing ListeningOn = null.

    Following the instructions from below link, I edited the Group plocy. Then restarted WinRM service. But no help.

    Also, I tried deleting the HTTP listener. Created a self signed cert, imported to the other host but no help.

    I am now clueless, what else I can try to fix this. Can you please help?

    C:\Windows\system32>winrm quickconfig -transport:https

    WinRM service is already running on this machine.

    WinRM is not set up to allow remote access to this machine for management.

    The following changes must be made:

    Create a WinRM listener on https://* to accept WS-Man requests to any IP on this


    Make these changes [y/n]? y

    WinRM has been updated for remote management.

    Created a WinRM listener on https://* to accept WS-Man requests to any IP on thi

    s machine.

    C:\Windows\system32>winrm e winrm/config/listener

    Listener [Source=”GPO”]

    Address = *

    Transport = HTTP

    Port = 5985


    Enabled = true

    URLPrefix = wsman


        ListeningOn = null


    Address = *

    Transport = HTTPS

    Port = 5986

    Hostname = hostname.dmz.cms

    Enabled = true

    URLPrefix = wsman

    CertificateThumbprint = bd 4b df cb ee 8a 34 62  22 78 d5 f6 b4 94 9a f487 6

    1 13 9a

    ListeningOn = null



    • Author

      Did you use a self-signed certificate? There have been changes with regard to self-signed certificates since I wrote this post.

  21. tilak ranjan 5 years ago

    Both  host machine and remote machine are in same domain. Server certificates are issued by same CA. So i think, we don’t need a self signed certificate.  What do you suggest?However, i have  tried with self-signed cert as well but that didn’t help and hence removed.

    I am not understanding why it’s showing ListeningOn = null. 

    What could be causing this? Please suggest. Thank you.

    C:\Windows\system32>winrm quickconfig -transport:https
    WinRM service is already running on this machine.
    WinRM is not set up to allow remote access to this machine for management.
    The following changes must be made:

    Create a WinRM listener on https://* to accept WS-Man requests to any IP on this

    Make these changes [y/n]? y

    WinRM has been updated for remote management.

    Created a WinRM listener on https://* to accept WS-Man requests to any IP on this machine.

    C:\Windows\system32>winrm e winrm/config/listener
    Listener [Source=”GPO”]
    Address = *
    Transport = HTTP
    Port = 5985
    Enabled = true
    URLPrefix = wsman
    ListeningOn = null

    Address = *
    Transport = HTTPS
    Port = 5986
    Hostname =
    Enabled = true
    URLPrefix = wsman
    CertificateThumbprint = 84 96 70 ab f1 5f df a8 26 9a 33 21 e2 a0 e3 6cee f
    8 de d4
    ListeningOn = null


    • Author

      Hmm strange. I just tried again the procedure described in the post and it still works. Maybe it is an issue with your network configuration. Maybe multiple NICs or something like that. Did you try if remoting via HTTP works? If not, maybe this helps you find the problem. You could also try using a self-signed certificate as described in the post. I am unsure if this would allow you to connect to the host. However, at least you should see the IP address when you read the listener configuration.

  22. tilak 5 years ago

    The above ListeningOn = null issue got resolved after doing following things:

    1. Launch Group Policy Management
    2. Browse the tree on left pane of “Local Group Policy Editor” to Computer Configuration\Administrative Templates\Windows Components\Windows Remote Management (WinRM)\WinRM Service
    3. Double click the policy setting “Allow remote server management through WinRM”. A window “Allow remote server management through WinRM” will show up
    4. Change the IPv4 filter and the IPv6 filter then click Apply.
    5. Rerun the enumeration of listeners

    PS C:\Windows\system32> winrm e winrm/config/listener

    Listener [Source=”GPO”]

    Address = *

    Transport = HTTP

    Port = 5985


    Enabled = true

    URLPrefix = wsman


    ListeningOn =,, ::1, fe80::5efe:, fe80::6988:8233:cb3:cb63%12


    Address = *

    Transport = HTTPS

    Port = 5986

    Hostname = brcwnt2l

    Enabled = true

    URLPrefix = wsman

    CertificateThumbprint = 060199F524C9987BE502D7908ECBBDED16A4EA7B

    ListeningOn =,, ::1, fe80::5efe:, fe80::6988:8233:cb3:cb63%12

    1. Might need to restart WinRM Service

    Restart-Service -Force -Name WinRM

    1. Test Remoting from a different machine


    $winrmPort = “5986”

    # Get the credentials of the machine

    $cred = Get-Credential

    # Connect to the machine

    $soptions = New-PSSessionOption -SkipCACheck

    Enter-PSSession -ComputerName $hostName -Port $winrmPort -Credential $cred -SessionOption $soptions -UseSSL



    Invoke-Command –ComputerName $hostName -Credential demo\serveradmin -ScriptBlock {Hostname}


  23. Boris 5 years ago

    I am having the same “Listening on Null” issue after rolling back my working setup and reconfiguring it again.

    Tthe same commands worked the first time but didn’t work the second time on the same VM.

  24. Nick Aleksandrowicz 5 years ago

    Hey Michael,

    This worked for me great! Is it possible to use this same configuration while still allowing the HTTP listener to be open in case someone wants to perform a remote Powershell session using HTTP? If so, what would be the steps to back out of the HTTP disablement which you have provided in your steps? I have a machine where i followed all your steps, and I want to re-enable the HTTP listener while still being able to use the self signed certificate over SSL when necessary.

  25. Great – thanks Michael. I just performed the following steps after your steps:

    New-Item -Path WSMan:\Localhost\listener\listener -Transport HTTP -Address *

    Enable-NetFirewallRule -DisplayName “Windows Remote Management (HTTP-In)”

    Are you saying that disabling PowerShell remoting and enabling it again would set everything back to defaults?



    • Author

      I didn’t do this for quite some time, but as far as remember disabling and enabling remoting again should reset everything. Did you try it?

Leave a reply to Varun Click here to cancel the reply

Please enclose code in pre tags

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


© 4sysops 2006 - 2023


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account