Configuring application Crash dumps with Powershell

In a windows environment applications crash for many reasons and the best way to troubleshoot them is to collect a application crash dump. An application crash dump is a snapshot of what the application was doing when it crashed.

From Windows Vista and Windows Server 2008 onwards Microsoft introduced Windows Error Reporting or WER . This allows the server to be configured to automatically enable the generation and capture of Application Crash dumps. The configuration of this is discussed here . The main problem with the default configuration is the dump files are created and stored in the  %APPDATA%\crashdumps folder running the process which can make it awkward to collect dumps as they are spread all over the server. There are additional problems with this as but the main problem I always had with it was that its a simple task that is very repetitive but easy to do incorrectly. Therefore is it a perfect task to be automated.

I wrote this little script in Powershell

app_crashdump.ps1

This script does 3 things :

  1. Creates a folder to put the crash dumps in
  2. Gives the appropriate accounts access to this folder
  3. Configures the registry with the appropriate settings

Part 1 : Creating the folder

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
$Folder=[Microsoft.VisualBasic.Interaction]::InputBox("Specify where to store crashdumps (not network location)", "Path", "c:\Crashdump")

New-Item $Folder -Type Directory -ErrorAction SilentlyContinue

### Verify the folder the user specified was a valid folder. Else failback to c:\Crashdump

$validatepath=Test-Path $Folder
	if ($validatepath -eq $false)
	{
	New-Item C:\Crashdump -Type Directory
	Set-Variable -Name Folder -value C:\Crashdump -Scope Script
	}

This piece of code asks the user for input as to where to put the folder, makes the folder. If it cannot make the folder the user suggested then it has a default path of c:\Crashdump

Part 2 : Specifying the permissions

$Acl= get-acl $Folder
$machinename = hostname
$querydomain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$domain = $querydomain.name

#Setting ACLs

$Acl.SetAccessRuleProtection($true, $false)
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("Network","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")))
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("Network Service","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")))
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("Local Service","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")))
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("System","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")))
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("Everyone","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")))

Set-Acl $folder $Acl

This code just defines some variables and assigns the following user accounts permissions to write to the folder

Network, Network Service, Local Service, System  and the domain account everyone. It then writes the ACL back to the folder.

Part 3: Actually configuring WER

$verifydumpkey = Test-Path "HKLM:\Software\Microsoft\windows\Windows Error Reporting\LocalDumps"

	if ($verifydumpkey -eq $false )
	{
	New-Item -Path "HKLM:\Software\Microsoft\windows\Windows Error Reporting\" -Name LocalDumps
	}

##### adding the values

$dumpkey = "HKLM:\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps"

New-ItemProperty $dumpkey -Name "DumpFolder" -Value $Folder -PropertyType "ExpandString" -Force
New-ItemProperty $dumpkey -Name "DumpCount" -Value 10 -PropertyType "Dword" -Force
New-ItemProperty $dumpkey -Name "DumpType" -Value 2 -PropertyType "Dword" -Force

This Script checks if the Local Dumps Registry key exists, if it doesnt it creates it and then adds the necessary values. You have probably noticed a potential gotcha with powershell and registry entries. Powershell treats registry values as properties of the Key that they are in as discussed here

The full script can be downloaded from here . To run this script you need to allow unsigned scripts by running the following command from a administrative powershell window.

Set-ExecutionPolicy -ExecutionPolicy Unrestricted

alternatively you can sign the script, which isn’t very difficult but has a number of steps. The Technet Scripting Guy blog has a very good guide here and part 2 here .

I use this script in a couple of ways but mainly to sumplify the task of enabling users/admins with collecting application crash dumps for analysis.

Hope this helps

Shane