Hi S-1-1-0! Today's topic is described in the post header :)
I guess most of you have encountered with some application/system issues. Sometimes the only information you have is Win32 error code and nothing else. To find a text message for particular error you usually use Google/Bing and/or other tools, like Err.exe from Windows Server 2003 Resource Kit. Yesterday I wrote a PowerShell script that will convert Win32 error code to a readable text. The code uses FormatMessage() WinAPI function. Here is a known limitation, this function doesn't handle network-related errors (that are defined in wininet.h header file). Hopefully my script resolves this limitation by adding a reference to the wininet.dll library when it is necessary. Here is a code snippet:
function Get-ErrorMessage { [OutputType('System.String')] [CmdletBinding()] param( [Parameter(Mandatory = $true)] [int]$ErrorCode ) $signature = @' [DllImport("kernel32.dll", SetLastError=true)] public static extern uint FormatMessage( uint dwFlags, IntPtr lpSource, int dwMessageId, uint dwLanguageId, ref IntPtr lpBuffer, uint nSize, IntPtr Arguments ); [DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)] public static extern IntPtr LoadLibrary( string lpFileName ); [DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)] public static extern bool FreeLibrary( IntPtr hModule ); [DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)] public static extern IntPtr LocalFree( IntPtr hMem ); '@ try {Add-Type -MemberDefinition $signature -Name Kernel32 -Namespace PKI} catch {Write-Warning $Error[0].Exception.Message; return} $StartBase = 12000 $EndBase = 12176 $ErrorHex = "{0:x8}" -f $ErrorCode $HighBytes = iex 0x$($ErrorHex.Substring(0,4)) $LowBytes = iex 0x$($ErrorHex.Substring(4,4)) $lpMsgBuf = [IntPtr]::Zero if ($LowBytes -gt $StartBase -and $LowBytes -lt $EndBase) { $hModule = [PKI.Kernel32]::LoadLibrary("wininet.dll") $dwChars = [PKI.Kernel32]::FormatMessage(0xb00,$hModule,$LowBytes,0,[ref]$lpMsgBuf,0,[IntPtr]::Zero) [void][PKI.Kernel32]::FreeLibrary($hModule) } else {$dwChars = [PKI.Kernel32]::FormatMessage(0x1300,[IntPtr]::Zero,$ErrorCode,0,[ref]$lpMsgBuf,0,[IntPtr]::Zero)} if ($dwChars -ne 0) { ([Runtime.InteropServices.Marshal]::PtrToStringAnsi($lpMsgBuf)).Trim() [void][PKI.Kernel32]::LocalFree($lpMsgBuf) } else { Write-Error -Category ObjectNotFound ` -ErrorId "ElementNotFoundException" ` -Message "No error messages are assoicated with error code: 0x$ErrorHex ($ErrorCode). Operation failed." } }
The usage is very simple:
[↓] [vPodans] Get-ErrorMessage 0x80070005 Access is denied. [↓] [vPodans] # short notation of this error: [↓] [vPodans] Get-ErrorMessage 5 Access is denied. [↓] [vPodans] Get-ErrorMessage 0x80072ee6 The URL does not use a recognized protocol [↓] [vPodans] 0x80072ee6 -2147012890 [↓] [vPodans] Get-ErrorMessage -2147012890 The URL does not use a recognized protocol [↓] [vPodans] Get-ErrorMessage 1 Incorrect function. [↓] [vPodans]
as you see, it accepts errors in 3 formats:
Even though the script won't handle any Win32 errors, but, most of them — definitely and this function will be included as a part of my upcoming PowerShell PKI module update.
HTH
That's great!
What a great work! Thanks for sharing it.
Post your comment:
Comments: