tech.guitarrapc.cóm

Technical updates

PowerShell で スケジューラタスク(SchedulerTask) を操作する

タスクスケジューラは、現在でもGUIで設定している方が多いですね。 一台や二台にやるならいいのですが、 10台、100台の時はどうするのかなー、とか思います。 Linux には、いうに及ばず cron があります。 Windows には、 Windows XP, 2003 以降 schtasks.exe が at.exe に変わりあります。 え? PowerShell? できますよ。PowerShell 3.0 で。 (PowerShell2.0 ならPSK Module で) 今回は、複数台での タスクスケジューラの自動登録、実行などの方法を紹介します。 毎回同じ操作をAutomateする。こういう身近な作業からPowerShell 普及を進めていきたいものです。 

 

GUI

GUI の スケジューラタスクは誰もが知っている画面でしょう。 が、一応 Windows Server 2008 からcontrol panel 直下ではなくなっているので紹介しておきます。

Windows Server 2012 の場合

Server Manager > Tools > Task Scheduler にあります。

f:id:guitarrapc_tech:20190125041234p:plain

Windows 8 の場合

Control Panel > Administrative Tools > Task Scheduler にあります。

タイル画面で 管理ツールを表示している場合

タイル画面で 管理ツールの表示を有効にしていれば簡単です。

GUIで開いた直後の画面

このような感じですね。 ここは path にかかわるので把握しておくべきです。 Task SchedulerLibrary は path でいうところの \ (ホームパス) に当てはまります。

PowerShellで操作する

schtasks.exe じゃない理由? いえ、寧ろ schtasks.exe である理由がないのです。

やったことがある方なら分かると思いますが、 Windows XP と Windows 7 だけでも schtasks.exe のコマンドオプション / 実行挙動は変わっています。

PowerShell を使って一貫したパラメータ/挙動 を維持、PowerShell Remoting で遠隔PCにも操作を、これが schtasks.exe ではなく PowerShell で スケジューラタスクを触りたい理由です。

PowerShell V3.0 の場合

PowerShell V3 からは、標準で ScheduledTask Cmdlet があります。

Get-Command | where Name -like "*ScheduledTask*"

# あるいはこれでも
Get-Command -Module ScheduledTasks

コマンド一覧結果です。

CommandType Name                              ModuleName    
----------- ----                              ----------    
Function    Disable-ScheduledTask             ScheduledTasks
Function    Enable-ScheduledTask              ScheduledTasks
Function    Export-ScheduledTask              ScheduledTasks
Function    Get-ClusteredScheduledTask        ScheduledTasks
Function    Get-ScheduledTask                 ScheduledTasks
Function    Get-ScheduledTaskInfo             ScheduledTasks
Function    New-ScheduledTask                 ScheduledTasks
Function    New-ScheduledTaskAction           ScheduledTasks
Function    New-ScheduledTaskPrincipal        ScheduledTasks
Function    New-ScheduledTaskSettingsSet      ScheduledTasks
Function    New-ScheduledTaskTrigger          ScheduledTasks
Function    Register-ClusteredScheduledTask   ScheduledTasks
Function    Register-ScheduledTask            ScheduledTasks
Function    Set-ClusteredScheduledTask        ScheduledTasks
Function    Set-ScheduledTask                 ScheduledTasks
Function    Start-ScheduledTask               ScheduledTasks
Function    Stop-ScheduledTask                ScheduledTasks
Function    Unregister-ClusteredScheduledTask ScheduledTasks
Function    Unregister-ScheduledTask          ScheduledTasks

PowerShell V2.0 の場合

PowerShell Pack を入れれば利用できます。 全てだったかは記憶にありませんが (

http://archive.msdn.microsoft.com/PowerShellPack

タスクの取得

取得は簡単ですね。 Get-ScheduledTask Cmdlet で行います。 TaskName や TaskPath でフィルタも可能です。

Get-ScheduledTask -TaskName test -TaskPath \

が、私は where で絞る方を好みますが。

タスクの登録

スケジューラタスクの登録は、Register-SchedledTask Cmdlet で行います。 なお、Cmdlet の裏で行っているのは cim 操作です。

Register-ScheduledTask -TaskPath \ -TaskName test -Action $action -Trigger $trigger -Settings $settings

-TaskPath と -TaskName は見てのとおりです。 しかし、 -Action と -Trigger と -Setting は違います。 Action は、 {MSFT_TaskExecAction} として Trigger は、{MSFT_TaskLogonTrigger} として Settings は、 MSFT_TaskSettings3 として渡す必要があるのです。 この様子は、現在の スケジュラタスクを見れば分かるでしょう。

Get-ScheduledTask | where taskpath -eq \ | where TaskName -eq "CLMLSvc" | select *

表示結果例です。

State                 : Running
Actions               : {MSFT_TaskExecAction}
Author                : CyberLink
Date                  : 
Description           : 
Documentation         : 
Principal             : MSFT_TaskPrincipal2
SecurityDescriptor    : D:(A;OICI;FAGAKA;;;WD)
Settings              : MSFT_TaskSettings3
Source                : 
TaskName              : CLMLSvc
TaskPath              : \
Triggers              : {MSFT_TaskLogonTrigger}
URI                   : 
Version               : 
PSComputerName        : 
CimClass              : Root/Microsoft/Windows/TaskScheduler:MSFT_ScheduledTask
CimInstanceProperties : {Actions, Author, Date, Description...}
CimSystemProperties   : Microsoft.Management.Infrastructure.CimSystemProperties

Action の登録

Action は、スケジューラタスクでいうところの 操作 = 実際に行う実行内容です。多くが exe 指定 などでしょうか。 実際に何が設定可能かは、 パラメータで見てもいいですし、現在の設定から見てもいいでしょう。

(Get-ScheduledTask | where taskpath -eq \ | where TaskName -eq "CLMLSvc").Actions

このように表示されました。

Id               : 
Arguments        : 
Execute          : D:\Software\Video_Player\CyberLink\Power2Go\CLMLSvc.exe
WorkingDirectory : 
PSComputerName   : 

この定義は、New-ScheduledTaskAction で行うことが出来ます。 今回は、 PowerShell.exe を起動して、 Get-Date Cmdlet をログに出す操作を定義してみましょう。 この操作を 適当な 変数に入れておきます。

$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-Command 'Get-Date | Out-File D:\Test.log -Encoding default'"

Trigger の設定

Trigger はトリガー、つまり実行スケジュールですね。 実際に何が設定可能かは、 パラメータで見てもいいですし、現在の設定から見てもいいでしょう。

(Get-ScheduledTask | where taskpath -eq \ | where TaskName -eq "CLMLSvc").Triggers

このように表示されました。

Enabled            : True
EndBoundary        : 
ExecutionTimeLimit : 
Id                 : 
Repetition         : MSFT_TaskRepetitionPattern
StartBoundary      : 
Delay              : PT30S
UserId             : 
PSComputerName     : 

この定義は、New-ScheduledTaskTrigger で行うことが出来ます。 今回は、毎日 PM20:15 に起動するようにしましょう。 この操作も 適当な 変数に入れておきます。

$trigger = New-ScheduledTaskTrigger -DaysInterval 1 -Daily -At "20:15 PM"

Settingsの定義

Settings は、上記以外の挙動全てです。 例えば、どの Windows Version として起動するかや、実行画面を出すかなどです。 実際に何が設定可能かは、 パラメータで見てもいいですし、現在の設定から見てもいいでしょう。

(Get-ScheduledTask | where taskpath -eq \ | where TaskName -eq "CLMLSvc").Settings

このように表示されました。

AllowDemandStart                : True
AllowHardTerminate              : False
Compatibility                   : Vista
DeleteExpiredTaskAfter          : 
DisallowStartIfOnBatteries      : False
Enabled                         : True
ExecutionTimeLimit              : P3D
Hidden                          : True
IdleSettings                    : MSFT_TaskIdleSettings
MultipleInstances               : IgnoreNew
NetworkSettings                 : MSFT_TaskNetworkSettings
Priority                        : 7
RestartCount                    : 0
RestartInterval                 : 
RunOnlyIfIdle                   : False
RunOnlyIfNetworkAvailable       : False
StartWhenAvailable              : True
StopIfGoingOnBatteries          : False
WakeToRun                       : False
DisallowStartOnRemoteAppSession : False
UseUnifiedSchedulingEngine      : False
MaintenanceSettings             : 
volatile                        : False
PSComputerName                  : 

この定義は、New-ScheduledTaskSettingsSet で行うことが出来ます。 今回は、 Windows 8 として起動して、 起動時に 実行画面を表示しないようにしましょう。 この操作も 適当な 変数に入れておきます。

$settings = New-ScheduledTaskSettingsSet -Compatibility Win8 -Hidden

スケジュラータスクの登録

ここまで出来れば簡単です。 適当な名前をつけて、定義するタスクパスを指定します。 先述の通り、タスクスケジューラ直下なら、 \ となります。

Register-ScheduledTask -TaskPath \ -TaskName test -Action $action -Trigger $trigger -Settings $settings

この時、ユーザー名、パスワードを指定する場合は、直接指定もできます。

# user / Pass の場合
$user = "hoge"
$pass = "fuga"

Register-ScheduledTask -TaskPath \ -TaskName test -Action $action -Trigger $trigger -User $user -Password $pass

あるいは、 cim session 経由でも可能です。 この cim session は、 settings の設定定義時か、 Register での タスクスケジューラ定義時に可能です。

# cim session も可能
$cred = Get-Credential -UserName administrator -Message "hoge"
$cim = New-CimSession -Credential $cred

# cim sessionの場合 (Register との選択)
$settings = New-ScheduledTaskSettingsSet -Compatibility Win8 -Hidden -CimSession $cim 

# cim sesionの場合 ( SettingSet との選択)
Register-ScheduledTask -TaskPath \ -TaskName test -Action $action -Trigger $trigger -Settings $settings -Force -CimSession $cim

作成した スケジューラタスクを上書きしたい

同名の スケジューラタスクが同一パスに存在すると登録できません。 上書きするには、 Register 時に -Force をします。

# -Force 付けないと 同名エラー
Register-ScheduledTask -TaskPath \ -TaskName test -Action $action -Trigger $trigger -User $user -Password $pass

# -Force Swtich で上書き可能
Register-ScheduledTask -TaskPath \ -TaskName test -Action $action -Trigger $trigger -Settings $settings -Force

# ユーザーを指定してForce とか
Register-ScheduledTask -TaskPath \ -TaskName test -Action $action -Trigger $trigger -Settings $settings -User $user -Password $pass -Force

タスクの開始/停止

開始は Start 、 停止はStop です。

# 開始
Start-ScheduledTask -TaskPath \ -TaskName test
# 停止
Stop-ScheduledTask -TaskPath \ -TaskName test

タスクの無効/有効化

コレも容易です。 無効は Disable、 有効は Enable です。

# 無効
Disable-ScheduledTask -TaskPath \ -TaskName test

# 有効
Enable-ScheduledTask -TaskPath \ -TaskName test

タスクの削除

スケジューラタスクの削除は? Register の逆で Unregister です。 削除時は、確認第ログが出ますが -Force スイッチはありません。 バックグラウンドで暗黙に処理させる場合は、 -AsJob します。これで、ダイアログなしに削除できます。 この場合は、 Get-Job で結果を取得できます。

# 設定の除去 (-AsJob Switch で確認なしで除去)
Unregister-ScheduledTask -TaskName test
Unregister-ScheduledTask -TaskName test -AsJob

まとめ

決まったスケジューラタスクの登録は PowerShell で。 そのメリットは、一度設定を定めれば 人の手が入ることなく = DRY や Automation 、ミスの低減を実現するためです。 簡単ですので、試して見てください。 cim は、上手くいかなくて結構泣きましたが..... Windows 8 なら問題ないんですよね..... んー。まぁ現在の実行ユーザーなら不要なので要らないと言えば要らない?