In several places in Windows (but especially in functions and calls resolving around COM) the errors/warnings returned by Windows APIs are returned as 32-bit numbers HRESULT. The binary value of HRESULT adds a special meaning for certain bits, like information about the type of the error, origin and much more.
Let’s analyze an example value of HRESULT 0x800706BA
, which may be also represented in decimal form –2147023174
. When seeing that number being returned by the API, it is usually not quite clear what the actual error really is. Wikipedia has a really simple explanation of how the number is structured:
https://en.wikipedia.org/wiki/HRESULT
Based on the specification and a header file to find out the mappings between facilities and their identifiers, I created a simple PowerShell function, which – given a number representing HRESULT – returns a human-friendly structure. This way you can convert this:
0x800706BA
into this:
HResult : -2147023174
HResultHex : 0x800706BA
HResultBin : 10000000000001110000011010111010
Facility : FACILITY_WIN32
FacilityCode : 7
ErrorCode : 1722
IsFailure : True
Message : RPC server is unavailable
IsCustom : False
IsServerFailure : False
Much better, isnt’t it? Turns out, this particular HRESULT represents an error, code 1722 (RPC Server is unavailable. Some other information, including representation in different formats are also there.
The usage is simple as that:
Get-ActualError 0x800706BA
and the full source code is available in the following gist:
https://gist.github.com/marcinotorowski/8c09fc556469b22a9df421be51e370b2
This is nice, but how do I obtain the HRESULT from a failed PowerShell cmdlet? I have the following code:
try {Add-AppxPackage $filename)
catch {$Errpr}
If a newer version of the package is already installed, $Error prints “Add-AppxPackage : Deployment failed with HRESULT: 0x80073D06, The package could not be installed because a higher version of this package
is already installed.” plus a bunch of additional garbage. I need to get just the HRESULT so I can test for that code and treat this error as benign, but still display and halt on other errors.