Deciphering error codes

If you’ve been working with WMI or SCCM or just once encountered an error code that needs to be first converted to be troubleshooted (I mean have hits to MSDN or Technet or support.microsoft.com in Google), Powershell is your friend 🙂

I’ve been working to convert some vbscript to powershell that had to constants written with an hexadecimal notation

private const HKEY_LOCAL_MACHINE = &H80000002

Converted to powershell, we would simply write

$HKLM = 0x80000002

But later on, while I was working with modifying the registry through WMI (using “ROOT\DEFAULT:StdRegProv”), I had a dilema.
Should the HKEY_LOCAL_MACHINE be written like this

$HKLM = 2147483650

or

$HKLM = 0x80000002

Actually both notations are correct and only their type are different.

To figure it out, I did:

0x80000002 | gm
-2147483646 -eq 0x80000002
2147483650 | gm
"{0:X0}" -f ([int64]2147483650)

The following resources also helped me figure it out

The first parameter is the value to convert and the second value is the base (i.e. 2 for binary, 8 for octal, 10 for decimal, and 16 for hexadecimal).

Note also that the WMI registry provider “ROOT\DEFAULT:StdRegProv” and Invoke-WMIMethod cmdlet will accept the long integer and not the hexadecimal/int32.
I’ve also found a list of registry hives with both values on this page :

HKEY_CLASSES_ROOT (2147483648 (0x80000000))
HKEY_CURRENT_USER (2147483649 (0x80000001))
HKEY_LOCAL_MACHINE (2147483650 (0x80000002))
HKEY_USERS (2147483651 (0x80000003))
HKEY_CURRENT_CONFIG (2147483653 (0x80000005))
HKEY_DYN_DATA (2147483654 (0x80000006))

I couldn’t resist and quickly wrote a function that would help deciphering any of these error codes whatever their type:

Function Get-ErrorCode {
[CmdletBinding()]
param(
    [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
    [System.Object[]]$InputObjet
)
Begin {}
Process {
    $InputObjet | ForEach-Object -Process {
        $hex = $int64 = $int32 = $null
        Write-Verbose -Message "Dealing with $_ as $($_.GetType())"
        Switch ($_)
        {
            {$_ -is [string]}  {
                $hex = "{0:X0}" -f ([int32]$_)
                $int64 = [Convert]::ToInt64($hex,16)
                $int32 = $_
                break
            }
           {$_ -is [int32]}  {
                $hex = "{0:X0}" -f ([int32]$_)
                $int64 = [Convert]::ToInt64($hex,16)
                $int32 = $_
                break
            }
            {$_ -is [int64]}  {
                $hex = "{0:X0}" -f ([int64]$_)
                $int64 = $_
                $int32 = [Convert]::ToInt32($hex,16)
                break
            }
            default {}
        }
        New-Object -TypeName psobject -Property @{
            Hexadecimal = "0x$hex"
            Int32 = $int32
            Int64 = $int64
        }
    }
}
End {}
}

To test the above function, you can do for example:


Get-ErrorCode -2147483646 -Verbose
Get-ErrorCode -InputObjet (-2147483646) -Verbose
2147483650,0x80000002,-2147483646 | Get-ErrorCode -Verbose | fl -Property *
Advertisements

One thought on “Deciphering error codes

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s