1

The desired result from this script is to find out the PowerShell version on a list of hosts. I would like to handle the exception when the remote machine is down or does not have remoting enabled. However, the catch does not appear to be entered. Just the standard red flaming error message from PowerShell appears.

What do I need to do to catch the exception?

X:\Scripts\PSAutomation> Get-Content .\get-versions.ps1 server_list = @( 'CAPPY' ) $server_list | ForEach-Object { Try { Invoke-Command -ComputerName $_ {$PSVersionTable.PSVersion} } Catch { Write-Host "Failed to connect to $_" } } X:\Scripts\PSAutomation> .\get-versions.ps1 [CAPPY] Connecting to remote server CAPPY failed with the following error message : WinRM cannot process the request. The following error occurred while using Kerberos authentication: Cannot find the computer CAPPY. Verify that the computer exists on the network and that the name provided is spelled correctly. For more information, see the about_Remote_Troubleshooting Help topic. + CategoryInfo : OpenError: (CAPPY:String) [], PSRemotingTransportException + FullyQualifiedErrorId : NetworkPathNotFound,PSSessionStateBroken 

2 Answers 2

2

Just set the ErrorAction for that call to stop:

Invoke-Command -ComputerName "sdf" {$PSVersionTable.PSVersion} -ErrorAction Stop 
Sign up to request clarification or add additional context in comments.

2 Comments

Using -ErrorAction causes the red message to appear in the normal console text color. However, nothing about Write-Host ever appears.
I think you are wrong, the message should start with Failed to connect....Thats because $_ in your catch block represents the error instead of the current foreach-object pipeline variable. You probably have to introduce a variable before you try, like: $current = $_ and use $current instead of $_ in your Write-Host
1

I actually encountered a very similar situation in which I had a long list of PCs, but some were offline, and some I didn't have access to. In addition, there were some I did have access to, that would encounter a non-terminating error that beings with 'Failed to Initialize Drives'. This is why I couldn't use try/catch or something that would stop for any error. I might've been able to use targeted catch's, but I used the -ErrorVariable parameter from Invoke-Command to save whatever error each Invoke-Command encountered to a variable (I called mine $stoperror). Here is a simplified version of the snippet from my code:

$computers = get-content $(Read-Host "enter path list .txt file") foreach ($computer in $computers) { Write-Host "Pinging $computer..." $ping_result = Test-Connection $computer -Count 1 -ErrorAction SilentlyContinue if ($ping_result) { $query_result = invoke-command -computername $computer -errorvariable stoperror -scriptblock { Write-Host "Accessed $env:COMPUTERNAME" -ForegroundColor Green } # this is where you can check the $stoperror variable, for whatever errors you're looking for if (($stoperror -like "*Access is denied*") -or ($stoperror -like "*WinRM cannot complete the operation*")) { write-host $stoperror Write-Host "$computer got an access denied or winrm operation error!" -ForegroundColor Yellow } } else { Write-Host "$computer is down!" -ForegroundColor Red } } 

The tricky part is when you use that -errorvariable parameter and define the variable, you don't have to use a $.

Also, you may be able to do a ping test right off the bat to test for connectivity. It may help save time down the line, the Invoke-Command errors always take longer than a ping for me.

Please let me know if this helps.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.