Skip to content

Instantly share code, notes, and snippets.

@Bill-Stewart
Last active May 14, 2024 15:40
Show Gist options
  • Save Bill-Stewart/ae21669dedbd4d5d11fbba62baf9dd1b to your computer and use it in GitHub Desktop.
Save Bill-Stewart/ae21669dedbd4d5d11fbba62baf9dd1b to your computer and use it in GitHub Desktop.
Get-Message.ps1
# Get-Message.ps1
# Written by Bill Stewart (bstewart AT iname.com)
# Version history:
#
# 0.1.0 (2023-07-11)
# * Initial version.
#
# 1.0.0 (2024-05-14)
# * Improved: MessageId parameter now allows unsigned 32-bit values.
# * Changed: Use .NET Win32Exception class rather than P/Invoke unmanaged code.
#requires -version 3
<#
.SYNOPSIS
Gets the Windows message string for a specified message ID number.
.DESCRIPTION
Gets the Windows message string for a specified message ID number. A Windows message ID can be a 32-bit value, where the high (most significant) 16 bits are a "facility code" and the low (least significant) 16 bits are the Windows message ID. The Windows message string is obtained by getting the Win32 error message from the low 16 bits.
.PARAMETER MessageId
Specifies the message ID number. Message ID numbers can be specified as signed, unsigned, or hexadecimal (0x) values.
.OUTPUTS
Objects with the following properties:
* ID_Dec_Signed - Message ID as a signed decimal 32-bit value
* ID_Dec_Unsigned Message ID as an unsigned decimal 32-bit value
* ID_Hex - Message ID as a hexadecimal value
* LowWord_Dec - Low 16 bits of message ID (decimal)
* LowWord_Hex - Low 16 bits of message ID (hex)
* Message - Message string (if found)
.EXAMPLE
PS C:\> Get-Message -2147024843
This command converts the signed decimal value to unsigned decimal value 2147942453, which is hex 0x80070035. The low 16 bits of this value is 0x35 (decimal 53), which corresponds to the English message string "The network path was not found."
.EXAMPLE
PS C:\> Get-Message 1325
Message ID 1325 is hex 0x052D, which corresponds to the English message string "Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirements of the domain."
.EXAMPLE
PS C:\> Get-Message 0x57
Message ID 0x57 is decimal code 87, which corresponds to the English message string "The parameter is incorrect."
#>
[CmdletBinding()]
param(
[Parameter(Mandatory,ValueFromPipeline)]
$MessageId
)
begin {
function Get-Integer {
param(
$value
)
if ( $null -ne ($value -as [Int]) ) {
[System.BitConverter]::ToInt32([System.BitConverter]::GetBytes($value -as [Int]),0)
}
elseif ( $null -ne ($value -as [UInt32]) ) {
[System.BitConverter]::ToInt32([System.BitConverter]::GetBytes($value -as [UInt32]),0)
}
}
function Get-Low16Bits {
param(
[Int]
$value
)
$bytes = [BitConverter]::GetBytes($value)
(($bytes[1] -as [Int]) -shl 8) -bor $bytes[0]
}
function Get-WindowsMessage {
param(
[Int]
$messageId
)
$low16Bits = Get-Low16Bits $messageId
[PSCustomObject] @{
"ID_Dec_Signed" = $messageId
"ID_Dec_Unsigned" = [BitConverter]::ToUInt32([BitConverter]::GetBytes($messageId),0)
"ID_Hex" = "0x{0:X8}" -f $messageId
"LowWord_Dec" = $low16Bits
"LowWord_Hex" = "0x{0:X4}" -f $low16Bits
"Message" = "{0}." -f ([ComponentModel.Win32Exception] $low16Bits).Message
}
}
}
process {
foreach ( $MessageIdItem in $MessageId ) {
$MessageIdValue = Get-Integer $MessageIdItem
if ( $null -ne $MessageIdValue ) {
Get-WindowsMessage $MessageIdValue
}
else {
Write-Error ("Cannot convert value '{0}' to an integer." -f $MessageIdItem) -Category InvalidType
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment