Windows PowerShell: Windows PowerShell とワークフローは似て見える

今年は、Don Jones が Windows PowerShell ワークフローに関する 12 部構成のチュートリアルを毎月 1 部ずつお届けします。2013 年 1 月号から始まるシリーズは順番にお読みいただくことをお勧めします。

Don Jones

ワークフローの外観は、Windows PowerShell の関数やスクリプトのように見えますが、これらは別物です。似ているのは、表面上だけで、その表面上の領域だけを見ても、全部が似ているわけではありません。

Windows PowerShell では、ワークフローを完全に別のテクノロジである Windows Workflow Foundation (WF) に変換しなければならないことは常に覚えておいてください。つまり、ワークフローでは、WF で複製可能な処理しか実行できません。コードは、独自の規則や制限があるまったく異なる種類の環境で実行されることになります。

ワークフローとしてスクリプトを実行する

単純に標準的な Windows PowerShell スクリプトをワークフローとして実行するのが、ワークフローを実行する最も簡単な方法です。これは、Invoke-AsWorkflow コマンドレットを使用して実行できます。このコマンドレットは PSWorkflow モジュールに含まれていますが、Windows PowerShell 3.0 では、このモジュールを明示的に読み込まなくても、このコマンドレットを検出して実行できます。このコマンドレットでは、基本的に InlineScript ブロックにすべてのスクリプトをラップします。つまり、スクリプトは、WF 内で 1 つの手順として実行されます。

このコマンドレットを使用すると、Windows PowerShell ワークフローの制限についてあまり心配する必要がありません。しかし、中断されたプロセスを再開するなど、Windows PowerShell ワークフローの一部の機能が利用できなくなります。この場合の "プロセス" は、1 つの手順で実行されるスクリプト全体で構成されているため、一時停止または中断する必要がある場合、途中からプロセスを再開する方法はありません。次に、いくつかのコマンドを含むスクリプト ブロックを 1 つ作成してワークフローとして実行する例を示します。

$script = { $name = Get-Content Env:\COMPUTERNAME $name | Out-File c:\MyName.txt Get-Service } Invoke-AsWorkflow -Expression $script -PSComputerName DC,CLIENT

ここでは、WF によって、このコードが 1 つの InlineScript ブロックとして実行されることを示すために変数を使用しました。WF で実行されるすべてのコマンドには独自の新しい環境が用意されることを覚えておいてください。コマンド間でデータを保持する組み込みの方法はありません。つまり、そのままでは、変数はほとんど役に立ちません。しかし、このスクリプト全体は InlineScript ブロックの 1 つの手順として暗黙的にラップされているため、作成した変数ではスクリプトが実行されている間データを保持します。

なので、心配する必要はありません。また、Windows PowerShell ワークフローには、他にも利点がいくつかあります。すべてのワークフローに共通のパラメーターもいくつかあります。これらのパラメーターを使用すると、対象コンピューターの名前などを指定できます。スクリプトは、複数のコンピューターで機能する基本的なインフラストラクチャを継承します。実行時間が長いスクリプトについては、ワークフローを開始して、このワークフローが実行している間はリモート コンピューターとの接続を切断できます。これは優れた機能です。

正式なワークフローの構文

とてもシンプルなワークフローを次に示します。

Workflow New-Server { Get-Content -Path Env:\COMPUTERNAME | Out-File -FilePath C:\MyName.txt Get-NetAdapter -Physical } New-Server -PSComputerName CLIENT,DC

ワークフローは Windows PowerShell コマンド (コマンドレット、スクリプト、または関数) の一種です。そのため、上記の例の最終行で実行したように、名前を呼び出すことでコマンドを実行できます。すべてのワークフローは、いくつかの組み込みのパラメーター (PSComputerName など) を継承していることを覚えておいてください。また、ワークフローでは Windows PowerShell のリモート処理機能を利用しており、この例では両方のコンピューターでリモート処理機能が有効になっています。

実用的なのは、ワークフローの両方のコマンドがリモート コンピューター上で実行され、自分のコンピューターに結果が送信されるようにできることです。このようなリモート処理を記述したり、コンピューター名を保持するパラメーターを作成する必要もありませんでした。また、コンピューター名を列挙したり、接続を作成したりする必要もありませんでした。Windows PowerShell ワークフローですべての処理が行われます。Windows PowerShell ワークフローを使わなくても、このスクリプトの内容は実現可能ですが、ユーザー側で少し作業が必要になります。

ワークフローでコマンド名を明記したことにはお気付きでしょう。また、すべてのインスタンスで名前付きパラメーターも使用しました。このようにすることは Windows PowerShell スクリプトではベスト プラクティスですが、ワークフローでは必須です。位置指定パラメーターは使用できません。すべてのパラメーターを明記する必要があり、明記しなければエラーになります。

今度は、次のワークフローを確認してください (Workflow キーワードを有効にするには、シェル インスタンスに PSWorkflow セッションをインポートする必要があります)。

Workflow New-Server { $name = Get-Content -Path Env:\COMPUTERNAME Get-Content -Path Env:\COMPUTERNAME | Out-File -FilePath C:\MyName.txt Get-NetAdapter -Physical $name | Out-File -FilePath C:\MyOtherName.txt } New-Server -PSComputerName CLIENT,DC

最初にこの例を書いたとき MyOtherName.txt は空になると考えました。ワークフローのコンテンツは、それぞれ個別のコマンドとして実行し、コンテンツ間で共有されるコンテキストがありません。しかし、この例を実行すると機能しました。コンピューター名が MyName.txt と MyOtherName.txt の両方に書き込まれましたが、どうなっているのでしょうか。

実際、Windows PowerShell では、内部で多くの処理を実行して、ワークフローで期待する結果を得られるようにしています。たとえば、"標準" のワークフロー コマンドは、かなり特殊な方法で記述されます。WF では、以前の Windows PowerShell コマンドレットをネイティブに実行することはできません。Windows PowerShell チームは、WF に対応した多数のネイティブ コマンドレットを提供しているため、多くのコマンドレットと WF アクティビティは 1 対 1 で関連付けられます。

対応するアクティビティがないコマンドレットを使用する場合、Windows PowerShell では WF の InlineScript アクティビティでコードを暗黙的にラップします。これには、WF で Windows PowerShell を実行し、Windows PowerShell 内でコマンドを実行して、WF に結果を返すという効果があります。つまり、Windows PowerShell で問題が解決されるので、機能するはずがない多くのものが機能します。

ここでの危険性は、Windows PowerShell が内部で実行している処理を常に確認できるとは限らないので、トラブルシューティングが信じられないほど困難になることです。この例の場合、Windows PowerShell によって、最上位レベルの変数が、ワークフローを通じて維持されています。

次回の内容

信じられないかもしれませんが、既に基本的なワークフローの記述を開始するのに必要な情報は提供しました。Windows PowerShell 3.0 をインストールしてリモート処理を有効にしているコンピューターを対象にワークフローを記述できます。リモート処理を有効にする 1 つの理由は、Windows PowerShell ワークフローが使用するセッション構成が作成されるからです。Windows PowerShell 2.0 がインストールされていて、後から Windows PowerShell 3.0 をインストールしたコンピューターでリモート処理を有効にする場合は、Enable-PSRemoting コマンドレットを再度実行して必要な構成を作成する必要があります。

ワークフローは、なるべくシンプルな状態に保ってください。コマンドのシーケンスを実行し、多くの凝った操作は実行しないでください。問題が発生することなく、組み込みの Windows PowerShell ワークフロー リモート処理や複数のコンピューターを対象とする機能などを活用できます。

来月は、より複雑な分野に関する説明を始めます。ワークフローと標準の Windows PowerShell スクリプトに関する難解な違いを説明し、Windows PowerShell ワークフローのより興味深い機能をいくつか紹介します。

Don Jones

Don Jones は、Windows PowerShell MVP の受賞者で、TechNet マガジンの寄稿編集者でもあります。彼は、Windows PowerShell と Windows PowerShell リモート処理を使用して HTML 形式のレポートを作成する方法について説明したいくつかの無料の書籍を含む、Windows PowerShell 3.0 について 4 冊の書籍を共同執筆しています。すべての書籍は PowerShellBooks.com (英語) で確認できます。また、PowerShell.org (英語) のディスカッション フォーラムでは、彼に質問することができます。

関連コンテンツ