HP ILO Cmdlets violate the first law of powershell

So this isn’t strictly a question, but I just had to rant about this somewhere. Feel free to delete this if needed.

The HP ILO cmdlets from HP found here:

http://www8.hp.com/us/en/products/server-software/product-detail.html?oid=5440657#!tab=features

are, in theory, useful for managing the out-of-band management interfaces (ilo) of HP servers. However, in trying to script around them and catch the error output I was getting nowhere. I look into the cmdlet code itself and what do I find? not a write-error or throw, but

WRITE-HOST “ERROR MESSAGE” -FOREGROUNDCOLOR RED

ARE YOU KIDDING ME HP?!?! REALLY?!?

Now I’m no expert programmer and maybe there’s a valid reason for doing this, but I can’t for the life of me think of what it could be. For anyone reading this, don’t ever do this, it makes the output completely useless for any kind of branching logic or anything. Use write-error. Also, if you are using these cmdlets be aware that the “error” output is anything but.

/rant

Yuck. If I had to use that crap, I’d probably monkey patch it with a Write-Host proxy function, something like this:

$crapModule = Import-Module HPiLOCmdlets -PassThru

& $crapModule {
    function script:Write-Host
    {
        [CmdletBinding()]
        param(
            [Parameter(Position=0, ValueFromPipeline=$true, ValueFromRemainingArguments=$true)]
            [System.Object]
            ${Object},
    
            [switch]
            ${NoNewline},
    
            [System.Object]
            ${Separator},
    
            [System.ConsoleColor]
            ${ForegroundColor},
    
            [System.ConsoleColor]
            ${BackgroundColor})
    
        begin
        {
            if ($ForegroundColor -ne 'Red')
            {
                try {
                    $outBuffer = $null
                    if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
                    {
                        $PSBoundParameters['OutBuffer'] = 1
                    }
                    $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Utility\Write-Host', [System.Management.Automation.CommandTypes]::Cmdlet)
                    $scriptCmd = {& $wrappedCmd @PSBoundParameters }
                    $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
                    $steppablePipeline.Begin($PSCmdlet)
                } catch {
                    throw
                }
            }
        }
    
        process
        {
            if ($ForegroundColor -eq 'Red')
            {
                Write-Error -Message ($object | Out-String)
            }
            else
            {
                try {
                    $steppablePipeline.Process($_)
                } catch {
                    throw
                }
            }
        }
    
        end
        {
            if ($ForegroundColor -ne 'Red')
            {
                try {
                    $steppablePipeline.End()
                } catch {
                    throw
                }
            }
        }
    }
}

Amen to that. I have had the unfortunate “pleasure” of working with the iLO Cmdlets as well, and found the overall quality and consistency to be questionable at best.

Interesting approach with the monkey patching Dave :slight_smile:

I’ve been inspired … we need a fight-club-esque list of laws to be stickied at the top.

Fun, helpful, lets do it.

Though I propose that the first law of powershell should be: you will try to do it in PowerShell first.