I needed a way to resolve Windows Update error codes for a solution I am working on and I remembered there are a couple of web pages on the Microsoft Docs site that document Windows Update error codes, eg this and this.
So I decided to create a PowerShell function that scrapes these pages and pulls all the error codes and descriptions into a table. This allows me to dynamically resolves a particular error code to a friendly description, or simply output the entire table as a reference.
You can use the function like so:
Resolve a single error code
Get-WUErrorCode -ErrorCode 0x800f0825
# or
"0x800f0825" | Get-WUErrorCode

Resolve multiple error codes:
Get-WUErrorCode "0x8024A000","0x8024D00B"
# or
"0x8024A000","0x8024D00B" | Get-WUErrorCode

Output the entire list of error codes and send to GridView:
Get-WUErrorCode -AsTable | Out-GridView

Here’s the code:
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
Function Get-WUErrorCode { | |
[CmdletBinding()] | |
Param | |
( | |
[Parameter(Mandatory=$true,ParameterSetName='Parameter Set 1',ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0)] | |
[string[]] | |
$ErrorCode, | |
[Parameter(Mandatory=$true,ParameterSetName='Parameter Set 2',Position=1)] | |
[switch] | |
$AsTable | |
) | |
Begin | |
{ | |
# create a table | |
$ErrorCodeTable = [System.Data.DataTable]::new() | |
$ErrorCodeTable.Columns.AddRange(@("ErrorCode","Description","Message","Category")) | |
################################ | |
## PROCESS THE FIRST WEB PAGE ## | |
################################ | |
# scrape the web page | |
$ProgressPreference = 'SilentlyContinue' | |
$URL = "https://docs.microsoft.com/en-us/windows/deployment/update/windows-update-error-reference" | |
$tempFile = [System.IO.Path]::GetTempFileName() | |
Invoke-WebRequest –URI $URL –OutFile $tempFile –UseBasicParsing | |
$htmlarray = Get-Content $tempFile –ReadCount 0 | |
[System.IO.File]::Delete($tempFile) | |
# get the headers and data cells | |
$headers = $htmlarray | Select-String –SimpleMatch "<h2 " | Where {$_ -match "error" -or $_ -match "success"} | |
$dataCells = $htmlarray | Select-String –SimpleMatch "<td>" | |
# process each header | |
$i = 1 | |
do { | |
foreach ($header in $headers) | |
{ | |
$lineNumber = $header.LineNumber | |
$nextHeader = $headers[$i] | |
If ($null -ne $nextHeader) | |
{ | |
$nextHeaderLineNumber = $nextHeader.LineNumber | |
$cells = $dataCells | Where {$_.LineNumber -gt $lineNumber -and $_.LineNumber -lt $nextHeaderLineNumber} | |
} | |
else | |
{ | |
$cells = $dataCells | Where {$_.LineNumber -gt $lineNumber} | |
} | |
# process each cell | |
$totalCells = $cells.Count | |
$t = 0 | |
do { | |
$Row = $ErrorCodeTable.NewRow() | |
"ErrorCode","Message","Description" | foreach { | |
$Row["$_"] = "$($cells[$t].ToString().Replace('<code>','').Replace('</code>','').Split('>').Split('<')[2])" | |
$t ++ | |
} | |
$Row["Category"] = "$($header.ToString().Split('>').Split('<')[2])" | |
[void]$ErrorCodeTable.Rows.Add($Row) | |
} | |
until ($t -ge ($totalCells -1)) | |
$i ++ | |
} | |
} | |
until ($i -ge $headers.count) | |
################################# | |
## PROCESS THE SECOND WEB PAGE ## | |
################################# | |
# scrape the web page | |
$URL = "https://docs.microsoft.com/en-us/windows/deployment/update/windows-update-errors" | |
$tempFile = [System.IO.Path]::GetTempFileName() | |
Invoke-WebRequest –URI $URL –OutFile $tempFile –UseBasicParsing | |
$htmlarray = Get-Content $tempFile –ReadCount 0 | |
[System.IO.File]::Delete($tempFile) | |
# get the headers and data cells | |
$headers = $htmlarray | Select-String –SimpleMatch "<h2 id=""0x" | |
$dataCells = $htmlarray | Select-String –SimpleMatch "<td>" | |
# process each header | |
$i = 1 | |
do { | |
foreach ($header in $headers) | |
{ | |
$lineNumber = $header.LineNumber | |
$nextHeader = $headers[$i] | |
If ($null -ne $nextHeader) | |
{ | |
$nextHeaderLineNumber = $nextHeader.LineNumber | |
$cells = $dataCells | Where {$_.LineNumber -gt $lineNumber -and $_.LineNumber -lt $nextHeaderLineNumber} | |
} | |
else | |
{ | |
$cells = $dataCells | Where {$_.LineNumber -gt $lineNumber} | |
} | |
# process each cell | |
$totalCells = $cells.Count | |
$t = 0 | |
do { | |
$WebErrorCode = $header.ToString().Split('>').Split('<')[2].Replace('or ','').Replace(' ',' ').Split() | |
If ($WebErrorCode.GetType().BaseType.Name -eq "Array") | |
{ | |
foreach ($Code in $WebErrorCode) | |
{ | |
$Row = $ErrorCodeTable.NewRow() | |
$Row["ErrorCode"] = $Code.Trim() | |
"Message","Description" | foreach { | |
$Row["$_"] = "$($cells[$t].ToString().Split('>').Split('<')[2])" | |
$t ++ | |
} | |
$Row["Category"] = "Common" | |
[void]$ErrorCodeTable.Rows.Add($Row) | |
1..2 | foreach {$t —} | |
} | |
1..2 | foreach {$t ++} | |
} | |
else { | |
$Row = $ErrorCodeTable.NewRow() | |
$Row["ErrorCode"] = $ErrorCode | |
"Message","Description" | foreach { | |
$Row["$_"] = "$($cells[$t].ToString().Split('>').Split('<')[2])" | |
$t ++ | |
} | |
$Row["Category"] = "Common" | |
[void]$ErrorCodeTable.Rows.Add($Row) | |
} | |
$t ++ | |
} | |
until ($t -ge ($totalCells -1)) | |
$i ++ | |
} | |
} | |
until ($i -ge $headers.count) | |
$outputArray = @() | |
} | |
Process | |
{ | |
if ($ErrorCode) | |
{ | |
$ErrorCode | foreach { | |
$outputArray += ($ErrorCodeTable.Select("ErrorCode='$_'") | Select –First 1) | |
} | |
} | |
} | |
End | |
{ | |
if ($ErrorCode) | |
{ | |
return $outputArray | |
} | |
if ($AsTable) | |
{ | |
return $ErrorCodeTable | |
} | |
} | |
} |