WS-Management is a new web services-based management protocol. It's SOAP-based of course, and it is compatible with the rest of the specifications in the WS-* Web Service stack, like WS-Transfer, WS-Enumeration, WS-Addressing.
WS-Management is enabled in Vista (and Longhorn Server) in several ways.
Security
WS-Management is securely enabled on Vista machines. To find out the security configuration of your machine (both for client and server) you can use WS-Management itself like in the command below:
C:\>winrm get winrm/configConfig MaxEnvelopeSizekb = 150 MaxTimeoutms = 60000 MaxBatchItems = 20 MaxProviderRequests = 25 Client NetworkDelayms = 5000 URLPrefix = wsman AllowUnencrypted = false Auth Basic = false Digest = true Kerberos = true Negotiate = true DefaultPorts HTTP = 80 HTTPS = 443 TrustedHosts Service RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;ER)S:P(AU;FA;GA;;;WD)(AU;SA;GWGX;;;WD) MaxConcurrentOperations = 100 EnumerationTimeoutms = 60000 MaxConnections = 5 AllowUnencrypted = false Auth Basic = false Kerberos = true Negotiate = true DefaultPorts HTTP = 80 HTTPS = 443 IPv4Filter = * IPv6Filter = * Winrs AllowRemoteShellAccess = true IdleTimeout = 900000 MaxConcurrentUsers = 5 MaxShellRunTime = 28800000 MaxProcessesPerShell = 5 MaxMemoryPerShellMB = 80 MaxShellsPerUser = 2
By default, WS-Management is not enabled for remote access, Windows authentication is used by default on local acceess, and encryption is turned on.
You can enable remote access by typing:
C:\>winrm quickconfigWinRM is not set up to allow remote access to this machine for management.The following changes must be made: Set the WinRM service type to delayed auto start.Start the WinRM service.Create a WinRM listener on HTTP://* to accept WS-Man requests to any IP on this machine.Enable the WinRM firewall exception. Make these changes [y/n]? y WinRM has been updated for remote management. WinRM service type changed successfully.WinRM service started.Created a WinRM listener on HTTP://* to accept WS-Man requests to any IP on this machine.WinRM firewall exception enabled.
C:\>winrm quickconfigWinRM is not set up to allow remote access to this machine for management.The following changes must be made:
Set the WinRM service type to delayed auto start.Start the WinRM service.Create a WinRM listener on HTTP://* to accept WS-Man requests to any IP on this machine.Enable the WinRM firewall exception.
Make these changes [y/n]? y
WinRM has been updated for remote management.
WinRM service type changed successfully.WinRM service started.Created a WinRM listener on HTTP://* to accept WS-Man requests to any IP on this machine.WinRM firewall exception enabled.
The output above already illustrates one main advantages of web services - their flexibility with respect to firewall access. Say that you want to enable your current machine to accept incoming WS-Management SOAP requests through the port 80 (as HTTP requests). Then, all you need to do is opening port 80 and that's it! Also, NAT is not a problem, of course.
Try this type of exercise when enabling DCOM through the firewall, and you'll have nightmares. This can get really complicated. Furthermore, DCOM doesn't really work in NAT environments.
A simple example
At this point, you have a secure web service enabled on your machine, that you can then use to perform regular management queries, in WMI style. Let's get some information about a Windows service, like the status of the Spooler service.
Note that I am doing a remote query - basically contacting the machine AOLTEAN-D2, through an internal, WS-Management web service interface:
C:\>winrm get wmicimv2/Win32_Service?Name=spooler -r:aoltean-d2Win32_Service AcceptPause = false AcceptStop = true Caption = Print Spooler CheckPoint = 0 CreationClassName = Win32_Service Description = Loads files to memory for later printing DesktopInteract = true DisplayName = Print Spooler ErrorControl = Normal ExitCode = 0 InstallDate = null Name = spooler PathName = C:\Windows\System32\spoolsv.exe ProcessId = 1472 ServiceSpecificExitCode = 0 ServiceType = Own Process Started = true StartMode = Auto StartName = LocalSystem State = Running Status = OK SystemCreationClassName = Win32_ComputerSystem SystemName = AOLTEAN-D2 TagId = 0 WaitHint = 0
Well, it looks like the spooler service is started. We can perform even more complicated queries, such as this one, to find the list of stopped services which are supposed to be started:
C:\trace>winrm enumerate wmicimv2/* -filter:"select * from win32_service where StartMode=\"Auto\" and State = \"Stopped\" " -r:aoltean-d2
XmlFragment Win32_Service AcceptPause = false AcceptStop = false Caption = Media Center Service Launcher CheckPoint = 0 CreationClassName = Win32_Service Description = Starts Media Center Scheduler and Media Center Receiver services at startup if TV is enabled within Media Center. DesktopInteract = false DisplayName = Media Center Service Launcher ErrorControl = Ignore ExitCode = 0 InstallDate = null Name = ehstart PathName = C:\Windows\system32\svchost.exe -k LocalServiceNoNetwork ProcessId = 0 ServiceSpecificExitCode = 0 ServiceType = Share Process Started = false StartMode = Auto StartName = NT AUTHORITY\LocalService State = Stopped Status = OK SystemCreationClassName = Win32_ComputerSystem SystemName = AOLTEAN-D2 TagId = 0 WaitHint = 0
So, where does WS-Management comes into play? At its roots, WS-Management is a simple management protocol that allows us to operate with resources. WS-Management defines a few operations on these resources:
In some sense, resources can be viewed as "objects" in OOP point of view, and WS-Management defines a simple protocol to manipulate these "objects".
Under the hood
So where do web services come into play? Can we peek into the actual management protocol?
With web services, it is actually easy - all we need to do is to use a network protocol analyzer to sniff the HTTP packets between client and the server. Ultimately, web service interactions are nothing more than exchanging XML packets using HTTP/HTTPS, so analyzing these interactions is no more difficult than analyzing HTTP request/response commands between a browser and a web server.
Let's take the GET command above (winrm get wmicimv2/Win32_Service?Name=spooler -r:aoltean-d2). In our case, the client program attempts to get the properties of a given resource of type "wmicimv2/Win32_Service", identified by the selector "Name=spooler".
Let's dive in. With the network sniffer we obtain the following SOAP request message:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"> <s:Header> <a:To>http://aoltean-d2:80/wsman</a:To> <w:ResourceURI s:mustUnderstand="true">http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Service</w:ResourceURI> <a:ReplyTo> <a:Address s:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address> </a:ReplyTo> <a:Action s:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/09/transfer/Get</a:Action> <w:MaxEnvelopeSize s:mustUnderstand="true">153600</w:MaxEnvelopeSize> <a:MessageID>uuid:2A553640-AA45-4BE1-8CE8-C3F20BD3C74E</a:MessageID> <w:Locale xml:lang="en-US" s:mustUnderstand="false" /> <w:SelectorSet> <w:Selector Name="Name">spooler</w:Selector> </w:SelectorSet> <w:OperationTimeout>PT60.000S</w:OperationTimeout> </s:Header> <s:Body></s:Body></s:Envelope>
Correspondingly, the WS-Man response packet looks like this:
<s:Envelope xml:lang="en-US" xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"> <s:Header> <a:Action >http://schemas.xmlsoap.org/ws/2004/09/transfer/GetResponse</a:Action> <a:MessageID >uuid:3E0BE062-2615-497E-BE6A-2FC7D5B7C9C3</a:MessageID> <a:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:To> <a:RelatesTo >uuid:2A553640-AA45-4BE1-8CE8-C3F20BD3C74E</a:RelatesTo> </s:Header> <s:Body> <p:Win32_Service xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Service" xmlns:cim="http://schemas.dmtf.org/wbem/wsman/1/base" xsi:type="Win32_Service"> <p:AcceptPause>false</p:AcceptPause> <p:AcceptStop>true</p:AcceptStop> <p:Caption>Print Spooler</p:Caption> <p:CheckPoint>0</p:CheckPoint> <p:CreationClassName>Win32_Service</p:CreationClassName> <p:Description>Loads files to memory for later printing</p:Description> <p:DesktopInteract>true</p:DesktopInteract> <p:DisplayName>Print Spooler</p:DisplayName> <p:ErrorControl>Normal</p:ErrorControl> <p:ExitCode>0</p:ExitCode> <p:InstallDate xsi:nil="true"/> <p:Name>spooler</p:Name> <p:PathName>C:\Windows\System32\spoolsv.exe</p:PathName> <p:ProcessId>1596</p:ProcessId> <p:ServiceSpecificExitCode>0</p:ServiceSpecificExitCode> <p:ServiceType>Own Process</p:ServiceType> <p:Started>true</p:Started> <p:StartMode>Auto</p:StartMode> <p:StartName>LocalSystem</p:StartName> <p:State>Running</p:State> <p:Status>OK</p:Status> <p:SystemCreationClassName>Win32_ComputerSystem</p:SystemCreationClassName> <p:SystemName>AOLTEAN-D2</p:SystemName> <p:TagId>0</p:TagId> <p:WaitHint>0</p:WaitHint> </p:Win32_Service> </s:Body></s:Envelope>
That's it for now. I hope that in a future post I will cover the actual structure of WS-Management messages.