Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Try Catch not working in Powershell Script

I cannot seem to get this try-catch to work. I am sure it is something simple, but my brain is just too fried at this very moment. PLEASE HELP!

param(
[String[]]$RemoteServicesVMs = ('VmThatThrowsError')
)

function getWinServiceStatus
{

#Get-WmiObject "win32_service" 
    try{

        Get-WmiObject "win32_service" | Where-Object {$_.startname -notlike "NT*" -and $_.startname -notlike "local*" } | Format-Table -property PSComputerName, name, state, status, startname

    }  
    catch{

        wite-host "Failed"

    }

}

$PassWordEnc = convertto-securestring $RemotePassWord -asplaintext -force
$MyCred = New-Object -TypeName System.Management.Automation.PSCredential ArgumentList $RemoteUserName,$PassWordEnc

foreach($RemoteServicesVM in $RemoteServicesVMs){

    Invoke-Command -ComputerName $RemoteServicesVM -Port 5985 -Authentication Negotiate -ScriptBlock ${function:getWinServiceStatus} -Credential $MyCred

}
like image 290
LostInTheSauce Avatar asked Jan 05 '17 02:01

LostInTheSauce


3 Answers

Try/Catch will only 'trigger' on a terminating exception. Most cmdlets in PowerShell, by default, won't throw terminating exceptions. You can set the error action with the -ErrorAction or -ea parameters:

Do-Thing 'Stuff' -ErrorAction Stop

In saying that... I don't think Get-WmiObject will ever generate a terminating error. If it doesn't find something it just won't return anything. In this case you can have an if condition inside your try block, and manually throw:

Try {
    $Obj = Get-WmiObject "win32_service" | Where ...
    if ($null -eq $Obj) {
        throw
    }
}
Catch {
    # Error Handling
}
like image 65
Windos Avatar answered Oct 23 '22 02:10

Windos


1) Your catch statement has a typo. It should be Write-Host

2) Try-catching in Powershell is different to most other programming languages. There are 2 types of errors in Powershell, terminating and non-terminating. By default, a non-terminating error will not trigger your catch handling.

So, if you want to force powershell to catch the error no matter what type it is, you can append -ErrorAction Stop to your InvokeCommand line.

Eg:

Invoke-Command -ComputerName $RemoteServicesVM -Port 5985 -Authentication Negotiate -ScriptBlock ${function:getWinServiceStatus} -Credential $MyCred -ErrorAction Stop

Or (as copied from the link below):

It is also possible to treat all errors as terminating using the ErrorActionPreference variable. You can do this either for the script your are working with or for the whole PowerShell session. To set it in a script, make the first line $ErrorActionPreference = Stop. To set it for the session, type $ErrorActionPreference = Stop at the PowerShell console.

See more here: http://www.vexasoft.com/blogs/powershell/7255220-powershell-tutorial-try-catch-finally-and-error-handling-in-powershell

like image 24
ash Avatar answered Oct 23 '22 01:10

ash


I modified your function param a little bit , but for your answer , I have to say since you are using notlike your get-wmiobject is not returning any error.

If data is not there also , it will show you blank. You can narrow down the issue by putting the output in the variable and displaying the output.

You should use -eq with wildcard to deal with it.

For narrowing down the issue, use this:

$erroractionpreference = stop;
function getWinServiceStatusparam(
[String[]]$RemoteServicesVMs = ('VmThatThrowsError')
)
{

#Get-WmiObject "win32_service" 
    try{

       $a=  Get-WmiObject "win32_service" | Where-Object {$_.startname -notlike "NT*" -and $_.startname -notlike "local*" } | Format-Table -property PSComputerName, name, state, status, startname
       Write-Host $a
    }  
    catch{

        wite-host "Failed"

    }

}

$PassWordEnc = convertto-securestring $RemotePassWord -asplaintext -force
$MyCred = New-Object -TypeName System.Management.Automation.PSCredential ArgumentList $RemoteUserName,$PassWordEnc

foreach($RemoteServicesVM in $RemoteServicesVMs){

    Invoke-Command -ComputerName $RemoteServicesVM -Port 5985 -Authentication Negotiate -ScriptBlock ${function:getWinServiceStatus} -Credential $MyCred

}

Hope it helps.

like image 1
Ranadip Dutta Avatar answered Oct 23 '22 00:10

Ranadip Dutta