src/Get-PsDump.ps1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
#requires -version 6 using namespace System.IO using namespace System.Text using namespace Microsoft.Win32.SafeHandles Set-Alias -Name psdump -Value Get-PsDump function Get-PsDump { [CmdletBinding()] param( [Parameter(Mandatory, Position=0)] [ValidateScript({!!($script:ps = Get-Process -Id $_ -ErrorAction 0)})] [Int32]$Id, [Parameter()] [ValidateNotNullOrEmpty()] [ValidateSet('MiniDump', 'FullDump')] [String]$DumpType = 'MiniDump', [Parameter()] [ValidateNotNullOrEmpty()] [ValidateScript({Test-Path $_})] [String]$SavePath = $pwd.Path ) begin { $kernel32, $dmp = (New-Delegate kernel32 -Signature @{ LoadLibraryW = [Func[[Byte[]], IntPtr]] FreeLibrary = [Func[IntPtr, Boolean]] }), "${SavePath}\$($ps.Name)_${Id}.dmp" } process {} end { try { if (!($dll = $kernel32.LoadLibraryW.Invoke( [Encoding]::Unicode.GetBytes('dbghelp.dll') ))) { throw [DllNotFoundException]::new() } $dbghelp, $fs, $numeric = (New-Delegate dbghelp -Signature @{ MiniDumpWriteDump = [Func[IntPtr, UInt32, SafeFileHandle, UInt32, IntPtr, IntPtr, IntPtr, Boolean]] }), [File]::Create($dmp), (6, 261)[$DumpType -eq 'MiniDump'] if (!$dbghelp.MiniDumpWriteDump.Invoke( $ps.Handle, ${Id}, $fs.SafeFileHandle, $numeric, [IntPtr]::Zero, [IntPtr]::Zero, [IntPtr]::Zero )) { $err = $true throw [InvalidOperationException]::new() } } catch { Write-Verbose $_ } finally { if ($fs) { $fs.Dispose() } if ($dll) { if (!$kernel32.FreeLibrary.Invoke($dll)) { Write-Verbose 'Could not release dbghelp.dll library.' } } if ($err) { Remove-Item $dmp -Force -ErrorAction 0 } } $ps.Dispose() } } |