psTroubleshootWinRM.psm1
function Convert-WinrmError { <# .SYNOPSIS Function to help troubleshoot Powershell Remoting failures. .DESCRIPTION I needed a function that would take the myriad of random returns that psRemoting gives as errors and consolidate them into useful information in a standardized format. This function aims to do that. .PARAMETER server The name of the server to troubleshoot. This parameter is mandatory. .PARAMETER thrown_error The error object thrown by the failed remoting command. This parameter is mandatory. .PARAMETER test_ping A switch to determine if a ping test should be performed. It is not mandatory and defaults to false. .PARAMETER test_dns A switch to determine if a DNS resolution test should be performed. It is not mandatory and defaults to false. .INPUTS None. .OUTPUTS Returns a psObject with the following properties: "server" = The name of the server passed to the function. "full_error" = The entire exception thrown by powershell. "ping_result" = A result of a Test-Connection command. "dns_result" = The result of a Resolve-DNSName command. "short_error" = A friendly short error that hopefully gives most of whats relevant from the full exception. .EXAMPLE This example tries to run a simple invoke-command against a machine and if it fails it calls the fucntion with full ping and DNS checking enabled. Try{ $result = Invoke-Command -ComputerName $server -Credential $credential -ScriptBlock{ $env:computername } -ErrorAction Stop Write-Host "`t This Server did not error. Hostname is $env:computername" } Catch { $Result = Convert-WinrmError -server $server.name -thrown_error $_ -test_ping $true -test_dns $true $result } .EXAMPLE This example tries to run a simple invoke-command against a machine and if it fails it calls the fucntion with no ping or dns checking. Try{ $result = Invoke-Command -ComputerName $server -Credential $credential -ScriptBlock{ $env:computername } -ErrorAction Stop Write-Host "`t This Server did not error. Hostname is $env:computername" } Catch { $Result = Convert-WinrmError -server $server.name -thrown_error $_ $result } #> [CmdletBinding()] param ( [Parameter(Mandatory=$true, HelpMessage="This is the server to test against.")] [String]$server, [Parameter(Mandatory=$true, HelpMessage='This is the full error normally a $_ in your catch block.')] [System.Object]$thrown_error, [Parameter(Mandatory=$false, HelpMessage="This is a bool to decide if you want to run a ping test.")] [bool]$test_ping=$false, [Parameter(Mandatory=$false, HelpMessage="This is a bool to decide if you want to run a DNS test.")] [bool]$test_dns=$false ) begin{ # Attempt to perform a ping test if requested. Try{ if($test_ping){ $ping_result = Test-Connection -ComputerName $server -quiet -ErrorAction Stop } else{ $ping_result = 'Skipped' } } Catch{ $ping_result = "ERROR: $($_.exception.message)" } # Attempt to perform a DNS resolution test if requested. Try{ if($test_dns){ $dns = Resolve-DnsName -Name $server -ErrorAction Stop $dns_result = $dns.name + ':' + $dns.ipaddress } else{ $dns_result = 'Skipped' } } Catch{ $pattern = "(?!.*:)\s*(.*)" if ([string]$_.exception -match $pattern) { Write-debug 'Worked' $dns_result = $matches[1].Trim() } else{ Write-debug 'Didnt Work' $dns_result = "$($_.exception.message)" } } # Create a new object to hold the results of the troubleshooting. $return_obj = New-Object -typename psobject -Property @{ "server" = $server "full_error" = $thrown_error.exception "ping_result" = $ping_result "dns_result" = $dns_result "short_error" = 'UNKNOWN' } } process{ # Debugging output of the exception. Write-debug "Exception is: $($thrown_error.exception)" # Analyze the exception message to set a more user-friendly error message. Switch -wildcard ($thrown_error.exception){ '*the server name cannot be resolved*' { Write-Debug "`tMatched error successfully: the server name cannot be resolved" $return_obj.short_error = 'The WinRM client cannot process the request because the server name cannot be resolved' } '*The following error with errorcode 0x80090322 occurred while using Kerberos authentication*' { Write-Debug "`tMatched error successfully: the server name cannot be resolved" $return_obj.short_error = 'The following error with errorcode 0x80090322 occurred while using Kerberos authentication' } '*cannot determine the content type of the HTTP response*'{ Write-Debug "`tCannot determine the content type of the HTTP response" $return_obj.short_error = 'Bad HTTP response. The content type is absent or invalid' } '*If the destination is the WinRM service, run the following command on the destination*'{ Write-Debug "`tIf the destination is the WinRM service, run the following command on the destination'" $return_obj.short_error = 'Generic WINRM Issue. This is probably the winrm config, the service, or the proxy.' } '*WinRM cannot complete the operation*'{ Write-Debug "`tMatched error successfully: WinRM cannot complete the operation" $return_obj.short_error = 'WinRM cannot complete the operation.' } '*Access is denied*'{ Write-Debug "`tMatched error successfully: WinRM cannot complete the operation" $return_obj.short_error = 'Access is denied.' } 'default' { Write-Debug "`tUnable to match error" $_ | select -Property * } } } end{ # Return the results object to the caller. return $return_obj } } |