Created
December 7, 2025 15:00
-
-
Save secdev02/e0ec77e9a5ad80ddc2f6b8a1821cccf3 to your computer and use it in GitHub Desktop.
WerFault Shenanigans
This file contains hidden or 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
| <# | |
| .SYNOPSIS | |
| Configure Windows Error Reporting to use an internal corporate server, | |
| trigger a test crash, and review reports. | |
| .DESCRIPTION | |
| This script provides functions to: | |
| - Set WER corporate server URL and settings | |
| - Trigger a basic crash for testing | |
| - Review pending and archived WER reports | |
| .PARAMETER ServerUrl | |
| The URL of your internal WER server | |
| .PARAMETER UseSSL | |
| Whether to use SSL (default: true) | |
| .PARAMETER Port | |
| Port number for the WER server (default: 443) | |
| .EXAMPLE | |
| .\Configure-WER.ps1 -ServerUrl "https://buildlogs.company.com/wer" | |
| #> | |
| param( | |
| [Parameter(Mandatory=$false)] | |
| [string]$ServerUrl, | |
| [Parameter(Mandatory=$false)] | |
| [bool]$UseSSL = $true, | |
| [Parameter(Mandatory=$false)] | |
| [int]$Port = 443 | |
| ) | |
| #Requires -RunAsAdministrator | |
| # Registry path for WER policies | |
| $WerPolicyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" | |
| $WerSettingsPath = "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting" | |
| function Set-WerCorporateServer { | |
| param( | |
| [Parameter(Mandatory=$true)] | |
| [string]$Url, | |
| [Parameter(Mandatory=$false)] | |
| [bool]$Ssl = $true, | |
| [Parameter(Mandatory=$false)] | |
| [int]$PortNumber = 443 | |
| ) | |
| Write-Host "Configuring WER Corporate Server..." -ForegroundColor Cyan | |
| # Create the policy key if it doesn't exist | |
| if (-not (Test-Path $WerPolicyPath)) { | |
| New-Item -Path $WerPolicyPath -Force | Out-Null | |
| Write-Host " Created WER policy registry key" -ForegroundColor Green | |
| } | |
| # Set the corporate server URL | |
| Set-ItemProperty -Path $WerPolicyPath -Name "CorporateWerServer" -Value $Url -Type String | |
| Write-Host " Set CorporateWerServer: $Url" -ForegroundColor Green | |
| # Set SSL preference | |
| $sslValue = if ($Ssl) { 1 } else { 0 } | |
| Set-ItemProperty -Path $WerPolicyPath -Name "CorporateWerUseSSL" -Value $sslValue -Type DWord | |
| Write-Host " Set CorporateWerUseSSL: $sslValue" -ForegroundColor Green | |
| # Set port number | |
| Set-ItemProperty -Path $WerPolicyPath -Name "CorporateWerPortNumber" -Value $PortNumber -Type DWord | |
| Write-Host " Set CorporateWerPortNumber: $PortNumber" -ForegroundColor Green | |
| # Enable corporate WER mode | |
| Set-ItemProperty -Path $WerPolicyPath -Name "CorporateWerUseAuthentication" -Value 0 -Type DWord | |
| Write-Host "`nWER Corporate Server configured successfully!" -ForegroundColor Green | |
| } | |
| function Get-WerConfiguration { | |
| Write-Host "`n=== Current WER Configuration ===" -ForegroundColor Cyan | |
| # Check policy settings | |
| if (Test-Path $WerPolicyPath) { | |
| Write-Host "`nPolicy Settings ($WerPolicyPath):" -ForegroundColor Yellow | |
| Get-ItemProperty -Path $WerPolicyPath | Format-List | |
| } | |
| else { | |
| Write-Host "`nNo WER policy settings found." -ForegroundColor Yellow | |
| } | |
| # Check general WER settings | |
| if (Test-Path $WerSettingsPath) { | |
| Write-Host "`nGeneral Settings ($WerSettingsPath):" -ForegroundColor Yellow | |
| Get-ItemProperty -Path $WerSettingsPath | Format-List | |
| } | |
| } | |
| function Invoke-TestCrash { | |
| Write-Host "`n=== Triggering Test Crash ===" -ForegroundColor Cyan | |
| # Method 1: Use WerFault directly to create a test report | |
| $testAppPath = [System.IO.Path]::Combine($env:TEMP, "WerTestApp.exe") | |
| # Create a simple C# app that crashes | |
| $crashCode = @" | |
| using System; | |
| class Program { | |
| static void Main() { | |
| Console.WriteLine("WER Test Application - About to crash..."); | |
| throw new InvalidOperationException("Test crash for WER reporting"); | |
| } | |
| } | |
| "@ | |
| Write-Host "Creating test crash application..." -ForegroundColor Yellow | |
| # Alternative: Use PowerShell to trigger WerFault with a test report | |
| Write-Host "Triggering WER report via WerFault..." -ForegroundColor Yellow | |
| # Create a problem report using ReportFault API simulation | |
| $reportPath = Join-Path $env:TEMP "WerTestReport" | |
| if (-not (Test-Path $reportPath)) { | |
| New-Item -Path $reportPath -ItemType Directory -Force | Out-Null | |
| } | |
| # Create a minimal WER report file | |
| $reportContent = @" | |
| Version=1 | |
| EventType=TestCrash | |
| EventTime={0} | |
| ReportType=2 | |
| Consent=1 | |
| ReportIdentifier={1} | |
| AppName=WerTestApplication | |
| AppPath=C:\Windows\System32\cmd.exe | |
| ModName=TestModule | |
| ModVersion=1.0.0.0 | |
| Offset=0x00000000 | |
| "@ -f (Get-Date -Format "yyyyMMddHHmmss"), [guid]::NewGuid().ToString() | |
| $reportFile = Join-Path $reportPath "Report.wer" | |
| $reportContent | Out-File -FilePath $reportFile -Encoding ASCII | |
| Write-Host " Created test report: $reportFile" -ForegroundColor Green | |
| # Trigger wermgr to process reports | |
| Write-Host "`nTriggering WER upload process..." -ForegroundColor Yellow | |
| # Queue the reporting task | |
| try { | |
| Start-Process -FilePath "wermgr.exe" -ArgumentList "-upload" -NoNewWindow -Wait | |
| Write-Host " WER upload triggered successfully" -ForegroundColor Green | |
| } | |
| catch { | |
| Write-Host " Error triggering WER: $_" -ForegroundColor Red | |
| } | |
| # Alternative: Trigger via scheduled task | |
| Write-Host "`nTriggering QueueReporting scheduled task..." -ForegroundColor Yellow | |
| try { | |
| $task = Get-ScheduledTask -TaskName "QueueReporting" -TaskPath "\Microsoft\Windows\Windows Error Reporting\" -ErrorAction SilentlyContinue | |
| if ($task) { | |
| Start-ScheduledTask -TaskName "QueueReporting" -TaskPath "\Microsoft\Windows\Windows Error Reporting\" | |
| Write-Host " QueueReporting task started" -ForegroundColor Green | |
| } | |
| else { | |
| Write-Host " QueueReporting task not found" -ForegroundColor Yellow | |
| } | |
| } | |
| catch { | |
| Write-Host " Could not trigger scheduled task: $_" -ForegroundColor Red | |
| } | |
| } | |
| function Get-WerReports { | |
| Write-Host "`n=== WER Reports ===" -ForegroundColor Cyan | |
| # Pending reports location | |
| $pendingPath = Join-Path $env:ProgramData "Microsoft\Windows\WER\ReportQueue" | |
| # Archived reports location | |
| $archivePath = Join-Path $env:ProgramData "Microsoft\Windows\WER\ReportArchive" | |
| # User reports | |
| $userPendingPath = Join-Path $env:LOCALAPPDATA "Microsoft\Windows\WER\ReportQueue" | |
| $userArchivePath = Join-Path $env:LOCALAPPDATA "Microsoft\Windows\WER\ReportArchive" | |
| Write-Host "`n--- Pending Reports (System) ---" -ForegroundColor Yellow | |
| if (Test-Path $pendingPath) { | |
| $pending = Get-ChildItem -Path $pendingPath -Directory -ErrorAction SilentlyContinue | |
| if ($pending) { | |
| foreach ($report in $pending) { | |
| Write-Host " Report: $($report.Name)" -ForegroundColor White | |
| $werFile = Get-ChildItem -Path $report.FullName -Filter "Report.wer" -ErrorAction SilentlyContinue | |
| if ($werFile) { | |
| Write-Host " Content:" -ForegroundColor Gray | |
| Get-Content $werFile.FullName | Select-Object -First 15 | ForEach-Object { | |
| Write-Host " $_" -ForegroundColor Gray | |
| } | |
| } | |
| } | |
| } | |
| else { | |
| Write-Host " No pending reports" -ForegroundColor Gray | |
| } | |
| } | |
| else { | |
| Write-Host " Report queue path does not exist" -ForegroundColor Gray | |
| } | |
| Write-Host "`n--- Archived Reports (System) ---" -ForegroundColor Yellow | |
| if (Test-Path $archivePath) { | |
| $archived = Get-ChildItem -Path $archivePath -Directory -ErrorAction SilentlyContinue | Select-Object -Last 5 | |
| if ($archived) { | |
| foreach ($report in $archived) { | |
| Write-Host " Report: $($report.Name)" -ForegroundColor White | |
| Write-Host " Created: $($report.CreationTime)" -ForegroundColor Gray | |
| } | |
| } | |
| else { | |
| Write-Host " No archived reports" -ForegroundColor Gray | |
| } | |
| } | |
| else { | |
| Write-Host " Archive path does not exist" -ForegroundColor Gray | |
| } | |
| Write-Host "`n--- Pending Reports (User) ---" -ForegroundColor Yellow | |
| if (Test-Path $userPendingPath) { | |
| $userPending = Get-ChildItem -Path $userPendingPath -Directory -ErrorAction SilentlyContinue | |
| if ($userPending) { | |
| foreach ($report in $userPending) { | |
| Write-Host " Report: $($report.Name)" -ForegroundColor White | |
| } | |
| } | |
| else { | |
| Write-Host " No pending user reports" -ForegroundColor Gray | |
| } | |
| } | |
| else { | |
| Write-Host " User report queue path does not exist" -ForegroundColor Gray | |
| } | |
| # Also check Windows Event Log for WER events | |
| Write-Host "`n--- Recent WER Events (Event Log) ---" -ForegroundColor Yellow | |
| try { | |
| $events = Get-WinEvent -LogName "Application" -FilterXPath "*[System[Provider[@Name='Windows Error Reporting']]]" -MaxEvents 5 -ErrorAction SilentlyContinue | |
| if ($events) { | |
| foreach ($event in $events) { | |
| Write-Host " [$($event.TimeCreated)] $($event.Message.Substring(0, [Math]::Min(100, $event.Message.Length)))..." -ForegroundColor Gray | |
| } | |
| } | |
| else { | |
| Write-Host " No recent WER events found" -ForegroundColor Gray | |
| } | |
| } | |
| catch { | |
| Write-Host " Could not query event log: $_" -ForegroundColor Red | |
| } | |
| } | |
| function Remove-WerCorporateServer { | |
| Write-Host "`nRemoving WER Corporate Server configuration..." -ForegroundColor Cyan | |
| if (Test-Path $WerPolicyPath) { | |
| Remove-ItemProperty -Path $WerPolicyPath -Name "CorporateWerServer" -ErrorAction SilentlyContinue | |
| Remove-ItemProperty -Path $WerPolicyPath -Name "CorporateWerUseSSL" -ErrorAction SilentlyContinue | |
| Remove-ItemProperty -Path $WerPolicyPath -Name "CorporateWerPortNumber" -ErrorAction SilentlyContinue | |
| Remove-ItemProperty -Path $WerPolicyPath -Name "CorporateWerUseAuthentication" -ErrorAction SilentlyContinue | |
| Write-Host " WER corporate settings removed" -ForegroundColor Green | |
| } | |
| else { | |
| Write-Host " No WER policy settings to remove" -ForegroundColor Yellow | |
| } | |
| } | |
| # Main menu | |
| function Show-Menu { | |
| Write-Host "`n========================================" -ForegroundColor Cyan | |
| Write-Host " WER Configuration Tool" -ForegroundColor White | |
| Write-Host "========================================" -ForegroundColor Cyan | |
| Write-Host "1. Set Corporate WER Server" | |
| Write-Host "2. View Current Configuration" | |
| Write-Host "3. Trigger Test Crash/Report" | |
| Write-Host "4. View WER Reports" | |
| Write-Host "5. Remove Corporate WER Settings" | |
| Write-Host "6. Exit" | |
| Write-Host "" | |
| } | |
| # If ServerUrl was provided as parameter, configure and exit | |
| if ($ServerUrl) { | |
| Set-WerCorporateServer -Url $ServerUrl -Ssl $UseSSL -PortNumber $Port | |
| Get-WerConfiguration | |
| exit | |
| } | |
| # Interactive mode | |
| do { | |
| Show-Menu | |
| $choice = Read-Host "Select an option (1-6)" | |
| switch ($choice) { | |
| "1" { | |
| $url = Read-Host "Enter Corporate WER Server URL" | |
| $sslChoice = Read-Host "Use SSL? (Y/n)" | |
| $ssl = $sslChoice -ne "n" | |
| $portInput = Read-Host "Port number (default 443)" | |
| $port = if ($portInput) { [int]$portInput } else { 443 } | |
| Set-WerCorporateServer -Url $url -Ssl $ssl -PortNumber $port | |
| } | |
| "2" { | |
| Get-WerConfiguration | |
| } | |
| "3" { | |
| Invoke-TestCrash | |
| } | |
| "4" { | |
| Get-WerReports | |
| } | |
| "5" { | |
| Remove-WerCorporateServer | |
| } | |
| "6" { | |
| Write-Host "Exiting..." -ForegroundColor Cyan | |
| } | |
| default { | |
| Write-Host "Invalid option. Please select 1-6." -ForegroundColor Red | |
| } | |
| } | |
| } while ($choice -ne "6") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment