Out-of-band Hardware Management using WS-Management and Powershell


This will be the first in a series of posts about out-of-band management.  First, “out-of-band” basically means outside of the Operating System.  Specifically, a client is managing hardware irrespective of what OS is installed or if an OS is even installed/running.  This is possible because the hardware (typically called a Baseboard Management Controller (BMC)) implements some management protocol and in this case, we’re using WS-Management. 

The scripts I have here are tested against Intel’s vPro only because that happens to be what is in my office.  The same scripts (in theory) should work against any vendor implementation of WS-Management as long as the appropriate CIM Profiles are available.  I’ll leave discussion about CIM Profiles for another post.  If you want to use these scripts, I assume the hardware you want to manage is already provisioned for remote management.  Also, to successfully execute these scripts, you need to enable unsigned script execution in Powershell, allow unencrypted traffic, and trust the management endpoint in the WinRM client configuration (you should only do these things in a test environment).

For this first entry, we’ll focus on one aspect of the CIM Power State Management Profile specifically on changing the power state.  BMCs are typically low power devices that enable management of the main system.  They are capable of running just on standby power.  Some share the NIC with the main system, so you could have a computer system turned off (on standby) and plugged into the network and be able to remotely turn it back on.   

The first step is to get the current power state.  Here’s the first of two Powershell scripts and I’ll explain any interesting parts of it.

Param ([parameter(Mandatory=$true,Position=0)][string] $connectionUrl = “http://wsman-intelpc:16992/wsman“,
    [System.Management.Automation.PSCredential] $credential,
    [string] $authentication = “Digest”)

Since we are remoting to the hardware, we need some information.  First is the connectionUrl, this includes the transport (http or https), the computer address, the port, and the rest of the URL.  In this case, I’ve hardcoded the URL to the machine in my office and using the standard vPro port and URL.  Next, we need credentials as well as the authentication method.

    $assocPowerMgmtSvc = Get-WSManInstance -ConnectionURI $connectionUrl -Authentication $authentication `
        -Credential $credential -Enumerate -ResourceURI cimv2/CIM_AssociatedPowerManagementService
       
    if ($assocPowerMgmtSvc -eq $null)
    {
        “The remote endpoint does not support the Power State Management Profile”
        exit
    }

If you follow the Use Cases defined in the CIM Power State Management Profile spec, you would first see if the management endpoint supports this particular profile by going to the Interop namespace and looking for the corresponding instance of CIM_RegisteredProfile.  Then find the associated CIM_AssociatedPowerManagementService instance and then validate its capabilities, and finally perform the management operation.  We’ll shortcut some of this by attempting to get the CIM_AssociatedPowerManagementService directly.  If it exists, we’ll try to read the current power state, if not, well then it’s obviously not supported.

    $powerStates = “Unknown”, “Unknown”, “On”, “Sleep-Light”, “Sleep-Deep”,
        “Power Cycle (Off-Soft)”, “Off-Hard”, “Hibernate (Off-Soft)”, “Off-Soft”,
        “Power cycle (Off-Hard)”, “Master Bus Reset”, “Diagnostic Interrupt (NMI)”,
        “Off-Soft Graceful”, “Off-Hard Graceful”, “Master Bus Reset Graceful”,
        “Power Cycle off-Soft Graceful”, “Power Cycle Off-Hard Graceful”
   
    $assocPowerMgmtSvc.PowerState + “:” + $powerStates[$assocPowerMgmtSvc.PowerState]

The CIM class will just return an integer value (for localization reasons), so we’ll hardcode the English values here so that we know a value of 2 means On and 8 means Off.  Pretty simple so far.  Changing the power state is a bit more complicated which we cover next and is in a seperate script.

  $remoteParams = @{ConnectionURI=$connectionUrl;Authentication=$authentication;Credential=$credential}

I’m skipping defining the Powershell script parameters which are similar to Get with the addition of a PowerState parameter. Unlike reading the current state, setting it requires multiple network calls, so we’ll store the commonly used paramters in a variable.

    $powerprofile = Get-WSManInstance @remoteParams -Enumerate -ResourceURI `
        cimv2/CIM_RegisteredProfile?__cimnamespace=interop |
        Where-Object { $_.RegisteredName -eq “Power State Management” }
   
    if ($powerprofile -eq $null)
    {
        “The remote endpoint does not support the Power State Management Profile”
        exit
    }

Here I show what it looks like to see if the managed node supports the Power State Management Profile.  One thing you’ll notice is that I use Powershell to perform filtering on the client.  Intel vPro supports the WS-Management Selector filter, however, it only filters against Key properties and the RegisteredName property of CIM_RegisteredProfile is not a key.  To be completely proper, we are supposed to check the Capabilties to see if it supports the RequestPowerStateChange method, however, it’s just easier to call it to determine whether it will work.

    $comp = Get-WSManInstance @remoteParams -Enumerate -ResourceURI cimv2/CIM_ComputerSystem |
        Where-Object { $_.Dedicated -ne 14 }
    $ManagedSystemName = $comp.Name

Now that we know that this machine supports it, we need to find the right CIM_ComputerSystem that we want to turn on or off.  In the case of the BMC, you’ll actually get two instances of CIM_ComputerSystem where one represents the BMC itself and the other the managed system.  CIM_ComputerSystem has a Dedicated property we can filter agains to determine which is which.  A value of 14 means the Management System, so we just look for the other one.  Since this isn’t a key property, we perform the filtering on the client using Powershell.  We store the name of the managed system for later use.

    $managedSystemEPR = Get-WSManInstance @remoteParams -Enumerate -ResourceURI cimv2/CIM_ComputerSystem `
        -Dialect Selector -Filter “Name=’$managedSystemName'” -ReturnType EPR

The CIM method we’ll actually be using later to change the power state requires an EPR (EndPoint Reference) which is the path to an instance.  The WS-Management GET operation doesn’t support returning a EPR (rather than the object itself), so we’ll use a little trick here (otherwise we’d have to construct the XML ourselves).  Basically, I perform an enumeration, but using the Selector filter, I can just get the single instance I care about and have the EPR returned.

    $powerMgmtSvcs = @(Get-WSManInstance @remoteParams -Enumerate -ResourceURI cimv2/* -Dialect Association `
      -Filter “{Object=CIM_ComputerSystem?Name=$ManagedSystemName;ResultClassName=CIM_PowerManagementService}”)

Next, we need to get the CIM_PowerManagementService that is associated with the instance of CIM_ComputerSystem we want to change the power state since the method belongs to this class.  We do this using the Association filter dialect providing the CIM_ComputerSystem instance resource URI and specifying the ResultClassName we want.

    Invoke-WSManAction @remoteParams -ResourceUri cimv2/CIM_PowerManagementService -SelectorSet `
        @{Name=$powerMgmtSvcs[0].Name;CreationClassName=$powerMgmtSvcs[0].CreationClassName} `
        -Action RequestPowerStateChange -ValueSet `
        @{PowerState=$powerState;ManagedElement=$($managedSystemEPR.InnerXml)}

Finally, we are ready to call the RequestPowerStateChange method.  We need to provide the path to the specific instance of CIM_PowerManagementService and I’m using the SelectorSet parameter to do this.  The method parameters is the new PowerState and ManagedElement is the instance of CIM_ComputerSystem we want to power on/off.

I’ll have more scripts and scenarios in the future.  Note that I’ll be on leave during April, so my next post will be either the end of this month or in May.

Steve Lee
Senior Test Manager
Standards Based Management

PowerState.zip


Comments (16)

  1. Aaron says:

    Can you tell me how to do the prerequisite as you said: I assume the hardware you want to manage is already provisioned for remote management.  Also, to successfully execute these scripts, you need to enable unsigned script execution in Powershell, allow unencrypted traffic, and trust the management endpoint in the WinRM client configuration (you should only do these things in a test environment). After I type winrm quickconfig in the server side, it turns out error that WinRM firewall exception and let me set the firewall to either domain or private rather than public.

    I' ll very appreciate your anwser!

  2. SteveLee says:

    @Aaron, to answer your questions (all run as elevated admin in PowerShell):

    1) provisioning the hardware for remote management today is not standardized so it depends on the OEM.  For example, a Dell workstation with Intel vPro (and even different versions of the Management Engine firmware) do it differently than a HP workstation with Broadcom's DASH chip.  You'll need to go to the OEM's website to get specific instructions.

    2) enable unsigned script execution: set-executionpolicy unrestricted

    3) allow unencrypted traffic: Set-Item WSMan:localhostClientAllowUnencrypted true

    4) trust the management endpoint: Set-Item WSMan:localhostClientTrustedHosts <machineNameorIP>

    5) winrm quickconfig is only for configuring a listener on the Windows machine which is not used at all in this specific scenario where Windows is only used as the client

  3. Aaron says:

    @Steve Lee, I'm very appreciate your answer and I have followed the steps: set-executionpolicy unrestricted, Set-Item… as you said.

    However I got the error says"CimSession : Access is denied.

    At line:1 char:10

    +          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

       + CategoryInfo          : PermissionDenied: (:) [New-CimSession], CimException

       + FullyQualifiedErrorId : HRESULT 0x80070005,Microsoft.Management.Infrastructure.C

      imCmdlets.NewCimSessionCommand

  4. SteveLee says:

    @Aaron, if you are running those commands on a machine that is in a Workgroup AND with an account in the administrator's group, but not THE Administrator account, then you'll need to set the Remote UAC TokenFilterPolicy: support.microsoft.com/…/942817

  5. Aaron says:

    @Steve Lee

    I think the server and the client are not using the same username and password, so they should not in the same workgroup and the server and client are both in the win7 OS. I have changed the server's firewall setting to the home one. However, when I type $comp1 = New-CimSession – ComputerName comp1 -Credential $cred. It still get the same error….

  6. SteveLee says:

    @Aaron, it doesn't really matter (for WinRM) if the two machines are in the same Workgroup or different.  However, if in a Workgroup at all (versus a Domain), then the Remote UAC policy applies.  Did you make the change indicated in the link above?

  7. Aaron says:

    @Steve Lee

    I saw the link and it said so serious that I'm afraid I may break down the system coz I'm not so familiar with those stuffs….

  8. SteveLee says:

    @Aaron, actually I linked to an article that is more complicated than what you need.  Try this one: support.microsoft.com/…/951016

  9. Aaron says:

    @Steve Lee, I have created that file in the registry and modified the value to 1 and it still shows the same error.

  10. Steve Lee says:

    Does that modification happens on client? or Server?

  11. Aaron says:

    Does the protocol use DCOM?

  12. SteveLee says:

    No, only WS-Man is used.  The modification is only needed on the "server" (that is the machine you are "remoting to", not "remoting from").  To help make progress on troubleshooting this, let's remove WinRM from the equation.  Can you try to map a drive to a share on the "server"?  (net use z: \remoteMachineshare /u:.user).  Make sure the necessary firewall rules allow for File Sharing.

  13. Aaron says:

    Hi  I can map a drive to a share on the server, and I have set the variable $comp1 and $comp2. However, when I type the command, such as get-powerstate -Cimsession $comp1, $comp2. It turns out to let my input the parameter like Cimsession[0] :     I don't know how to input this .

  14. SteveLee says:

    The get-powerstate script in this article was written before CimSession existed.  I have a newer version of this script as a module with more capabilities that I will publish within the next few weeks (as a Beta) that supports CimSession.  

  15. Harish P says:

    Hi Steve ,

    I need a powershell script to restart my dell Server through DRAC console for out of bound management for my critical application . could you please share me the script to harishge89@gmail.com .

  16. SteveLee says:

    iDrac doesn't support all the CIM Profiles needed (it has Dell specific ones that are similar, but not the same).  Since iDrac supports IPMI, you should use the PCSV cmdlets: technet.microsoft.com/…/dn283380.aspx