1. ホーム
  2. powershell

Try/catchは効果がないようだ

2023-10-10 17:46:48

質問

私はpowershellの初心者で、try/catch文によるエラー処理を追加しようとしていますが、彼らは実際にエラーをキャッチしていないようです。これはpowershell v2 CP3です。

$objComputer = $objResult.Properties;
$strComputerName = $objComputer.name
write-host "Checking machine: " $strComputerName

try
{
    $colItems = get-wmiobject -class "Win32_PhysicalMemory" -namespace "root\CIMV2" -computername $strComputerName -Credential $credentials
    foreach ($objItem in $colItems) 
    {
        write-host "Bank Label: " $objItem.BankLabel
        write-host "Capacity: " ($objItem.Capacity / 1024 / 1024)
        write-host "Caption: " $objItem.Caption
        write-host "Creation Class Name: " $objItem.CreationClassName      
        write-host
    }
}
Catch 
{
    write-host "Failed to get data from machine (Error:"  $_.Exception.Message ")"
    write-host
}
finally 
{ }  

特定のマシンへの接続に失敗すると、コンソールにこのようなメッセージが表示され、クリーンキャッチメッセージは表示されません。

Get-WmiObject : The RPC server is
unavailable. (Exception from HRESULT:
0x800706BA) At Z:\7.0 Intern
Programvare\Powershell\Get memory of
all computers in AD.ps1:25 char:34
+ $colItems = get-wmiobject <<<< -class "Win32_PhysicalMemory"
-namespace "root\CIMV2" -computername $strComputerName -Credential
$credentials
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject],
COMException
+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

どのように解決するのですか?

リモート WMI クエリを実行しようとしたときに、あなたの結果を複製することができました。 投げられた例外は Try/Catch によって捕捉されず、また、quot;terminating error" ではないため、Trap によっても捕捉されません。 PowerShellでは、終端エラーと非終端エラーがあります。 Try/Catch/FinallyやTrapは、ターミネーティングエラーに対してのみ機能するようです。

自動変数$errorに記録され、自動変数$?

生成されたエラーの外観から、エラーが返され、キャッチ可能な例外でラップされていないように見えます。 以下は、生成されたエラーのトレースです。

PS C:\scripts\PowerShell> Trace-Command -Name errorrecord  -Expression {Get-WmiObject win32_bios -ComputerName HostThatIsNotThere}  -PSHost
DEBUG: InternalCommand Information: 0 :  Constructor Enter Ctor
Microsoft.PowerShell.Commands.GetWmiObjectCommand: 25857563
DEBUG: InternalCommand Information: 0 :  Constructor Leave Ctor
Microsoft.PowerShell.Commands.GetWmiObjectCommand: 25857563
DEBUG: ErrorRecord Information: 0 :  Constructor Enter Ctor
System.Management.Automation.ErrorRecord: 19621801 exception =
System.Runtime.InteropServices.COMException (0x800706BA): The RPC
server is unavailable. (Exception from HRESULT: 0x800706BA)
   at
System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
   at System.Management.ManagementScope.InitializeGuts(Object o)
   at System.Management.ManagementScope.Initialize()
   at System.Management.ManagementObjectSearcher.Initialize()
   at System.Management.ManagementObjectSearcher.Get()
   at Microsoft.PowerShell.Commands.GetWmiObjectCommand.BeginProcessing()
errorId = GetWMICOMException errorCategory = InvalidOperation
targetObject =
DEBUG: ErrorRecord Information: 0 :  Constructor Leave Ctor
System.Management.Automation.ErrorRecord: 19621801

あなたのコードのための回避策は、次のようになります。

try
{
    $colItems = get-wmiobject -class "Win32_PhysicalMemory" -namespace "root\CIMV2" -computername $strComputerName -Credential $credentials
    if ($?)
    {
      foreach ($objItem in $colItems) 
      {
          write-host "Bank Label: " $objItem.BankLabel
          write-host "Capacity: " ($objItem.Capacity / 1024 / 1024)
          write-host "Caption: " $objItem.Caption
          write-host "Creation Class Name: " $objItem.CreationClassName      
          write-host
      }
    }
    else
    {
       throw $error[0].Exception
    }