functions/Get-AADSTSError.ps1
function Get-AADSTSError{ <# .Synopsis Get-AADSTSError .DESCRIPTION Get-AADSTSError performs a lookup for the specified AADSTS error code and returns error code description and remeidiation information .PARAMETER ErrorCode The AADSTS error code A list of documented error codes can be found here: https://docs.microsoft.com/en-us/azure/active-directory/develop/reference-aadsts-error-codes#aadsts-error-codes .EXAMPLE Get-AADSTSError -ErrorCode AADSTS50076 ErrorCode : 50076 Description : Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access '{resource}'. Remediation: User needs to perform multi-factor authentication. There could be multiple things requiring multi-factor, e.g. Conditional Access policies, per-user enforcement, requested by client, among others. #> [CmdletBinding()] Param ( # The AADSTS Error code to lookup [Parameter(Mandatory=$true)] [string]$ErrorCode ) Begin { $AllProtocols = [System.Net.SecurityProtocolType]'Tls,Tls11,Tls12,Tls13' [System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols $Data = [System.Collections.ArrayList]::new() $Data.PSObject.TypeNames.Insert(0,'AADSTS.ErrorInfo') $uri = "https://login.microsoftonline.com/error" $body = "code=$ErrorCode" } Process { Try{ $request = Invoke-RestMethod -Uri $uri -Body $body -Method Post #credits for the web scraping hint - https://www.pipehow.tech/invoke-webscrape/ $CodePattern = '<table><tr><td>Error Code</td><td>(?<Code>.*)</td></tr><tr><td>Message' # pattern when the result includes Remediation info $MessagePattern1 = '<tr><td>Message</td><td>(?<Message1>.*)</td></tr><tr><td>Remediation' # pattern when there is no remediation info $MessagePattern2 = '<tr><td>Message</td><td>(?<Message2>.*)</td></tr></table></body>' $RemediationPattern = '</td></tr><tr><td>Remediation</td><td>(?<Remediation>.*)</td></tr></table></body>' $Patterns = "$CodePattern","$MessagePattern1","$MessagePattern2","$RemediationPattern" $ResultData = forEach ($patt in $Patterns) { ($request | Select-String $patt -AllMatches).Matches } $OutMessage1 = $null $OutMessage2 = $null $OutRemediation = $null $OutCode = $null foreach ($result in $ResultData) { If (($result.Groups.Where{$_.Name -like 'Code'}).Value -notlike ""){ $OutCode = ($result.Groups.Where{$_.Name -like 'Code'}).Value } If (($result.Groups.Where{$_.Name -like 'Remediation'}).Value -notlike ""){ $OutRemediation = ($result.Groups.Where{$_.Name -like 'Remediation'}).Value } If (($result.Groups.Where{$_.Name -like 'Message1'}).Value -notlike ""){ $OutMessage1 = ($result.Groups.Where{$_.Name -like 'Message1'}).Value } If (($result.Groups.Where{$_.Name -like 'Message2'}).Value -notlike ""){ $OutMessage2 = ($result.Groups.Where{$_.Name -like 'Message2'}).Value } } If($OutCode -like "") { Write-Verbose "Error code: $ErrorCode not found" $object = [PSCustomObject]@{ PSTypeName = "AADSTS.ErrorInfo" ErrorCode = $ErrorCode Description = "not found" Remediation = "" } [void]$Data.Add($object) } Else { Write-Verbose "Error code: $ErrorCode found" $object = [PSCustomObject]@{ PSTypeName = "AADSTS.ErrorInfo" ErrorCode = $OutCode Description = If ($OutRemediation -notlike "") {$OutMessage1} Else {$OutMessage2} Remediation = $OutRemediation } [void]$Data.Add($object) } $Data } Catch{ Write-Error "Error retrieving AADSTS Error information [$_]" } } End {} } |