尝试Catch在Powershell脚本中不起作用

Los*_*uce 2 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

}
Run Code Online (Sandbox Code Playgroud)

小智 11

1) 你的 catch 语句有一个错字。它应该是Write-Host

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

所以,如果你想强制powershell 捕捉错误,不管它是什么类型,你可以附加-ErrorAction Stop到你的InvokeCommand行。

例如:

Invoke-Command -ComputerName $RemoteServicesVM -Port 5985 -Authentication Negotiate -ScriptBlock ${function:getWinServiceStatus} -Credential $MyCred -ErrorAction Stop
Run Code Online (Sandbox Code Playgroud)

或者(从下面的链接复制):

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

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


Win*_*dos 5

尝试/捕获只会在终止异常时“触发”。默认情况下,PowerShell中的大多数cmdlet都不会引发终止异常。您可以使用-ErrorAction-ea参数设置错误操作:

Do-Thing 'Stuff' -ErrorAction Stop
Run Code Online (Sandbox Code Playgroud)

这么说...我认为Get-WmiObject永远不会产生终止错误。如果找不到,就不会返回任何东西。在这种情况下,您可以在try块中放入一个if条件,然后手动抛出:

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


Ran*_*tta 1

我稍微修改了你的函数参数,但是对于你的回答,我不得不说,因为你使用的是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

}
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你。