Private/Kinds/CrashDump.ps1
|
# The CrashDump Kind: the files Windows wrote down when it stopped. # # The Stability Kind counts blue screens from the event log. This finds what they left # behind, which is the thing a second-level Technician can actually analyse: a minidump # names the faulting driver, and the event does not. $script:CrashDumpNeedsAdmin = $true function Get-CrashDumpData { [CmdletBinding()] [OutputType([psobject])] param([hashtable]$Parameters = @{}) $days = [int](Get-Parameter $Parameters 'Days' 30) $since = (Get-Date).AddDays(-$days) $folder = Join-Path $env:SystemRoot 'Minidump' $denied = $false $dumps = @() if (Test-Path -LiteralPath $folder) { $errors = $null $dumps = @(Get-ChildItem -LiteralPath $folder -Filter *.dmp -File -ErrorAction SilentlyContinue -ErrorVariable errors | Where-Object { $_.LastWriteTime -ge $since } | ForEach-Object { [pscustomobject]@{ Name = $_.Name; LastWriteTime = $_.LastWriteTime; SizeKB = [math]::Round($_.Length / 1KB) } }) # A folder that exists and will not open is not a machine with no crash dumps. if ($errors -and @($errors | Where-Object { Test-AccessDenied -ErrorRecord $_ }).Count) { $denied = $true } } $full = Get-Item -LiteralPath (Join-Path $env:SystemRoot 'MEMORY.DMP') -ErrorAction SilentlyContinue [pscustomobject]@{ PSTypeName = 'Gutcheck.Data.CrashDump' Days = $days Folder = $folder FolderUnreadable = $denied Minidumps = $dumps FullDumpWrittenAt = $(if ($full -and $full.LastWriteTime -ge $since) { $full.LastWriteTime } else { $null }) } } function ConvertTo-CrashDumpFinding { [CmdletBinding()] [OutputType([psobject])] param( [AllowNull()]$Data, [hashtable]$Parameters = @{} ) $warnAbove = Get-Parameter $Parameters 'MinidumpWarnAbove' 0 $failAbove = Get-Parameter $Parameters 'MinidumpFailAbove' ([double]::MaxValue) $days = Get-DataProperty $Data 'Days' if (Get-DataProperty $Data 'FolderUnreadable') { New-Finding -Category Stability -Check (Get-Text 'Check.CrashDump.Minidumps') -Severity INFO ` -Value (Get-Text 'Value.CrashDump.FolderNeedsAdmin') ` -Hint (Get-Text 'Hint.CrashDump.RerunAndAllowTheAdmin') } else { $dumps = Get-DataCollection $Data 'Minidumps' New-Finding -Category Stability -Check (Get-Text 'Check.CrashDump.Minidumps') ` -Severity (Get-Severity $dumps.Count $warnAbove $failAbove) ` -Value $(if ($dumps.Count) { (Get-Text 'Value.CrashDump.CountInPeriod') -f $dumps.Count, (Get-DataProperty $Data 'Folder'), $days } else { 'none in period' }) ` -Hint (Get-Text 'Hint.CrashDump.AnalyseWithWinDbgAnalyzeV') } $full = Get-DataProperty $Data 'FullDumpWrittenAt' if ($full) { New-Finding -Category Stability -Check (Get-Text 'Check.CrashDump.FullMemoryDump') -Severity WARN ` -Value ('{0:yyyy-MM-dd HH:mm}' -f [datetime]$full) ` -Hint (Get-Text 'Hint.CrashDump.WindowsWroteACompleteMemory') } } function ConvertTo-CrashDumpSection { [CmdletBinding()] [OutputType([psobject])] param([AllowNull()]$Data) New-Section -Title (Get-Text 'Title.CrashDump.Minidumps') -Row @( (Get-DataCollection $Data 'Minidumps') | Sort-Object LastWriteTime -Descending | Select-Object Name, LastWriteTime, SizeKB ) } |