尝试Catch不在Powershell脚本中工作

时间:2017-01-05 02:42:02

标签: powershell try-catch

我似乎无法让这个try-catch工作。我相信这很简单,但是我的大脑在这个时刻太过油腻了。请帮助!

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

}

4 个答案:

答案 0 :(得分:4)

尝试/抓取只会触发'在终止例外。默认情况下,PowerShell中的大多数cmdlet不会抛出终止异常。您可以使用-ErrorAction或-ea参数设置错误操作:

Do-Thing 'Stuff' -ErrorAction Stop

在说...我不认为Get-WmiObject会产生终止错误。如果它找不到任何东西,它就会赢回任何东西。在这种情况下,您可以在try块中包含if条件,并手动抛出:

Try {
    $Obj = Get-WmiObject "win32_service" | Where ...
    if ($Obj) {
        throw
    }
}
Catch {
    # Error Handling
}

答案 1 :(得分:1)

1)你的捕获声明有拼写错误。它应该是c

2)Powershell中的尝试捕获与大多数其他编程语言不同。 Powershell中有两种类型的错误,终止和非终止。默认情况下,非终止错误会触发您的catch处理。

因此,如果您想强制 powershell捕获错误,无论它是什么类型,您都可以将Write-Host追加到-ErrorAction Stop行。

例如:

InvokeCommand

或(从以下链接复制):

  

也可以使用ErrorActionPreference变量将所有错误视为终止。您可以为正在使用的脚本或整个PowerShell会话执行此操作。要在脚本中设置它,请将第一行设为$ ErrorActionPreference = Stop。要为会话设置它,请在PowerShell控制台中键入$ ErrorActionPreference = Stop。

在此处查看更多内容:http://www.vexasoft.com/blogs/powershell/7255220-powershell-tutorial-try-catch-finally-and-error-handling-in-powershell

答案 2 :(得分:0)

我稍微修改了你的函数参数,但是对于你的答案,我必须说因为你正在使用 notlike 你的 get-wmiobject 没有返回任何错误。

如果数据不存在,则会显示空白。您可以通过将输出放在变量中并显示输出来缩小问题范围。

您应该使用 -eq 和通配符来处理它。

要缩小问题范围,请使用:

$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

}

希望它有所帮助。

答案 3 :(得分:0)

您可以检查上一条命令是否成功运行,而不是try / catch,然后对其进行处理:

Get-WmiObject "win32_service"
if(!$?){
  if($error[0].exception.message -match "invalid class"){ write-warning "The class doesn't exist"}
  else{ throw $error[0] }
}