Public/Out-MiniDump.ps1

# ? TITEL Out-MiniDump
# ? DESCRIPTION
# ? TAGS UserCmdlet
# ? VERSION 2019.09.09

using namespace System
using namespace System.Runtime.InteropServices
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
Set-StrictMode -Version Latest

function Out-MiniDump {
    <#
        .SYNOPSIS
        Memorydump of a process.
  
        .PARAMETER Process
        The process object is obtained with Get-Process.
  
        .PARAMETER DumpFilePath
        Specifies the path where dump files will be written. By default, dump files are written to the current working directory. Dump file names take following form: processname_id.dmp
  
        .EXAMPLE
        Out-Minidump -Process (Get-Process -Id 4293)
        Get-Process lsass | Out-Minidump
        Get-Process | Out-Minidump -DumpFilePath C:\temp
  
        .INPUTS
        System.Diagnostics.Process => You can pipe a process object to Out-Minidump.
  
        .OUTPUTS
        System.IO.FileInfo
    #>

    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [System.Diagnostics.Process]
        $Process,

        [ValidateScript({ Test-Path $_ })]
        [String]
        $DumpFilePath = $PWD
    )

    BEGIN {
        $WER = [PSObject].Assembly.GetType('System.Management.Automation.WindowsErrorReporting')
        $WERNativeMethods = $WER.GetNestedType('NativeMethods', 'NonPublic')
        $Flags = [Reflection.BindingFlags]'NonPublic, Static'
        $MiniDumpWriteDump = $WERNativeMethods.GetMethod('MiniDumpWriteDump', $Flags)
        $MiniDumpWithFullMemory = [UInt32]2
    }

    PROCESS {
        $ProcessId = $Process.Id
        $ProcessName = $Process.Name
        $ProcessHandle = $Process.Handle
        $ProcessFileName = "$($ProcessName)_$($ProcessId).dmp"
        $ProcessDumpPath = Join-Path $DumpFilePath $ProcessFileName
        
        $FileStream = New-Object IO.FileStream($ProcessDumpPath, [IO.FileMode]::Create)
        "ACHTUNG: Tauschen Sie ERSETZ_MICH durch Invoke aus, erstellen Sie eine Ausnahme für den Windows Defender und löschen Sie diese Zeile" | Write-Error
        $Result = $MiniDumpWriteDump.ERSETZ_MICH($null, @($ProcessHandle, $ProcessId, $FileStream.SafeFileHandle, $MiniDumpWithFullMemory, [IntPtr]::Zero, [IntPtr]::Zero, [IntPtr]::Zero))
        $FileStream.Close()

        if (-not $Result) {
            $Exception = New-Object ComponentModel.Win32Exception
            $ExceptionMessage = "$($Exception.Message) ($($ProcessName):$($ProcessId))"
            Remove-Item $ProcessDumpPath -ErrorAction SilentlyContinue
             Write-Error -Exception $ExceptionMessage
        }
        else {
            Get-ChildItem $ProcessDumpPath
        }
    }

    END {}
}