ディレクトリのサイズを計算するためにdu.exe( Disk Usage 元はSysinternals製)を使用するPowerShellスクリプトがあります。
コンソールでdu c:\Backup
を実行すると、期待どおりに動作しますが、ISEまたはPowerGuiで実行された同じコード行で、期待される結果とエラーが表示されます。
+ du <<<< c:\backup
+ CategoryInfo : NotSpecified: (:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
何故ですか?このエラーを回避するにはどうすればよいですか? &
を使用してinvoke-expressionを試しましたが、行きません。
助けてくれてありがとう。
これを回避するには、stderrをnullにリダイレクトできます(例:
du 2> $null
基本的に、コンソールホストとISE(およびリモート処理)はstderrストリームを異なる方法で処理します。コンソールホストでは、色付きの出力やエラーを画面に書き込む他のアプリケーションと連携して動作するために、edit.comなどのアプリケーションをPowerShellがサポートすることが重要でした。 I/Oストリームがコンソールホストでリダイレクトされない場合、PowerShellはネイティブEXEに直接書き込むコンソールハンドルを提供します。これにより、PowerShellがバイパスされるため、PowerShellは書き込まれたエラーを認識できないため、$ errorまたはPowerShellのstderrストリームへの書き込みによってエラーを報告できません。
ISEとリモート処理はこのシナリオをサポートする必要がないため、stderrでエラーを確認し、その後エラーを書き込んで$ errorを更新します。
私は最近同じ問題に直面していますが、stderrの出力をstdoutに送りたいと思います。次のように動作すると思います。
& du 2>&1
しかし、PowerShellはリダイレクトを解釈し、「du」の完了後に処理します。私が見つけた回避策は、cmd.exe/cを使用して呼び出すことです:
& cmd /c 'du 2>&1'
NativeCommandError
出力を抑制する別の方法は、パイプラインのobjectsをstringsこの回答 の下部に概説されているとおり:
du c:\Backup 2>&1 | %{ "$_" }
以前のFIXはエラーをリダイレクトしますが、ユーザー名またはパスワードが不適切な場合、または統合認証を使用している場合、アクセス権がない場合、実際のエラーを失う可能性があります。
そのため、ここにエラー処理を実装し、psexecによって発生した特定のエラー(それ以外のエラー)をバイパスする方法を示します。
try{
psexec command .....
}
catch [System.Management.Automation.RemoteException]{
if ($_.TargetObject -like "Connecting to *" -and $_.CategoryInfo.Category -eq "NotSpecified" -and $_.FullyQualifiedErrorId -eq "NativeCommandError" -and $_.InvocationInfo.MyCommand.Name -like "psexec*.exe"){
$error.Remove[$Error[0]]
}
else{
Throw
}
}
catch{
throw
}
試してください:
du 2>&1 | %{ "$_" }