How to create dump files remotely (ProcDump) using PowerShell?

Recently I had to create memory dump files for multiple remote servers. I found great tool called ProcDump on Microsoft page which can do it. Unfortunately it can’t be run remotely so I had to combine this tool features with PowerShell commands.

ProcDump

ProcDump is a command-line utility whose primary purpose is monitoring an application for CPU spikes and generating crash dumps during a spike that an administrator or developer can use to determine the cause of the spike. For more information about this great tool please visit Microsoft docs page.

At the bottom of the page you will find download link:

Download procdump
Download procdump

You can create folder on d: drive – "D:\procdump_script\tmp" on source server. Script will use this path to copy .exe files to remote machines:

procdump files
procdump files

In this example I would like to show you have to get memory dump files for ADFS process. Below you can find example how to create it file locally:

#Process name of ADFS service
$ProcessName = "Microsoft.IdentityServer.ServiceHost" 
$Srv = Get-Process -Name $ProcessName  | Select-Object ProcessName,Id
New-Item -Path "d:\tmp\dumps" -Type directory -Force
cmd.exe /c "d:\tmp\procdump.exe" -ma $Srv.id -accepteula "d:\tmp\dumps\"

As you can see above in last code line -ma parameter has been used. This will get dump file with all process memory:

-ma – Write a dump file with all process memory. The default dump format only includes thread and handle information.

Final script:

#=======================================================================
#Servers
$Servers = Get-Content -Path "D:\scripts\input.txt"

#Location with procdump exe files
$ProcDumpPath = "D:\procdump_script\tmp"

#Process name
$ProcessName = "Microsoft.IdentityServer.ServiceHost" 

#=======================================================================
#Looping each server
Foreach($Server in $Servers)
{
    $Server = $Server.Trim()
    Write-Host "Processing $Server" -ForegroundColor Green
    
    #Testing path 
    $DestinationPath = "\\$Server\d$\"
    $TestPath = Test-Path $DestinationPath
 
    If(!$TestPath)
    {
        Write-Warning "Failed to access: $DestinationPath"
    }
    Else
    {
        Write-Host "Copying Procdump files to $DestinationPath"
        $CopyError = $Null
        $Srv = $Null
        
        Try
        {
            #Copying procdump files to server
            Copy-Item -Recurse $ProcDumpPath -Destination $DestinationPath -Force -ErrorVariable CopyError -ErrorAction Stop

            #Creating folder for dumps and getting process id
            If(!$CopyError)
            {
                $Fold = New-Item -Path \\$Server\d$\tmp\dumps -Type directory -Force -ErrorAction Stop
                $Srv = Get-Process -ComputerName $Server -Name $ProcessName -ErrorAction Stop | Select-Object ProcessName,Id
            }
        }
        Catch
        {
            $_.Exception.Message
            Continue
        }
        
        If($Srv)
        {
            $SrvDump = $Null
            $SrvDumpPath = $Null

            Write-Host 'Creating dump file "d:\tmp\dumps\"'
            #Creating procdump and save in "d:\tmp\dumps\"
            Try
            {
                $SrvDump = Invoke-Command $Server -ErrorAction Stop -ScriptBlock{param($Srv)  
 
                       cmd.exe /c "d:\tmp\procdump.exe"  -ma $Srv.id -accepteula "d:\tmp\dumps\"
 
                } -ArgumentList $Srv
 
                $SrvDumpPath = $SrvDump | Where-Object {$_ -match "initiated"} 
                $SrvDumpPath -Replace  '(\[\d\d:\d\d:\d\d\]\ Dump \d initiated: )'
            }
            Catch
            {
                $_.Exception.Message
                Continue
            }
        }
    }
}#Foreach loop end
 
Read-Host "`nPress any key to exit..."
exit

Leave a Reply

Your email address will not be published. Required fields are marked *