Windows PowerShell でのバックグラウンドジョブ ~ その4 親ジョブと子ジョブ~

PowerShellで実行されるジョブには親子関係があります。

今回は

について説明します



親ジョブと子ジョブの確認

親子関係を確認する為に 、最初に次のコマンドを実行してみます。

このコマンドはローカルコンピュータとリモートコンピュータMyServ01に対し、Get-Serviceコマンドレットを実行します。

PS> $job = Invoke-Command localhost, MyServ01 -Command {Get-Service} -AsJob

この時点で次のようにGet-Jobコマンドレットを実行すると、1つのジョブが返されます。

1つのジョブでlocalhostとMyServ01に対して、コマンドが実行されていることがわかります。

PS> Get-Job
Id Name State HasMoreData Location Command
-- ---- ----- ----------- -------- -------
1 Job1 Completed True localhost,MyServ01 Get-Service

次に、下記のようにGet-Jobコマンドレットを使用して、もう少し詳しい情報を見てみましょう。(この確認方法はヘルプに載っています)

PS> Get-Job | Format-List -Property Name, ChildJobs 
Name      : Job1
ChildJobs : {Job2, Job3}

実行結果を見るとNameにJob1が、ChildJobsにJob2とJob3が記述されています。

これは、実際のジョブはJob2とJob3で実行されており、親ジョブであるJob1の管理下にあることを示しています。

次のように入力すれば、各子ジョブについて確認することができます。

PS> Get-Job Job2, Job3

Id              Name            State      HasMoreData     Location             Command
-- ---- ----- ----------- -------- -------
2 Job2 Completed True localhost Get-Service
3 Job3 Completed True MyServ01 Get-Service

 


子ジョブの管理

ジョブの親子関係がわかると、特定の子ジョブの実行結果を取得することが可能になります。

たとえば、先ほどの子ジョブであるJob2の実行結果を取得するのであれば

PS> Receive-Job -Id 2 -Keep

のように子ジョブのIDを指定することができます。

また、子ジョブは親ジョブに管理されていることから、次のようにRemeve-Jobコマンドレットを使用して親ジョブを削除すると、ぶら下がっているすべての子ジョブも削除されますので覚えておきましょう。

PS> Remove-Job -Id 1

Windows PowerShell でのバックグラウンドジョブ ~ その3 リモートコンピュータでのバックグラウンドジョブ~

これまでの記事

では、ローカルコンピュータにおけるバックグラウンドジョブについて説明しました。

今回は

について説明します。



対話型セッションでのバックグラウンドジョブ

PowerShellにおける対話型セッションでも、バックグラウンドジョブを実行することができます。

対話型セッションの方法については、Windows PowerShell によるリモート制御 ~その1 準備編~ を参照ください。

まずは、リモートコンピュータ(ここでは例として MyServ01 とします)に対話型接続をします。

PS> Enter-PSSesion MyServ01
[MyServ01]: PS C:\Work>

あとは、Start-Jobコマンドレットを使用すれば、対話型セッションの中でもローカルコンピュータ同様にバックグラウンドジョブを実行できます。

[MyServ01]: PS C:\Work> $job = Start-Job -ScriptBlock { Get-Service }

Start-Jobコマンドレットの使用方法については

Windows PowerShell でのバックグラウンドジョブ ~ その1 ローカルコンピュータでのバックグラウンドジョブ~

を参照ください。


永続的なセッションでのバックグラウンドジョブ

今度は、対話型セッションではなく、永続的なセッションでのバックグラウンドジョブについてです。

永続的なセッションについては、Windows PowerShell によるリモート制御 ~その3 永続的なセッション編 ~ を参照ください。

 

まずは、New-PSSessionコマンドレットでリモートコンピュータへのセッションを作成します。

PS >$sess = New-PSSession -ComputerName MyServ01

作成したセッションを使用してバックグラウンドジョブを実行するにはInvoke-Commandコマンドレットと-AsJobパラメータを使用します。

PS C:\Work>Invoke-Command -Session $sess -ScriptBlock { Get-Service } -AsJob

Id              Name            State      HasMoreData     Location             Command
--              ----            -----      -----------     --------             -------
1               Job1            Running    True            htaka2                Get-Service

たったこれだけで、リモートコンピュータでもバックグラウンドジョブを実行することができます。


参考記事

リモート制御については、下記の記事を参照ください

  • Windows PowerShell によるリモート制御 ~その1 準備編~
  • Windows PowerShell によるリモート制御 ~その2 セッション編(基礎)~
  • Windows PowerShell によるリモート制御 ~その3 永続的なセッション編 ~
  • Windows PowerShell によるリモート制御 ~その4 複数セッションの作成と使用 ~
  • Windows PowerShell によるリモート制御 ~その5 ComputerNameパラメータを持つコマンドレット ~
  • Windows PowerShell でのバックグラウンドジョブ ~ その2 ジョブ完了の待機とジョブの停止~

    今回は、実行したバックグランドジョブの完了を待機する方法と、ジョブを停止する方法についてです。

    について説明します。



    ジョブ完了の待機

    前回の記事では、バックグラウンドでジョブを実行すると、すぐに次のコマンドを実行できることについて説明しました。

    Wait-Jobコマンドレットを使用すれば、バックグラウンドジョブの実行完了を待ってから、コマンドプロンプトを表示させることができます。

    PS> Wait-Job

    Wait-Jobコマンドレットの使い道としては、他のコマンドとの同期を取る場合、時間のかかるコマンドの打ち切りなどが考えられます。

    Wait-Jobコマンドレットにはいろいろなパラメータがあります。いくつかの例とともに使い方を見てみましょう。

    まずは、一定時間待機する例です。

    一定時間待機するには-Timeoutパラメータを使用して、最大待ち時間(秒)を指定します。

    もしも、最大待機時間待ってもコマンドが完了しない場合は、待機を終了してコマンドプロンプトを表示して、バックグラウンドジョブを実行し続けます。

    下記は、IDが1のジョブを60秒間待機します。IDの確認方法は前回の記事を参照ください。

    PS> Wait-Job -ID 1 -Timeout 60

     

    次に、-Anyパラメータについてです。

    -Anyパラメータを指定すると、複数指定したバックグラウンドジョブのうち、いずれかが完了するとコマンドプロンプトを表示します。

    下記は、IDが1,3,5のいずれかのバックグランドジョブが完了した時点でコマンドプロンプトが表示されます。

    終了してないジョブは引き続き実行されます。

    PS> Wait-Job -ID 1, 3, 5 -Any

    ジョブの停止

    次にバックグランドジョブを停止する方法について見てみましょう。

    バックグラウンドジョブを停止するにはStop-Jobコマンドレットを使用します。

    まずはIDを指定してジョブを停止させる方法です。

    この場合は、下記のように-IDパラメータを使用して、停止したいジョブを指定します。

    PS> Stop-Job -ID 1,3

     

    次に-Stateパラメータを使用して、コマンドの実行状況によってジョブを停止させる方法を見てみましょう。

    -Stateパラメータには、NotStarted、Running、Completed、Stopped、Failed, Blocked を指定できます。

    たとえば、下記のコマンドは-StateにRunningを指定することにより、実行中のジョブをすべて停止させます。

    PS> Stop-Job -State Running

    Windows PowerShell でのバックグラウンドジョブ ~ その1 ローカルコンピュータでのバックグラウンドジョブ~

    PowerShell V1.0 では、バックグラウンドでのジョブ実行ができなかったため、コマンドが完了するまでプロンプト操作をすることができませんでした。

    PowerShell 2.0からは、簡単にバックグラウンドジョブの実行することができるようになりました。

    今回は、

    について説明します。



    ローカルコンピューターでのジョブ実行

    ローカルコンピュータでバックグラウンドジョブを実行するには、Start-Jobというコマンドプロンプトを使用します。

    Satrt-Jobコマンドレットの基本構文は

     

    Start-Job -ScriptBlock { バックグラウンドで実行するコマンド }

     

    です。

    次のコマンドは、Get-Serviceコマンドレットをバックグラウンドで実行します。

    実行したバックグランドジョブにはユニークな識別番号(Id)が付きます。

    PS> Start-Job -ScriptBlock { Get-Service }

    Id Name State HasMoreData Location Command
    -- ---- ----- ----------- -------- -------
    1 Job1 Running True localhost Get-Service
    どんなに時間がかかる処理でも、すぐにコマンドプロンプトに制御が戻るので、次のコマンドを実行することが可能になります。

    実行ジョブの取得と確認

    Start-Jobで実行したコマンドは、バックグラウンドで動作するため、後から実行結果を取得しなければなりません。

    現在いくつのジョブがバックグラウンドで動作しているのかを確認するには、Get-Jobコマンドレットを使用します。

    PS> Get-Job

    Id Name State HasMoreData Location Command
    -- ---- ----- ----------- -------- -------
    1 Job1 Completed True localhost Get-Service
    3 Job3 Running True localhost Get-Process...

    上記はIdが1と2のジョブが実行されていることがわかります。

    またStateの列を見ると、CompletedやRunningとなっており、そのジョブが完了しているのか実行中なのかを確認することができます。

    ジョブが失敗した場合には、Failedと表示されます。


    ジョブ結果の取得

    今度は、バックグラウンドで実行したジョブ結果を取得する方法について説明します。

    バックグラウンドで実行したジョブ結果を取得するにはReceive-Jobコマンドレットを使用します。

    Receive-Jobコマンドレットの基本構文は

     

    Receive-Job -Id ジョブID

     

    です。

    次のコマンドはジョブIDが1の実行結果を変数に代入しています

    $JobResult = Receive-Job -Id 1

     


    ジョブ結果取得時の注意点

    最後にジョブ結果取得時の注意点について説明します。

    バックグラウンドジョブの実行結果はキャッシュに保存されています。

    Receive-Jobコマンドレットは、既定ではジョブの結果をキャッシュから削除します。

    ジョブの実行が完了している場合には、すべての実行結果が取り出されますが、実行途中のジョブは途中までの結果を返してその分の結果をキャッシュから削除します。

    もう1度Receive-Jobコマンドレットを実行すると、先ほど取得した結果の続きを返します。

    もしも、キャッシュから削除したくない場合にはkeepパラメータを使用します。

    たとえば次のコマンドは、ジョブ結果をキャッシュから取得しますが、キャッシュの中身は削除されません。

    $Jobresult =Receive-Job -Id 1 -Keep

     

     

    *本記事はWindows XPにインストールしたWindows PowerShell 2.0 RCで検証しております。