kernel32/FormatMessage.ps1

function FormatMessage
{
    <#
    .SYNOPSIS
 
    Formats a message string and returns a string.
 
    .DESCRIPTION
 
    The function requires a message definition as input. The message definition can come from a buffer passed into the function. It can come from a message table resource in an already-loaded module. Or the caller can ask the function to search the system's message table resource(s) for the message definition. The function finds the message definition in a message table resource based on a message identifier and a language identifier. The function copies the formatted message text to an output buffer, processing any embedded insert sequences if requested.
 
    .PARAMETER FormatMessageFlags
 
    A FORMAT_MESSAGE_FLAGS enum containing the formatting options, and how to interpret the lpSource parameter. The low-order byte of dwFlags specifies how the function handles line breaks in the output buffer. The low-order byte can also specify the maximum width of a formatted output line.
     
    .PARAMETER ResourceHandle
 
    A handle to the resource that is passed to lpSource parameter. Typically this is a handle to the message table from a call to LoadResource.
 
    .PARAMETER MessageId
 
    The message identifier for the requested message.
 
    .PARAMETER LanguageId
 
    The language identifier for the requested message.
 
    .NOTES
 
    Author: Brian Reitz (@brian_psu)
    License: BSD 3-Clause
    Required Dependencies: PSReflect
    Optional Dependencies: None
 
    (func kernel32 FormatMessage ([UInt32]) @(
        [UInt32], #_In_ DWORD dwFlags,
        [IntPtr], #_In_ LPCVOID lpSource,
        [UInt32], #_In_ DWORD dwMessageId,
        [UInt32], #_In_ DWORD dwLanguageId,
        [IntPtr], #_Out_ LPTSTR lpBuffer
        [UInt32], #_In_ DWORD nSize,
        [IntPtr] #_Out_ va_list Arguments
    ) -EntryPoint FormatMessage -SetLastError),
 
    .LINK
 
    https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessage
     
    .EXAMPLE
    #>


    param
    (     
 
        [Parameter()]
        # [ValidateSet('FORMAT_MESSAGE_ALLOCATE_BUFFER','FORMAT_MESSAGE_ARGUMENT_ARRAY','FORMAT_MESSAGE_FROM_HMODULE','FORMAT_MESSAGE_FROM_STRING','FORMAT_MESSAGE_FROM_SYSTEM', 'FORMAT_MESSAGE_IGNORE_INSERTS')]
        [string[]]
        $FormatMessageFlags = @('FORMAT_MESSAGE_ALLOCATE_BUFFER','FORMAT_MESSAGE_FROM_HMODULE','FORMAT_MESSAGE_IGNORE_INSERTS'),

        [Parameter(Mandatory = $true)]
        [IntPtr]
        $ResourceHandle,

        [Parameter()]
        [UInt32]
        $MessageId = 0,

        [Parameter()]
        [UInt32]
        $LanguageId = 0
    )

    # https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessage

    # Calculate dwFlags
    [UInt32]$dwFlags = 0
    foreach($val in $FormatMessageFlags)
    {
        $dwFlags = $dwFlags -bor $FORMAT_MESSAGE_FLAGS::$val
    }

    [IntPtr]$MessagePtr = [IntPtr]::Zero
    [string]$Message = "" 
    $BytesReturned = $kernel32::FormatMessage(
        $dwFlags,
        $ResourceHandle,
        $MessageId,
        $LanguageId,
        [ref]$MessagePtr,
        0,
        [IntPtr]::Zero
        );$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()

    if($BytesReturned -eq 0)
    {
        throw "[FormatMessage]: Error: $(([ComponentModel.Win32Exception] $LastError).Message)"
    } else {
        $Message = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($MessagePtr)
        $Message = $Message.Replace("`r`n","")
    }

    Write-Output $Message
}