HP servers have redundant power supplies.  SCOM will tell me which one is broken if it’s down, but in this case, I lost power to one side of the rack, and want to see if replacing the distribution unit fixed the issue.  Here’s a quick-and-dirty WMI wrapper to do that:


function Get-HPPowerSupplyStatus
{
    <#
    .snyopsis
    Get HP Power Supply status for each power supply

    .description
    Get-WmiObject -Namespace Root\HPQ -class HP_PowerSupply to extract out the SystemName, DeviceID, and StatusDescriptions (plural) properties.

    Uses WinRM to run the WMI queries locally for efficiency.

    By default, returns only power supply data for ones that do not have StatusDescriptions value of "Power Supply is operating normally".

    .parameter ComputerName
    Name(s) of computers on which to query.  Defaults to localhost.

    .parameter TimeoutInterval
    Seconds to wait for all jobs to complete.  Defaults to 60 seconds.

    .parameter JobPollingInterval
    Seconds to wait between polling for newly completed WinRM jobs.  Defaults to 5 seconds.

    .parameter ThrottleLimit
    Number of jobs to run at a time.  Defaults to 100.

    .parameter Full
    Return power suppy data for all power supplies, regardless of StatusDescriptions value.

    .outputs
    PsCustomObject with properties ComputerName, DeviceID, and StatusDescriptions

    .notes
    When        What        Who         Why 
    2014-05-20  v1.0        timdunn     RTO
    
    #>

    param (
        [Parameter(ValueFromPipeLine=$true)][String[]]$ComputerName = @($env:ComputerName),
        [int]$TimeoutInterval = 60,
        [int]$JobPollingInterval = 5,
        [int]$ThrottleLimit = 100,
        [switch]$Full
    )

    begin {

            $scriptBlock = {
                Get-WmiObject -Namespace Root\HPQ -Class HP_PowerSupply -ErrorAction SilentlyContinue | 
                Select-Object -Property @{
                    n = 'ComputerName';
                    e = { $_.SystemName.ToLower(); }
                }, DeviceID, @{
                    n = 'StatusDescriptions';
                    e = { [string]::Join(",", $_.StatusDescriptions); }
                }
            } # $scriptblock
            $jobs = New-Object System.Collections.ArrayList;
    
    }

    process {

        foreach ($computer in $ComputerName)
        {
            if (($Computer -match "^$env:ComputerName\.") -or ($Computer -match "^$env:ComputerName$"))
            {
                $jobs.Add((Start-Job -ScriptBlock $scriptblock -ArgumentList $arguments)) | Out-Null;
            } # if (($Computer -match "^$env:ComputerName\.") -or ($Computer -match "^$env:ComputerName$"))
            else
            {
                $jobs.Add((
                    Invoke-Command -AsJob -ScriptBlock $scriptblock -ArgumentList $arguments -ComputerName $computer -ThrottleLimit $ThrottleLimit -HideComputerName 
                )) | 
                Out-Null;
            } # if (($Computer -match "^$env:ComputerName\.") -or ($Computer -match "^$env:ComputerName$")) ... else
        
        } # foreach ($computer in $ComputerName)
    
    } # process

    end {

        $initialCount = $jobs.Count;
        $notAfter = (Get-Date) + (New-TimeSpan -Seconds $TimeoutInterval);
        while ($jobs)
        {
            $now = Get-Date;
            if ($now -gt $notAfter) { break; }

            Write-Progress $now "$($jobs.Count)/$initialCount jobs and $([int]($notAfter - $now).TotalSeconds) seconds to go.";

            Get-Job -Id ($jobs | % { $_.Id }) |
            ? { $_.State -ne 'Running' } |
            % {
                if ($_.State -eq 'Completed')
                {
                    if ($data = (Receive-Job -Id $_.Id))
                    {
                        if ($ShowRunspaceID)
                        {
                            $data;

                        } # if ($ShowRunspaceID)
                        else
                        {
                            $properties = $data | Get-Member -MemberType *Propert* | 
                            % { 
                                if ($_.name -ne 'RunspaceId') 
                                {
                                    $_.name;

                                } # if ($_.name -ne 'RunspaceId') 

                            } # $properties = $data | Get-Member -MemberType *Propert* | 

                            $data | Select-Object -Property $properties;

                        } # if ($ShowRunspaceID) ... else

                    } # if ($data = (Receive-Job -Id $_.Id))
                    else
                    {
                        Write-Warning "No data-received from job at $($_.Location)";

                    } # if ($data = (Receive-Job -Id $_.Id)) ... else

                    Remove-Job -id $_.Id;

                } # if ($_.State -eq 'Completed')
                else
                {
                    Write-Warning "JobId $($_.Id) failed.  Please investigate.";

                } # if ($_.State -eq 'Completed') ... else

                $jobs.Remove($_) | Out-Null;

            } |
            ? {
                if (($Full) -or ($_.StatusDescriptions -ne 'Power Supply is operating properly'))
                {
                    $_;

                } # if (($Full) -or ($_.StatusDescriptions -ne 'Power Supply is operating properly'))

            } # Get-Job -Id ($jobs | % { $_.Id }) | ? { $_.State -ne 'Running' }

            if ($jobs) { start-sleep $JobPollingInterval; }

        } # while ($jobs)

    } # end
} # function Get-HPPowerSupplyStatus