スクリプト ワークフローの作成

 

適用対象: Windows Server 2012,Windows Server 2012 R2

このセクションのトピックでは、Windows PowerShell で関数やスクリプトの作成に使用した言語と同じ Windows PowerShell® スクリプト言語でワークフローを作成する方法について説明します。 コマンド ラインで作成したワークフローを実行して、スクリプトに含め、スクリプト モジュールに含めることができます。

Windows Workflow Foundation のネイティブ言語 XAML でのワークフロー作成の詳細については、MSDN ライブラリの Windows PowerShell ワークフローの作成に関するページを参照してください。

ワークフローの計画

Windows PowerShell ワークフローは、実行するたびに数百台のコンピューターからデータを収集して変更を加える強力なソリューションです。 ワークフローの設計は、簡潔さと効率を考慮して計画します。 ワークフロー自体が中断したり、ユーザーによって中断されることがあること、単一のサーバー側プロセスに接続する多数の PSSession から制御できること、再起動の影響を受けないこと、並行して実行されるコマンドや関数が含まれること、各コマンドが独自のセッションで実行されることに注意してください。

次の計画ガイドラインに従ってください。

  • ワークフローに慣れていない場合は、このセクションの「スクリプト ワークフローとスクリプトとの構文上の違い」などの参照トピックを確認してください。

  • ワークフローで実行するタスクを列挙することから始めます。 同時に実行できるセクションやあらかじめ設定した順序で実行する必要のないセクションをマークします。 これらのセクション内で、順番に実行する必要のあるものをマークします。

  • タスクをワークフロー内の関数に整理します。 それぞれのタスクについて、既存の Windows PowerShell コマンドレットを使用するか、または新しいコマンドを作成して、重要な各手順の後にチェックポイントを追加します。

  • ワークフローは、複数の対象コンピューターで実行するように設計されています。 ワークフローでリモート セッションを作成したり、Invoke-Command コマンドレットを使用するようなリモート コマンドを使用する必要はありません。

  • 複数のコンピューターで実行されるスクリプトと同様に、オペレーティング システム、デバイス、ファイル システムの編成、環境変数、Windows PowerShell のバージョンなど、スクリプトの動作に影響する可能性のあるコンピューター間の相違を考慮してください。

  • 事前にワークフローのヘルプ トピックを計画します。 優先するワークフロー アーキテクチャ、優先するセッション構成の特徴、アクセス許可など、ユーザーとの通信に必要な情報を記録に残します。

ワークフローを作成するには、Windows PowerShell Integrated Scripting Environment (ISE) など、ワークフローの構文を実行し、構文エラーを強調表示するスクリプト エディターを使用します。 スクリプトとワークフローとは構文上の違いが大きいため、ワークフローとスクリプトの両方を理解するツールを使用すると、コーディングとテストの時間を大幅に節約できます。

ワークフローに最適なタスクの詳細については、「Windows PowerShell ワークフローについて」のワークフローと Windows PowerShell スクリプトの違いに関する説明を参照してください。

workflow キーワード

Windows PowerShell で workflow コマンドを識別できるようにする workflow キーワードで開始します。workflow キーワードは、スクリプト ワークフローで必要です。workflow キーワードの後に、ワークフローの名前が続きます。 ワークフローの本文は、かっこで囲みます。

Workflow キーワードの構文を次に示します。

workflow Test-Workflow
{
    ...
}

Windows PowerShell スクリプト言語のキーワードの詳細については、「about_Language_Keywords」を参照してください。

ワークフローとワークフロー要素の名前付け

ワークフローのコマンドの種類は Windows PowerShell です。 動詞-名詞の形式で名前を選択します。 名前に承認された動詞を選択するには、Get-Verb コマンドレットを使用し、Windows PowerShell コマンド向けの承認された動詞に関するヘルプ トピックを参照してください。 承認された動詞を含まないコマンドがモジュールからインポートされると、Windows PowerShell は警告を生成します。 必要に応じて、わかりやすい名詞と名詞プレフィックスを使用して、ワークフローがセッションにインポートされるときに、コマンド名の競合を防止します。

ワークフローのパラメーター名と変数名には、英数字、ハイフン (-) 、アンダースコア ( _ ) のみが使用できます。 ハイフンを使用したパラメーター名はワークフローやワークフローへの呼び出しで使用するたびにかっこで囲む必要があるため、パラメーター名にハイフンを使用するのは避けてください。ワークフロー共通パラメーター、ワークフロー ランタイム変数の名前、または "workflow" や"parallel" など、その他の予約語は使用しないでください。

ワークフロー ランタイム パラメーターの詳細については、MSDN ライブラリのヘルプ トピック「PSWorkflowRuntimeVariable Enumeration (PSWorkflowRunTimeVariable 列挙)」を参照してください。

予約語に関する詳細については、「スクリプト ワークフローとスクリプトとの構文上の違い」の「ワークフローの予約語」と「about_Reserved_Words」を参照してください。

ワークフローへのパラメーターの追加方法

ワークフローにパラメーターを追加するには、Param キーワードで、オプションの Parameter 属性を使用します。 これは関数にパラメーターを追加する場合と同じ手法です。

次のコード ブロックは、スクリプト ワークフローの Param キーワードと Parameter 属性の構文を示します。

workflow Test-Workflow
{
param ([Type]$<ParameterName>)
}

workflow Test-Workflow
{
    Param
    (
        [Parameter(Mandatory=<$True | $False>)]
        [<Type>]
        $<ParameterName>
    )
}

CmdletBinding 属性を使用して、ConfirmImpactDefaultParameterSetNameHelpUri、および SupportsShouldProcess 属性を使用することもできます。

次のコード ブロックは、CmdletBinding 属性を使用したサンプル ワークフローの構文を示します。

workflow Test-Workflow
{   
    [CmdletBinding(ConfirmImpact=<String>,
        DefaultParameterSetName=<String>,
        HelpURI=<URI>,
        PositionalBinding=<Boolean>)]

    Param
    (
        [parameter(Mandatory=$true)]
        [String[]]
        $<ParameterName>
    )
}

ワークフローにワークフロー共通パラメーターを追加する必要はありません。Windows PowerShell ワークフローでは、CmdletBinding 属性や Parameter 属性のない簡単なワークフローを含むすべてのワークフローに、共通パラメーターとワークフロー共通パラメーターを追加します。

関数とワークフローのパラメーターの詳細については、次のヘルプ トピックを参照してください。

ワークフローへのアクティビティの追加方法

アクティビティとは、ワークフローの基本単位です。 ワークフローで使用するすべてのコマンドと式は、アクティビティとして実行されます。Windows PowerShell ワークフローで、アクティビティはコマンドレットによく似ています。 アクティビティは、アクティビティ名に続けてパラメーターを入力して実行します。Windows PowerShell ワークフローは、Windows PowerShell に含まれる多数のコマンドレットをアクティビティに変換します。 除外されるコマンドレットは少ししかありません。 除外されるコマンドレットの詳細については、「スクリプト ワークフローでのアクティビティの使用」の「除外されるコマンドレット」を参照してください。

Windows PowerShell コア コマンドレットの大多数は、アクティビティとして実装されています。 これをワークフローで使用するには、コマンドレット名、またはコマンドレットのエイリアスを入力するだけです。

たとえば、次のワークフローには Get-Process アクティビティが含まれています。

workflow Test-Workflow
{
    Get-Process -Name PowerShell
    gps -Name Winword
}

コマンドレットに一致するアクティビティがなく、明示的に除外されていない場合、Windows PowerShell ワークフローは、inlineScript アクティビティのコマンドレットを自動的に実行して、出力をワークフローに返します。

たとえば、次のワークフローは、inlineScript アクティビティで暗黙的に実行される Get-WindowsFeature コマンドレットを使用しています。

workflow Test-Workflow
{
    Get-Process -Name PowerShell
    Get-WindowsFeature -Name PowerShell, PowerShell-v2
}

アクティビティとして実装されていないため、除外されたコマンドレットも実行できますが、これは inlineScript アクティビティで実行する必要があります。 たとえば、次のワークフローは、inlineScript アクティビティを使用して、除外された Get-Variable コマンドレットを実行します。

workflow Test-Workflow
{
    Get-Process -Name PowerShell
    Get-WindowsFeature -Name PowerShell, PowerShell-v2
    InlineScript { Get-Variable -Name PSHome }
}

ワークフローでは、算術式や比較ステートメントなどの式を使用することもできます。Windows PowerShell ワークフローは、その目的で設計された特殊なアクティビティで、式を自動的に実行します。

たとえば、次のワークフローには式が含まれています。 すべての式と同じように、アクティビティで実行されます。

workflow Test-Workflow
{
    Get-Process -Name PowerShell
    Get-WindowsFeature -Name PowerShell, PowerShell-v2
    InlineScript { Get-Variable PSHome }

    320GB / 3MB
}

アクティビティの詳細については、「スクリプト ワークフローでのアクティビティの使用」を参照してください。

アクティビティのパラメーターを使用する方法

アクティビティは、コマンドレットと同じように、パラメーターを持つコマンドです。 コマンドレットがアクティビティに変換されても、構文とパラメーターは変わりません。 ヘルプ トピック「スクリプト ワークフローのアクティビティ」にいくつかの例外が記載されています。

ただし、位置指定パラメーターはアクティビティでは有効でないため、すべてのパラメーター名が必要です。 パラメーター エイリアスと省略形は許可されます。 たとえば、次のサンプル ワークフローでは、Get-ProcessGet-WindowsFeatureGet-Variable コマンドレットの Name パラメーターがコマンドに表示されています。

workflow Test-Workflow
{
    Get-Process -Name PowerShell
    Get-WindowsFeature -Name PowerShell, PowerShell-v2
    InlineScript { Get-Variable -Name PSHome }
}

動的パラメーターもアクティビティで有効ではありません。 動的パラメーターを呼び出すには、InlineScript アクティビティでコマンドを囲みます。たとえば、次のワークフローには、Get-ChildItem コマンドレットの動的パラメーター CodeSigningCert を使用する inlineScript アクティビティが含まれています。CodeSigningCert パラメーターは、証明書プロバイダーによって追加され、Cert: ドライブでのみ機能します。

workflow Test-Workflow
{
   InlineScript {Get-ChildItem -Path Cert:\CurrentUser -CodeSigningCert}
} 

inlineScript アクティビティの詳細については、「ワークフローでの Windows PowerShell コマンドの実行」を参照してください。

アクティビティ共通パラメーターを使用する方法

Windows PowerShell ワークフローは、一連のアクティビティ共通パラメーターをアクティビティに追加します。 これらのパラメーターを使用すると、複数コンピューター環境で重要なオプションを設定できます。

ワークフロー共通パラメーターの一部は、アクティビティ共通パラメーターでもあります。 この機能を使用すると、ワークフロー共通パラメーターの値にアクティビティ固有の例外を作成できます。 たとえば、アクティビティの PSComputerName パラメーターを使用して選択したコンピューターのみでアクティビティを実行したり、PSCredential パラメーターを使用して、別の資格情報でアクティビティを実行することができます。

アクティビティ共通パラメーターは、すべてではありませんが、大多数のアクティビティで有効です。 たとえば、アクティビティ共通パラメーターは、Suspend-Workflow および Checkpoint-Workflow アクティビティでは無効です。 また、アクティビティ共通パラメーターは、Windows PowerShell ワークフローがアクティビティで自動的に実行するコマンドレットや式では使用できません。 アクティビティ共通パラメーターは InlineScript アクティビティで使用できますが、InlineScript スクリプト ブロックのコマンドでは使用できません。

次のワークフローのアクティビティでは、有効な場所にアクティビティ共通パラメーターが使用されています。

workflow Test-Workflow
{
    Get-Process -Name PowerShell -PSComputerName Server01, Server 12
    InlineScript { Get-Variable -Name PSHome } -PSRunningTimeoutSec 3600

    #No activity common parameters.
    Get-WindowsFeature -Name PowerShell, PowerShell-v2  

    #No activity common parameters.
    320GB / 3MB
}

アクティビティ共通パラメーターの詳細については、「スクリプト ワークフローでのアクティビティの使用」を参照してください。

共通パラメーターの値の取得方法

Windows PowerShell ワークフローでは、すべてのワークフローにワークフロー ランタイム変数が追加されます。 ワークフロー ランタイム変数には、共通パラメーターの値、ワークフロー共通パラメーター、ワークフローで重要なその他の値が含まれます。

変数値は非常に便利です。 時間を取って確認し、ワークフローで使用してください。 たとえば、ワークフローを実行すると、PSComputerName パラメーターは対象コンピューターの名前を取得しますが、ワークフローで $PSComputerName 変数にアクセスすると、ワークフローが現在実行されているコンピューターの名前が含まれます。

ワークフロー ランタイム変数の詳細については、「PSWorkflowRuntimeVariable Enumeration (PSWorkflowRuntimeVariable Enumeration 列挙)」を参照してください。

ワークフロー内からパラメーター値にアクセスするには、変数名を使用します。 変数を定義する必要はありません。

たとえば、次のワークフローは、$PSConnectionRetryCount 変数として参照することで、PSConnectionRetryCount 共通パラメーターの値を使用します。

workflow Test-Workflow
{
    "Retry count is $PSConnectionRetryCount."
}

次の例は、ワークフローが実行されているときに、PSConnectionRetryCount パラメーターを使用して、パラメーター値がワークフローに表示される場合を示しています。

PS C:\>Test-Workflow -PSConnectionRetryCount 4
Retry count is 4.

ワークフローでランタイム パラメーターと共通パラメーターの値を変更するには、Set-PSWorkflowData アクティビティを使用します。

たとえば、次のワークフローには、PSConnectionRetryCount 値を変更するコマンドが含まれています。

workflow Test-Workflow
{
    "Retry count is $PSConnectionRetryCount."
    Set-PSWorkflowData -PSConnectionRetryCount 5
    "Retry count is $PSConnectionRetryCount."
}

PS C:\>Test-Workflow -PSConnectionRetryCount 4
Retry count is 4.
Retry count is 5.

Windows PowerShell ワークフローの変数の詳細については、次のヘルプ トピックを参照してください。

ランタイム変数と共通パラメーターの値を取得する方法

Windows PowerShell ワークフローでは、すべてのワークフローにワークフロー ランタイム変数が追加されます。 ワークフロー ランタイム変数には、共通パラメーターの値、ワークフロー共通パラメーター、ワークフローで重要なその他の値が含まれます。

変数値は非常に便利です。 時間を取って確認し、ワークフローで使用してください。 たとえば、ワークフローを実行すると、PSComputerName パラメーターは対象コンピューターの名前を取得しますが、ワークフローで $PSComputerName 変数にアクセスすると、ワークフローが現在実行されているコンピューターの名前が含まれます。

ワークフロー ランタイム変数の詳細については、「PSWorkflowRuntimeVariable Enumeration (PSWorkflowRuntimeVariable Enumeration 列挙)」を参照してください。

ワークフロー内からパラメーター値にアクセスするには、変数名を使用します。 変数を定義する必要はありません。

たとえば、次のワークフローは、$PSConnectionRetryCount 変数として参照することで、PSConnectionRetryCount 共通パラメーターの値を使用します。

workflow Test-Workflow
{
    "Retry count is $PSConnectionRetryCount."
}

次の例は、ワークフローが実行されているときに、PSConnectionRetryCount パラメーターを使用して、パラメーター値がワークフローに表示される場合を示しています。

PS C:\>Test-Workflow -PSConnectionRetryCount 4
Retry count is 4.

ワークフローでランタイム パラメーターと共通パラメーターの値を変更するには、Set-PSWorkflowData アクティビティを使用します。

たとえば、次のワークフローには、PSConnectionRetryCount 値を変更するコマンドが含まれています。

workflow Test-Workflow
{
    "Retry count is $PSConnectionRetryCount."
    Set-PSWorkflowData -PSConnectionRetryCount 5
    "Retry count is $PSConnectionRetryCount."
}

PS C:\>Test-Workflow -PSConnectionRetryCount 4
Retry count is 4.
Retry count is 5.

Windows PowerShell ワークフローの変数の詳細については、次のヘルプ トピックを参照してください。

ワークフローでスクリプトを実行する方法

ワークフローでスクリプト (.ps1 ファイル) を実行するには、InlineScript アクティビティでスクリプトの呼び出しを囲みます。 他のコマンドやアクティビティと同じように、スクリプトはすべてのワークフローの対象コンピューターで実行され、出力がワークフローに返されます。

たとえば、次のワークフローには、スクリプトを実行する InlineScript アクティビティが含まれます。 スクリプトは共有ディレクトリに保存されます。 ワークフローは、スクリプトが完了すると、PSPersist アクティビティ パラメーターを使用して、チェックポイントを取得します。

workflow Test-Workflow
{
   $AssetData =InlineScript {\\Server01\Share01\Get-AssetData.ps1 -All} -PSPersist
   ...
}

ワークフローは複数のコンピューターで実行するように設計されているため、相対パスではなく、スクリプト ファイルへの絶対パスを使用します。

Parallel でコマンドを実行する方法

Parallel および ForEach -Parallel キーワードは、コマンドを同時に、不定な順序で実行することで、ワークフローを最適化します。Sequence キーワードは、選択したコマンドを Parallel スクリプト ブロック内で順番に実行します。 これらのキーワードは、ワークフローでのみ有効です。 入れ子になったワークフローでは有効ですが、ワークフローで入れ子になった関数では有効ではありません。 既定では、次のコマンドが開始する前に各コマンドが完了する場合、コマンドは順番に実行されます。

並列実行では、特にワークフローで多数のコンピューターが対象となっている場合、可能な限り使用すると、パフォーマンスがかなり向上します。

次の種類のコマンドとアクティビティは、並列実行に適しています。

  • Get-Process コマンドや Get-Service コマンドなどのデータを共有しないコマンド。

  • 項目などのコレクションに実行されるコマンド。 大多数の ForEach ステートメントは、ForEach -Parallel 実行に適しています。

Parallel

Parallel スクリプト ブロックのコマンドは、同時に実行できます。 実行される順序は決まっていません。

次の図は、Parallel キーワードとスクリプト ブロックを使用したワークフローの構文を示します。

workflow Test-Workflow
{
    Parallel
    {
         <Activity>
         <Activity>
...
    }
}

たとえば、次のワークフローには、コンピューターでプロセスやサービスを取得するアクティビティを実行する Parallel スクリプト ブロックが含まれています。 Get-Process と Get-Service の呼び出しは独立しているため、同時に、任意の順序で実行できます。

workflow Test-Workflow
{
    Parallel
    {
         Get-Process
         Get-Service
    }
}

ForEach -Parallel

ForEach キーワードの Parallel パラメーターは、指定したコレクションで各項目に ForEach スクリプト ブロックのコマンドを 1 回実行します。 コレクションの項目は同時に処理されます。 スクリプト ブロックのコマンドは順番に実行されます。

Windows PowerShell の ForEach ステートメントのように、コレクション ($<Collection>) を含む変数は、ForEach -Parallel ステートメントより前に定義する必要がありますが、現在の項目 ($<item>) を表す変数は、ForEach -Parallel ステートメントで定義されます。

次の図はコマンド構文を示します。

workflow Test-Workflow
{
    ForEach -Parallel ($<item> in $<collection>)
    {
       <Activity1>
       <Activity2>
 ...
    }
}

たとえば、次のワークフローには、Get-Disk アクティビティが取得したディスクを処理する Foreach -Parallel ステートメントが含まれています。 スクリプト ブロックのコマンドは順番に実行されますが、これらはディスク上では同時に実行されます。

workflow Test-Workflow
{
    $Disks = Get-Disk
    ForEach -Parallel ($Disk in $Disks)
    {
        $DiskPath = $Disk.Path   
        $Disk | Initialize-Disk
        Set-Disk -Path $DiskPath
    }
}

Sequence

Sequence キーワードは、Parallel スクリプト ブロック内のシーケンスでコマンドを実行します。Sequence スクリプト ブロックは他のコマンドと同時に実行されますが、Sequence スクリプト ブロック内のコマンドは、順番に、指定された順序で実行されます。

次のコード ブロックは、Sequence スクリプト ブロックの構文を示します。 Activity 3 は、Activity 1 と Activity 2 より前、または同時に実行される可能性がありますが、Activity 4 は Activity 3 が完了するまで実行されません。

workflow Test-Workflow
{
    parallel
    {
       <Activity1>
       <Activity2>

       sequence 
       {
           <Activity3>
           <Activity4>
           ...
       }
        ...
    }
}