私の目標は、Powershellを使用して、多数のWindowsサーバーでスケジュールされたタスクを確認、無効化、および削除することです。一部のサーバーはWindows2008R2であるため、Get-ScheduledTaskは問題外です。私はschtasksを使用する必要があります
これが私がこれまでに持っているものです
$servers = (Get-ADComputer -Server DomainController -Filter 'OperatingSystem -like "*Server*"').DNSHostname
$servers |
ForEach-Object {
if (Test-Connection -Count 1 -Quiet -ComputerName $_) {
Write-Output "$($_) exists, checking for Scheduled Task"
Invoke-Command -ComputerName $_ {
If((schtasks /query /TN 'SOMETASK')) {
Write-Output "Processing removal of scheduled task`n"
schtasks /change /TN 'SOMETASK' /DISABLE
schtasks /delete /TN 'SOMETASK' /F
}
else {
Write-Output "Scheduled Task does not exist`n"
}
}
}
}
これは、SOMETASKが存在する場合は正常に機能しますが、存在しない場合、Powershellは次のようなエラーを吐き出します。
ERROR: The system cannot find the file specified.
+ CategoryInfo : NotSpecified: (ERROR: The syst...file specified.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
+ PSComputerName : SERVER1
NotSpecified: (:) [], RemoteException
Scheduled Task does not exist
$ ErrorActionPreferenceを「SilentlyContinue」に設定することでこの動作を回避できますが、これにより、関心のある他のエラーが抑制されます。Try、Catchも試しましたが、それでもエラーが発生します。-ErrorHandling引数をIFステートメントに追加できるとは思いません。誰か助けてくれませんか?
ありがとうございました、
tl; dr:
2>$null
外部プログラム(などschtasksk.exe
)への呼び出しからのstderr出力を抑制するために使用します
$ErrorActionPreferece
は、がに設定されていないことを確認してください'Stop'
。# Execute with stderr silenced.
# Rely on the presence of stdout output in the success case only
# to make the conditional true.
if (schtasks /query /TN 'SOMETASK' 2>$null) { # success, task exists
"Processing removal of scheduled task`n"
# ...
}
背景情報とより一般的な使用例については、以下をお読みください。
質問に示されているように、外部プログラムのstderrストリームからの行がどのように現れるかを考えると、PowerShell ISEでコードを実行しているように思われます。これから離れることをお勧めします。PowerShellISEは廃止されているため、今後は避ける必要があります(リンクされた回答の下部セクション)。
ISEは、PowerShellののエラーストリームを経由して標準エラー出力ラインの表面を表面デフォルトでは特に問題である-を参照して、このGitHubの問題を。
幸いなことに、通常のコンソールはそれを行いません-stderr行をホスト(コンソール)に渡し、通常どおりに(赤ではなく)印刷します。これは、すべてのstderrが一般的に想定できないことを考えると、正しいことです。出力はエラーを表します(ストリームの名前にもかかわらず)。
正常に動作する外部プログラムでは、stderr出力の存在からではなく、プロセスの終了コード(自動$LASTEXITCODE
変数[1]に反映されている)からのみ成功と失敗を導き出す必要があります。:終了コード0
は成功を示し、ゼロ以外の終了コードは(通常)失敗を示します。
あなたの特定のケースに関して:
通常のコンソールでは、$ErrorActionPreference
設定変数の値は、リダイレクトも使用する場合schtasks.exe
のバグの形式を除いて、などの外部プログラムには適用されません2>
(PowerShell [Core] 7.0以降)-このGitHubの問題を参照してください。PowerShell7.1.0以降-preview.6; 修正された動作は、実験的な機能 として利用できますPSNotApplyErrorActionToStderr
。
あなたのでschtasks /query /TN 'SOMETASK'
、コマンドの機能テストは、次の操作を行うことができます。
# Execute with all streams silenced (both stdout and stderr, in this case).
# schtask.exe will indicate the non-existence of the specified task
# with exit code 1
schtasks /query /TN 'SOMETASK' *>$null
if ($LASTEXITCODE -eq 0) { # success, task exists
"Processing removal of scheduled task`n"
# ...
}
# You can also squeeze it into a single conditional, using
# $(...), the subexpression operator.
if (0 -eq $(schtasks /query /TN 'SOMETASK' *>$null; $LASTEXITCODE)) { # success, task exists
"Processing removal of scheduled task`n"
# ...
}
特定のケースでは、より簡潔な解決策が可能です。これは、schtasks
コマンド(a)成功した場合(タスクが存在する場合)にstdout出力を生成し、(b)成功した場合にのみ生成するコマンドに依存します。
# Execute with stderr silenced.
# Rely on the presence of stdout output in the success case only
# to make the conditional true.
if (schtasks /query /TN 'SOMETASK' 2>$null) { # success, task exists
"Processing removal of scheduled task`n"
# ...
}
schtasks.exe
stdout出力(PowerShellの成功出力ストリームにマップされる)を生成する場合1
、PowerShellの暗黙的なブール変換は条件付きを考慮します$true
(PowerShellのブール変換ルールの概要については、この回答の下部を参照してください)。
条件付きは成功出力ストリームの出力(1
)にのみ作用することに注意してください。この場合、stderr出力()などの他のストリームが渡さ2
れます(経験したとおり)。
2>$null
nullデバイスにリダイレクトすることにより、 stderr出力を無音にします。
1
および2
は、それぞれPowerShellの成功出力/エラーストリームの数です。外部プログラムの場合、それらはそれぞれstdout(標準出力)およびstderr(標準エラー)ストリームを参照しabout_Redirection
ます-を参照してください。
後で報告したい場合(または終了コードを適切に使用しない動作の悪いプログラムについて具体的に調べる必要がある場合)、リダイレクトを使用してstderr出力をキャプチャ2>
することもできます。
2> stderr.txt
stderr行をファイルに送信しますsdterr.txt
; 残念ながら、現在、変数でstderrをキャプチャする方法はありません。その構文を提案しているGitHubのこの提案を参照してください2>&variableName
。
$ErrorActionPreference
がに設定されていないことを確認する必要があります。これは、が誤ってスクリプト終了エラーをトリガーする'Stop'
ため2>
です。前述のバグとは別に、2>
現在(v7.0以降)を使用すると、別の予期しない副作用が発生します。stderr行も$Error
、エラーであるかのように自動コレクションに予期せず追加されます(想定できません)。
[1]$?
成功と失敗をブール値($true
/ $false
)で示す自動変数も設定されていますが、確実ではないことに注意してください。stderr出力は現在(v7.0)でリダイレクトされた場合、2>&
PowerShellのエラーストリームを介して予期せずルーティングされるため、 stderr出力の存在は、外部プログラムがレポートを介して全体的な成功を報告した場合でも、常にに設定さ$?
れます。したがって、成功をテストする唯一の信頼できる方法は、ではありません。$false
$LASTEXITCODE
0
$LASTEXITCODE -eq 0
$?
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加