New default ports for WS-Management and PowerShell remoting


Everybody knows that security is a big deal, especially when your servers are internet-connected.  When an administrator wants to protect a machine from possible remote attacks, a common quick-reflex defense is to block incoming traffic on ports 80 and 443, so that no messages can be sent to the machine via the internet.  However, if you also block management commands, it will be hard to diagnose and fix any possible damage that was done to the server, or to patch the security hole that prompted the shutdown in the first place!  Because of scenarios like this, the smart approach is to direct management traffic and web traffic to different ports.


 


In lieu of this, the default ports used for WS-Management and PowerShell remoting have been changed to 5985 an 5986 for connections over HTTP and HTTPS, respectively.


 


This means that, unless otherwise specified, all WS-Management listeners that are created will accept traffic on these ports, and all connections created will go through these ports, including listeners created using the commands winrm quickconfig or Enable-PSRemoting.


 


 


Though we recommend using these new ports for the sake of security, we also understand that there are some situations where moving to these new ports is either tricky or impossible.  If changing to these new ports will wreak havoc on your existing deployments, don’t worry – there are mechanisms in place to make it easy to maintain your current configuration.  If you want to accept traffic on ports 80 and 443, you need to use the new compatibility listeners.


 


The compatibility listeners are not directly addressable like your other listeners, meaning they can’t be retrieved using a WS-management get operation and their settings can’t be modified.  When you enumerate your active listeners, these special listeners are tagged with the string [Source=”Compatibility”] to distinguish them from the rest.  For example, the second listener below is a compatibility listener:


 


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


 


Listener


    Address = *


    Transport = HTTP


    Port = 5985


    Hostname


    Enabled = true


    URLPrefix = wsman


    CertificateThumbprint


    ListeningOn = 127.0.0.1, 157.59.85.27, ::1, 2001:4898:0:fff:200:5efe:157.59.85.27, 2001:4898:2b:3:594:e48f:e99a:de17, 2001:4898:2b:3:4c54:7d1e:a5f6:6ea, fe80::100:7f:fffe%11, fe80::200:5efe:157.59.85.27%13, fe80::4c54:7d1e:a5f6:6ea%12


 


Listener [Source=”Compatibility”]


    Address = *


    Transport = HTTP


    Port = 80


    Hostname


    Enabled = true


    URLPrefix = wsman


    CertificateThumbprint


    ListeningOn = 127.0.0.1, 157.59.85.27, ::1, 2001:4898:0:fff:200:5efe:157.59.85.27, 2001:4898:2b:3:594:e48f:e99a:de17, 2001:4898:2b:3:4c54:7d1e:a5f6:6ea, fe80::100:7f:fffe%11, fe80::200:5efe:157.59.85.27%13, fe80::4c54:7d1e:a5f6:6ea%12


 


If you want to create a listener to field traffic on ports 80 or 443 for HTTP or HTTPS traffic, respectively, you can do it two different ways.  You can directly modify WinRM configuration:


 


winrm set winrm/config/service @{EnableCompatibilityHttpListener=”true”}


winrm set winrm/config/service @{EnableCompatibilityHttpsListener=”true”}


 


Or, you can use the new Group Policy settings under Windows Components > Windows Remote Management (WinRM) > WinRM Service:


 


“Turn On Compatibility HTTP Listener”


“Turn On Compatibility HTTPS Listener”


 


 


If you’d rather use PowerShell to manage your listeners, you can enumerate all active listeners with the following command:


 


Get-WSManInstance –ResourceURI winrm/config/listener –Enumerate


 


To create a compatibility listener on ports 80 or 443 for HTTP or HTTPS traffic, respectively, use the following commands:


 


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


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


 


 


What will happen when you upgrade your current machines?  If you have existing listeners that are on non-default ports, meaning either an HTTP listener on something other than port 80 or an HTTPS listener on something other than port 443, nothing will change – those listeners will still exist with the same configuration.  However, any listeners that exist on the default ports will be moved to the new default ports (5985 for HTTP and 5986 for HTTPS), and a compatibility listener will take the place of the old listener.


 


So, for example, if your machine had one listener accepting HTTPS traffic on port 443, after upgrade your machine would have one listener accepting HTTPS traffic on port 5986 and one compatibility listener accepting HTTPS traffic on port 443.


 


 


For all you PowerShell users, the New-PSSession cmdlet has been modified to take these changes into account.  New-PsSession now takes on two different parameter sets, which are differentiated based on the existence (or absence) of two parameters:  ComputerName and ConnectionURI.


 


When the ComputerName parameter is given, then we will honor the default client port setting in the WinRM configuration (unless you change them, they will be 5985/5986 for HTTP/HTTPS).  When the ConnectionURI parameter is given, then the string will be interpreted in the same way as Internet Explorer does it (using ports 80/443 for HTTP/HTTPS).  In both cases, if a port number is explicitly given, then we will use that port – the difference is in the defaults.


 


So, the following PowerShell command will connect to my desktop machine on port 5985 (unless you go in and change the WinRM configuration settings for the default client ports):


 


                New-PSSession –ComputerName NathanDesktop


 


This command will connect to my desktop machine over HTTPS on port 5986 (unless you go in and change the WinRM configuration settings for the default client ports):


 


                New-PSSession –ComputerName NathanDesktop –UseSSL


 


This command will connect to my desktop machine on port 4444 (assuming there is a listener set up to handle the request):


 


                New-PSSession –ComputerName NathanDesktop –Port 4444


 


This command will connect to Exchange over port 80:


 


                New-PSSession –ConnectionURI http://Exchange.labs.com/Exchange


 


This command will connect to Exchange over HTTPS on port 443:


 


                New-PSSession –ConnectionURI https://Exchange.labs.com/Exchange


 


Finally, this command will connect to Exchange over port 4444:


 


                New-PSSession –ConnectionURI http://Exchange.labs.com/Exchange:4444


 


 


The following cmdlets for WS-Management operations have also undergone the same changes as described above:


 


Connect-WSMan


Get-WSManInstance


Invoke-WSManAction


New-WSManInstance


Remove-WSManInstance


Set-WSManInstance


 


 


The WinRM command-line tool has been updated in the same way.  If the user passes a computer name to the WinRM command line using the –remote:<Computername> switch, then we will pick the default client HTTP port from the WinRM config (by default, 5985).  If the user passes a computer name to the WinRM command line using the –remote:<Computername> switch and includes the –UseSSL flag, then we will pick the default client HTTPS port from the WinRM config (by default, 5986).


 


If the user passes a computer name to the WinRM command line using the –remote:<Computername> switch and specifies a particular port, then we will use the specified port.


 


If the user passes the connection URI string to the WinRM command line, such as –remote:http://Mycomputer/wsman, we will interpret the URI in the same way as Internet Explorer does it (using ports 80/443 as default for HTTP/HTTPS).


 


If the text below looks familiar, it’s probably because almost all of the text was copied and pasted from the PowerShell examples above – consistency is always a good thing!


 


The following command will connect to my desktop machine on port 5985 (unless you go in and change the WinRM configuration settings for the default client ports):


 


                winrm identify –remote:NathanDesktop


 


This command will connect to my desktop machine over HTTPS on port 5986 (unless you go in and change the WinRM configuration settings for the default client ports):


 


                winrm identify –remote:NathanDesktop –usessl


 


This command will connect to my desktop machine on port 4444 (assuming there is a listener set up to handle the request):


 


                winrm id –remote:NathanDesktop:4444


 


This command will connect to Exchange over port 80:


 


                winrm id –remote:http://Exchange.labs.com/Exchange


 


This command will connect to Exchange over HTTPS on port 443:


 


                winrm id –remote:https://Exchange.labs.com/Exchange


 


Finally, this command will connect to Exchange over port 4444:


 


                winrm id –remote:http://Exchange.labs.com/Exchange:4444


 


 


Nathan Burkhart


Program Manager  |  WS-Management


 


Comments (12)

  1. PowerUser says:

    The article is very concrete and useful. I am having an issue with powershell. I hope someone can help. I could find any relevant documentation or thread referring to same. I was just thinking if you can help. While running a script using WSMan in powershell, we created the script to get the data for CIM_Sensor class. The script ran successfully in C# but when we ran powershell script it started throwing exception after querying few CIM instance.

    Below is the exception thrown

    "Get-WSManInstance : The response that the WS-Management service computed exceed the internal limit for envelope size."

    Is this a powershell issue as we were able to retrieve data successfully using C# and Perl? Any pointers would be highly appreciated.

    – PowerUser

  2. That error message is unexpected.  Can you please check which version of WinRM you are running, by calling winrm id?  It’s possible that your problem will be fixed by upgrading to a more recent version.

  3. Steven says:

    I updated to WinRM 2.0 / Powershell 2.0 using the Oct 27,2009 release hoping that my listener port would be changed to the above mentioned 5985, but after updating, enumerating only shows one listener, Source: Compatibility, Port: 80.  The above text suggests that the alternate ports would be setup without user action (simply be updating), but this has not happened.

  4. Hey Steven, did you configure the original listener on port 80 (before the update) using Group Policy?  Shoot me an email at nathan.burkhart@microsoft.com and we can try to figure out what’s going on.

  5. Steven says:

    For the new installation to configure the 5895 port, you must run "winrm quickconfig".  The installation won’t automatically move the ports, but after running quickconfig, the new ports will be enabled.

  6. Brian says:

    This is not a PowerShell issue – it is a WinRM issue.

    It is simply the default size of receive envelope that the WinRM client can handle.

    This will set it to 1Mb:

    winrm set winrm/config @{MaxEnvelopeSizekb="1024"}

    (BTW – execute the command in an elevated command prompt)

    As your responces get ever larger your receive buffer needs to be larger as well.

  7. Jamey says:

    I have a quick question…

    How do I make a Windows 2008 R2 servers default WinRM port = 80 and not 5985?

    Or, I guess another solution would be to set all of the Windows 2003 R2 server to listen over 5985 however, when I try this I get errors.

    C:>winrm create winrm/config/Listener?Address=*+Transport=HTTP+Port=5985

    WSManFault

       Message

           ProviderFault

               WSManFault

                   Message = This resource requires the following selectors: Address Transport

    Error number:  -2144108453 0x8033805B

    The WS-Management service cannot process the request because the request contained invalid selectors for the resource.

    TIA,

    Jamey

  8. Hey Jamey, since the Port isn’t a key property on the Listener, try this two-step approach:

    C:>winrm create winrm/config/Listener?Address=*+Transport=HTTP

    C:>winrm set winrm/config/Listener?Address=*+Transport=HTTP @{Port="5985"}

  9. Shahid says:

    Hello,

    How to Restrict Dynamic Port Mapping for "Remote" Powershell Sessions ???

    "PowerShell" (How to Restrict Dynamic Port Mapping for "Remote" Powershell Sessions) behind a firewall … dont want to open 100 ++ ports for powershell to execute scripts on remote servers ???

    Has anyone come across this … PS works only if port 445, 135, 1024-65k are opened … i am fine with a few high ports, but cant afford to open the rest throughout all the firewall zones ??

    , for instance get-services from a remote computer, it establishes the connection on port 135, 445 etc. but it also uses random ports from source machince to remote machine – in the range 1024 ++

    Which means, from the source computer to remote computer – all ports should be opened(1024-65k)

    Machine A(PS host) — Machine B(PS target) (A&B are not behind a firewall)

    Machine A- ** PS: get-service B

    You can see traffic from A to B on 135, 445 – which is good. But post that A n B try comminucate on random ports ?

    Run a trace and you will see what i mean.

    As far as fixed DCOM port on Source Machine is concerned, thats gonna be tricky coz i am sure apps will crash if try to communicate on some thing else.

    well if you still insist, i can fix the ports on source machine, what about 100x targets ? You cant afford to mess with DCOM on all ?

  10. @Shahid

    It looks like you are encountering an issue where some cmdlets implement their own remoting and this doesn't have anything to do with PowerShell remoting.  Get-Service and Get-Process and others have their own built in remoting, but they use DCOM (same as WMI).  DCOM uses ports 135 and 445 to perform negotiating to determine the actual port used for the payload (1024-65k are all possible).

    The recommendation would be to use PowerShell remoting.  Use New-PSSession to establish a remote session from A to B and then execute get-service on B using invoke-command (for example) and the results should be sent via WS-Man rather than DCOM.

  11. Ganapathy says:

    Hi Stephen / All,

    I need to execute powershell on servers behind firewall, i set server to use 8530 port (which we opened for patching) so i can reach DMZ server from Non-DMZ via 8530.

    Below commands Configured on DMZ Server

    Set-Item WSMan:localhostServiceEnableCompatibilityHttpListener -Value true

    Set-Item wsman:localhostlistenerlistener*port –value 8530

    set-item wsman:localhostClientTrustedHosts -value (non-dmz desktop from where i plan to run Powershell script)

    While executing the below command

    New-PSSession -ComputerName " IP" -Port 8530 -credential $cred

    i am getting following error

    Connecting to remote server failed with the following error message : The WinRM client cannot process th

    e request. Default authentication may be used with an IP address under the following conditions: the transport is HTTPS

    or the destination is in the TrustedHosts list, and explicit credentials are provided. Use winrm.cmd to configure Trus

    tedHosts. Note that computers in the TrustedHosts list might not be authenticated. For more information on how to set T

    rustedHosts run the following command: winrm help config. For more information, see the about_Remote_Troubleshooting He

    lp topic.

       + CategoryInfo          : OpenError: (System.Manageme….RemoteRunspace:RemoteRunspace) [], PSRemotingTransportExc

      eption

       + FullyQualifiedErrorId : PSSessionOpenFailed

    If i execute with NAME

    Invoke-Command -ComputerName HAMWINWIZP015 -ScriptBlock {Get-Process} -Credential $cred

    Connecting to remote server failed with the following error message : WinRM cannot process the request.

    The following error occured while using Kerberos authentication: The network path was not found.

    Possible causes are:

     -The user name or password specified are invalid.

     -Kerberos is used when no authentication method and no user name are specified.

     -Kerberos accepts domain user names, but not local user names.

     -The Service Principal Name (SPN) for the remote computer name and port does not exist.

     -The client and remote computers are in different domains and there is no trust between the two domains.

    After checking for the above issues, try the following:

     -Check the Event Viewer for events related to authentication.

     -Change the authentication method; add the destination computer to the WinRM TrustedHosts configuration setting or us

    e HTTPS transport.

    Note that computers in the TrustedHosts list might not be authenticated.

      -For more information about WinRM configuration, run the following command: winrm help config. For more information,

    see the about_Remote_Troubleshooting Help topic.

       + CategoryInfo          : OpenError: (:) [], PSRemotingTransportException

       + FullyQualifiedErrorId : PSSessionStateBroken

    Could you suggest what would be the issue & if possible please help me to use that DMZ Server as proxy server as i am willing to run powershell on few DMZ Server via the one server.

  12. Bart van den Donk says:

    User Get-PSDrive!

    In Powershell you can type:

    cd wsman:

    then use cd and dir….

    PS WSMan:localhost> dir

      WSManConfig: Microsoft.WSMan.ManagementWSMan::localhost

    Type            Name                           SourceOfValue   Value

    —-            —-                           ————-   —–

    System.String   MaxEnvelopeSizekb                              500

    System.String   MaxTimeoutms                                   60000

    System.String   MaxBatchItems                                  32000

    System.String   MaxProviderRequests                            4294967295

    Container       Client

    Container       Service

    Container       Shell

    Container       Listener

    Container       Plugin

    Container       ClientCertificate