A Few Good Vista WS-Man (WinRM) Commands

In Vista, a lot of instrumentation, configuration, and utilization information is exposed via WS-Man. Vista WS-Man (aka: WS-Management, Windows Remote Management, and WinRM) incorporates many features, but I like to think of it as the management protocol/framework of the future (look out SNMP!). What makes WS-Man so great is the fact that it's all standards based, rides on HTTP/HTTPS (very firewall/NAT friendly), and packages its data in SOAP/XML packets (easy to shove into a database or use with a script).

Out of the box; Vista WS-Man exposes WMI information as well as Windows Remote Shell capabilities. What this means is that with WS-Man it's much easier to get instrumentation from remote machines as well as use that info in scripts.

Here are some sample commands to play with. If you cannot get the ‘Test WS-Man...' step to work, none of the steps following will work either (you're probably not using the right credentials to access the remote machine). One more caveat, the remote commands work best on domain joined machines. For workgroup machines, the WinRM service needs additional configuration.

Description

Command

Run from an Elevated Command prompt

Quickly configure the WS-Man service

winrm QuickConfig

Quickly delete the WS-Man listener

winrm invoke Restore winrm/Config \@{}

Run from an standard Command prompt

Display your machine's basic hardware info

winrm enumerate wmicimv2/Win32_ComputerSystem

Display your operating system properties

winrm get wmicimv2/Win32_OperatingSystem

Output your OS info in XML

winrm get wmicimv2/Win32_OperatingSystem -format:pretty

Ping WS-Man on a remote machine

winrm id -auth:none -remote:<some machine>

Test WS-Man access to a remote machine**

winrm id -remote:<some machine>

Grab a remote machine's WS-Man config

winrm get winrm/Config -r:<some machine>

Grab a remote machine's CPU load

winrm g wmicimv2/Win32_Processor?DeviceID=CPU0 -fragment:LoadPercentage -r:<some computer>

Grab a remote machine's free memory

winrm g wmicimv2/Win32_OperatingSystem -fragment:FreePhysicalMemory -r:<some computer>

Stop a service on a remote machine

winrm invoke stopservice wmicimv2/Win32_Service?name=w32time -r:<some computer>

Start a service on a remote machine

winrm invoke startservice wmicimv2/Win32_Service?name=w32time -r:<some computer>

Reboot a remote machine

winrm invoke reboot wmicimv2/Win32_OperatingSystem -r:<some computer>

Run a command on a remote machine (this uses winrS, not winrM)

winrs -r:<some computer> ipconfig /all

Run from PowerShell

Use PowerShell to grab the WS-Man Win32_OperatingSystem XML output

[xml]$osInfo = winrm get wmicimv2/Win32_OperatingSystem /format:pretty

Display the OS version property

$osInfo.Win32_OperatingSystem.Version

Display the last boot time

$osInfo.Win32_OperatingSystem.LastBootupTime.DateTime

Put free memory metric into an XML variable

[xml]$freemem = cmd /c "winrm get wmicimv2/Win32_OperatingSystem -fragment:FreePhysicalMemory -f:pretty -r:<some computer>"

Display the free memory value

$freemem.XMLFragment.FreePhysicalMemory

 

**Note: This step verifies that you have good connectivity to the remote machine, WS-Man is running and properly configured on the remote machine, AND you have the correct permissions to fully leverage WS-Man on the remote machine. If this step fails, it's probably a permissions issue.

Details:

WS-Man (WinRM) Architecture

The following diagram shows a high-level overview of the WS-Man (WinRM) architecture. In the diagram the 'Client' is querying the 'Server' for WS-Man information. Note that HTTP.sys and WinHTTP support the HTTP(s) transport for WS-Man, not IIS. In addition, IIS (or another web publishing service) can co-exist with WS-Man and share port 80.

Quickly configure the WS-Man service

Remember, this needs to be run from an 'Elevated' Command Prompt.

As you can see, this simple command does quite a bit. Please note every modification (hightlighted) since this might increase the attack surface of your computer. For example, Quick Config configures a listener that accepts connections from every network interface. This is probably not ideal for edge machines that connect to unsecure networks (like the Internet). In addition, this command only needs to be run once.

Quickly delete the WS-Man listener

Although this command only deletes all WinRM listeners, it effectively turns off any WS-Man communication to a machine.

Display your machine's basic hardware info and operating system properties

Win32_ComputerSystem and Win32_OperatingSystem are common WMI classes and useful for asset information and configuration information as well as some utilization metrics.

Output your OS info in XML

XML output makes the data much easier for storing in a database or dealing with programmatically (like with a script). PowerShell makes this that much easier since it works VERY well with XML (see below for a sample PowerShell script).

Ping WS-Man on a remote machine and test authorization credentials

Testing WS-Man on a remote machine is very useful in troubleshooting lots of connectivity and configuration issues. When pinging WS-Man without 'auth', it allows for the testing of the connectivity and basic service configuration. Using the 'auth' parameter tests the necessary authorization. Generally the credentials need to be in the 'Administrators' group for 'auth' to work. In this case no credentials are provided so the current credentials are used (this can be over-ridden). Notice that the OS version is included when successfully using 'auth' to test WS-Man.

Grab a remote machine's WS-Man config

Successfully completing this step pretty much insures that one has complete access to WS-Man on the remote computer.

Grab a remote machine's CPU load, free memory, and restart a service

WS-Man allows for gathering WMI properties (reading and writing although we're only reading in this example) as well as invoking methods (starting and stopping a service; as well as rebooting!). Notice the minimal return code for the invoke commands (0 = success).

Run a command on a remote machine (this uses winrS, not winrM)

WinRS is another utility that leverages WS-Man. WinRS allows for the execution of local, non-interactive command-line commands on a remote machine and returns the output. In other words, if the command can be run at the CMD prompt without any required input and it only accesses local resource (no network shares for example), then it will most likely work. There are ways to get around the 'local resource' issue, but that is out of scope for this blog.

Use PowerShell to grab instrumentation via WS-Man

PowerShell is great for consuming data from WS-Man since it works very well with XML. Notice that in the following example it's easy to 'surf' an object in PowerShell. In this case the XML object 'osInfo' is displayed on its own, and then expanded to the 'Win32_OperatingSystem' branch.

A simple PowerShell script

The following script shows how easy it is to automate the collection of WS-Man information using PowerShell.

$machines = ("machine1","machine2","machine3")
foreach ($machine in $machines) {
   [xml]$osInfo = winrm get wmicimv2/Win32_OperatingSystem /format:pretty /r:$machine
   $machine + ": " + $osInfo.Win32_OperatingSystem.LastBootupTime.DateTime
}

More Info

For more information on WS-Man, please see the following articles: