如何阻止在PowerShell中将错误传递到`$Error`中的错误?

huangapple go评论99阅读模式
英文:

How to stop casting error from populating `$Error` in Powershell?

问题

以下是代码部分的中文翻译:

  1. function Test-PendingReboot {
  2. try {
  3. $util = [wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities'
  4. $status = $util.DetermineIfRebootPending()
  5. if (($null -ne $status) -and $status.RebootPending) {
  6. return $true
  7. }
  8. } catch {}
  9. return $false
  10. }

这段代码是一个函数的一部分,如您所见,它用于检查系统是否有未完成的重启任务。

只有当重启任务待处理时,才会发生到[wmiclass]的强制类型转换。

这个函数正常工作,但有一个副作用,即在未有重启任务时,强制类型转换错误会被记录在$Error自动变量中。您可以通过以下方式检查:

  1. $error.clear()
  2. Test-PendingReboot
  3. $error

这将打印如下内容(False只是调用的返回值):

  1. False
  2. Cannot convert value "\.\root\ccm\clientsdk:CCM_ClientUtilities" to type "System.Management.ManagementClass". Error: "Invalid parameter "
  3. At C:\_\t.ps1:26 char:89
  4. + re'; return ([wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities') }
  5. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  6. + CategoryInfo : InvalidArgument: (:) [], RuntimeException
  7. + FullyQualifiedErrorId : InvalidCastToWMIClass

我不想让这种情况发生。我希望能完全控制错误处理,因为错误本身也是函数逻辑的一部分(因为它表示未来肯定不会有重启任务)。我希望能像在使用cmdlet时使用-ErrorAction ignore一样控制它。

我尝试使用以下方法:

  1. $ErrorActionPreference = 'ignore'
  2. $util = [wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities'

甚至以下方法(是的,有点疯狂):

  1. $ErrorActionPreference = 'ignore'
  2. $util = Invoke-Command -ScriptBlock { $ErrorActionPreference = 'ignore'; return ([wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities') } -ea Ignore

但都没有起作用...

我开始怀疑,这是否可能?

请注意:这段代码只是一个示例,我的问题是,一般情况下,如何阻止强制类型转换错误进入$Error

英文:

i have the following code:

  1. function Test-PendingReboot {
  2. try {
  3. $util = [wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities'
  4. $status = $util.DetermineIfRebootPending()
  5. if (($null -ne $status) -and $status.RebootPending) {
  6. return $true
  7. }
  8. } catch {}
  9. return $false
  10. }

which is part of a function that, as you can see, checks if a system reboot is pending.

That casting to [wmiclass] is possible only when a reboot is pending.

The function works correctly, but with the side effect of the casting error (when a reboot is not pending) going into the $Error automatic variable. You can check with:

  1. $error.clear()
  2. Test-PendingReboot
  3. $error

This will print the following (False is just the return value of the call):

  1. False
  2. Cannot convert value "\.\root\ccm\clientsdk:CCM_ClientUtilities" to type "System.Management.ManagementClass". Error: "Invalid parameter "
  3. At C:\_\t.ps1:26 char:89
  4. + re'; return ([wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities') }
  5. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  6. + CategoryInfo : InvalidArgument: (:) [], RuntimeException
  7. + FullyQualifiedErrorId : InvalidCastToWMIClass

I don't want that.
I want to have complete control over the error, as the error itself is also part of the logic of the function (because it means that a reboot is certainly not pending).
I want to control it as when using -ErrorAction ignore instead of silentlycontinue with a cmdlet.

I tried using the following:

  1. $ErrorActionPreference = 'ignore'
  2. $util = [wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities'

or even the following (yes that's mad):

  1. $ErrorActionPreference = 'ignore'
  2. $util = Invoke-Command -ScriptBlock { $ErrorActionPreference = 'ignore'; return ([wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities') } -ea Ignore

but nothing works...

I'm starting to doubt, Is it even possible?

PLEASE NOTE: this piece of code is just an example, my question is, in general, how to stop casting error from getting into $Error?


thanks

答案1

得分: 1

你可以考虑重定向(错误)

  1. function Test-PendingReboot {
  2. $util = & { [wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities' } 2>&1
  3. $util.ForEach{
  4. if ($_ -is [System.Management.Automation.ErrorRecord]) {
  5. "Your error: $_"
  6. }
  7. else {
  8. $status = $_.DetermineIfRebootPending()
  9. if ($null -ne $status) { $status.RebootPending }
  10. }
  11. }
  12. }

要完全拦截错误,您可以考虑启动一个昂贵且繁琐的新PowerShell会话:

  1. $Result = PowerShell {
  2. $util = & { [wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities' } 2>&1
  3. $util.ForEach{
  4. if ($_ -is [System.Management.Automation.ErrorRecord]) {
  5. "Your error: $_"
  6. }
  7. else {
  8. $status = $_.DetermineIfRebootPending()
  9. if ($null -ne $status) { $status.RebootPending }
  10. }
  11. }
  12. }
英文:

You might consider to redirect the (error) stream:

  1. function Test-PendingReboot {
  2. $util = & { [wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities' } *>&1
  3. $util.ForEach{
  4. if ($_ -is [System.Management.Automation.ErrorRecord]) {
  5. "Your error: $_"
  6. }
  7. else {
  8. $status = $_.DetermineIfRebootPending()
  9. if ($null -ne $status) { $status.RebootPending }
  10. }
  11. }
  12. }

To completely intercept the error, you might consider to start an expensive and cumbersome new PowerShell session:

  1. $Result = PowerShell {
  2. $util = & { [wmiclass]'\.\root\ccm\clientsdk:CCM_ClientUtilities' } *>&1
  3. $util.ForEach{
  4. if ($_ -is [System.Management.Automation.ErrorRecord]) {
  5. "Your error: $_"
  6. }
  7. else {
  8. $status = $_.DetermineIfRebootPending()
  9. if ($null -ne $status) { $status.RebootPending }
  10. }
  11. }
  12. }

答案2

得分: 0

这个从不例外,只要安装了 SCCM 客户端 (get-package 'configuration manager client'):

  1. # 或者使用 Invoke-WmiMethod
  2. $myargs = @{ namespace = 'root\ccm\clientsdk'
  3. class = 'CCM_ClientUtilities'
  4. name = 'DetermineIfRebootPending' }
  5. Invoke-CimMethod @myargs | select RebootPending
  6. RebootPending
  7. -------------
  8. False
英文:

This never has an exception as long as sccm client is installed (get-package 'configuration manager client'):

  1. # or Invoke-WmiMethod
  2. $myargs = @{ namespace = 'root\ccm\clientsdk'
  3. class = 'CCM_ClientUtilities'
  4. name = 'DetermineIfRebootPending' }
  5. Invoke-CimMethod @myargs | select RebootPending
  6. RebootPending
  7. -------------
  8. False

huangapple
  • 本文由 发表于 2023年3月31日 16:40:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75896501.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定