Created
August 18, 2018 22:01
-
-
Save smaglio81/5e033ffb25633558369ab692eb6fb0ab to your computer and use it in GitHub Desktop.
Takes a procdump of the w3wp process associated with a given url (either locally or remote). Transfer the process dump to a communal shared location for retrieval.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if($global:WebAdmin -eq $null) { | |
$global:WebAdmin = @{} | |
} | |
# http://stackoverflow.com/questions/1183183/path-of-currently-executing-powershell-script | |
$root = Split-Path $MyInvocation.MyCommand.Path -Parent; | |
$global:WebAdmin.ProcDumpLocalPath = "$root\Resources\procdump.exe" | |
<# | |
.SYNOPSIS | |
Uses sysinternal procdump to get a proc dump of a w3wp service on a webserver. The file will | |
be transfered to a shared location for distribution. | |
.PARAMETER ServerName | |
The server to pull a proc dump from. | |
.PARAMETER Url | |
The url of the website to get a proc dump from | |
.EXAMPLE | |
Command: | |
New-WebProcDumpUcsb -ServerName SA177 -Url my.dev.sa.ucsb.edu/aaa | |
Output: | |
#> | |
Function New-WebProcDump { | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Mandatory=$false)] | |
[string] $ServerName = $env:COMPUTERNAME, | |
[Parameter(Mandatory=$true)] | |
[string] $Url | |
) | |
# setup variables | |
$appPoolName = ConvertTo-UrlBasedAppPoolName -Url $Url | |
$isLocalMachine = Test-IsLocalComputerName -ComputerName $ServerName | |
if((Test-WebAppExists -ServerName $ServerName -Url $Url) -eq $false) { | |
throw "IIS $env:COMPUTERNAME - No webapp could be found for url $Url on $ServerName" | |
} | |
# ensure procdump exists on the remote server | |
if((Test-Path $global:WebAdmin.ProcDumpLocalPath) -eq $false) { | |
throw "IIS $env:COMPUTERNAME - Cannot find local copy of procdump.exe in WebAdministrationUcsb module ($($global:WebAdministrationUcsb.ProcDumpLocalPath)). Ensure it exists before running again." | |
} | |
if($isLocalMachine) { | |
# gonna run procdump locally so the local procdump in the module will be used. | |
} else { | |
# gonna run this on a remote server, so ensure that procdump is on the server | |
$utilRemotePath = "\\{0}\C$\IT\Utilities" -f $ServerName | |
if((Test-Path $utilRemotePath) -eq $false) { | |
New-Item -Path $utilRemotePath -ItemType Directory | Out-Null | |
} | |
$procdumpRemotePath = "$utilRemotePath\procdump.exe" | |
if((Test-Path $procdumpRemotePath) -eq $false) { | |
Copy-Item -Path $global:WebAdministrationUcsb.ProcDumpLocalPath -Destination $utilRemotePath | Out-Null | |
} | |
} | |
# get the process info from the remote server | |
$processScript = { | |
if($appPoolName -eq $null) { | |
$appPoolName = $args[0] | |
} | |
Import-Module WebAdministration | |
$webModule = Get-Module WebAdministration | |
if(-not $webModule) { | |
Import-Module WebAdministration | |
} | |
$processes = dir "IIS:\AppPools\$appPoolName\WorkerProcesses" | |
return $processes | |
} | |
$params = @($appPoolName) | |
if($isLocalMachine) { | |
$w = . $processScript | |
} else { | |
$w = Invoke-Command -ComputerName $ServerName -ScriptBlock $processScript -ArgumentList $params | |
} | |
if($w -eq $null) { | |
throw "IIS $env:COMPUTERNAME - No process for appPool $appPoolName on $ServerName could be found." | |
} | |
if(@($w).Count -gt 1) { | |
throw "IIS $env:COMPUTERNAME - Multiple processes for appPool $appPoolName on $ServerName were found. This is weird, contact an administrator. Process Count: $(@($w).Count)" | |
} | |
# run the dump remotely | |
$dumpScript = { | |
if($processId -eq $null) { | |
$processId = $args[0] | |
} | |
if($procdump -eq $null) { | |
$procdump = "C:\IT\Utilities\procdump.exe" | |
} | |
cd "C:\Users\$($env:USERNAME)\AppData\Local\Temp" | |
$out = . $procdump -ma -accepteula $processId | |
$line = $out |? { $_ -match "Dump 1 initiated" } | |
$ix = $line.IndexOf("ed: ") | |
$path = $line.Substring($ix + 4) | |
return $path | |
} | |
$processId = $w.processId | |
$procdump = $global:WebAdmin.ProcDumpLocalPath | |
if($isLocalMachine) { | |
$path = . $dumpScript | |
} else { | |
$path = Invoke-Command -ComputerName $ServerName -ScriptBlock $dumpScript -ArgumentList $processId | |
} | |
# copy dump to local storage | |
$sharepath = "" | |
if([string]::IsNullOrWhiteSpace($path) -eq $false) { | |
$nwPath = $path -replace "C:\\", "\\$ServerName\C$\" | |
if(Test-Path $nwPath) { | |
$parent = Split-Path $nwPath -Parent | |
$leaf = Split-Path $nwPath -Leaf | |
$null = . robocopy "$parent" "D:\Temp\" /r:1 /w:1 $leaf | |
$locpath = "D:\Temp\$leaf" | |
$curnttime = [DateTime]::Now.ToString("yyyyMMddHHmm") | |
$newfilename = "$ServerName-$appPoolName-w3wp-$curnttime.dmp" | |
$newpath = "D:\Temp\$newfilename" | |
mv $locpath $newpath | |
del $nwPath -Force -ErrorAction SilentlyContinue | |
$sharepath = "\\$($env:COMPUTERNAME)\d\temp\$newfilename" | |
} | |
} | |
return $sharepath | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment