2015/12/01

この記事はPowerShell Advent Calendar 2015の1日目です。

アドベントカレンダーは今年で5回目ですが、例年よりだいぶ参加者が少ないので、敢えて完走を目指さずまったりいきましょう。

とはいえ今年から来年にかけては、PowerShellの変革の年といっても過言ではないかと思います。

今年7月にはWindows 10のリリースとともに、WMF (Windows Management Framework) 5.0 / PowerShell 5.0 (2012R2/8.1向けにはProduction Preview)が登場しました。(私の書いたPS5.0新機能のセッション資料はこちら。)

PowerShell 5.0では特に、"Infrastructure as Code"、すなわちインフラの構成をコードで記述可能にし自動化するための機能である、PowerShell DSC周りが格段にパワーアップしています。DSCの機能増強により、Microsoft Azure等のクラウド、オンプレミスのサーバーはともに大きな恩恵を受けることが期待されます。Azure DSC Extensionも追従する形で凄まじい勢いでバージョンアップしてますね。

PowerShell 5.0の登場に合わせて、各種のPowerShell関係のモジュールやアプリケーションが新登場していますが、これらはいずれもOSS(オープンソースソフトウェア)となりました。

一例を挙げると、DSCで用いるロジック本体となる「DSCリソース」を作製する際に有用なDSCリソースキット、対応リポジトリをプロバイダという形で拡張可能であるパッケージ管理システムPackageManagement、PowerShellモジュールを専用リポジトリであるPowerShell Galleryからコマンド1発で取得可能となるPowerShellGet、PowerShellスクリプトの静的解析を行うスクリプトアナライザー、Windowsのみならず他プラットフォームの一括管理を目指すDSC for Linux等々です。

先日OSS化したばかりの、マルチプラットフォーム対応のコードエディタであるVisual Studio Codeと、PowerShellスクリプトが記述可能となるPowerShell Extensionあたりもトピックとして熱いですね。

Visual Studio 2015には、VSでPowerShellスクリプト開発を行うためのOSSなプラグインであるPowerShell Tools for Visual Studioが標準搭載されたことも記憶に新しいですね。(12/1追記)

逆に、PowerShellのテストスクリプトを記述するためのフレームワーク(DSL)であるPesterや、コンソールの入出力をパワーアップさせるPSReadlineといった、OSSで開発されている既存のPowerShellモジュールが、Windows 10に標準機能として取り込まれるなど、OSSとの関係性については大きく変化したと言えるでしょう。

そして次期Windows Serverである、Windows Server 2016の足音も聞こえてきました。現在はTP4が公開されており、試すことができます。Windows Server 2016の目玉は何といっても、Windows ContainersNano Serverでしょう。

アプリケーションをコンテナという単位で配置し、自由なすげ替え、あるいは使い捨てが可能な環境を構築するツールであるDockerというOSSに対し、インターフェースの互換性を持たせたWindows版コンテナがWindows Containersです。

そして、コンテナ機能を最大限に活用するためにフットプリントの最小化を目指し、GUIどころかコンソールすら廃した新しいWindows Serverの形態が、Nano Serverです。

Windows ContainersとNano Serverの管理は当然、PowerShellがメインとなります。また、ようやくWindowsにやってくる、SSHクライアントとサーバーはPowerShell上で動くようです。

PowerShellは5.0に進化することで、足回りを強化しました。そして各種OSSと連携して、クラウドとオンプレミスのサーバー群の基礎を支える存在として、ますます重要性を帯びていくことでしょう。

昨今のPowerShellを取り巻く状況は、私の理解ではざっとこんな感じです。この中に興味を持たれたテーマはありませんか? もちろん、新機能以外にも、まだまだ知られていない機能や利用法も埋もれていると思います。

もしそんなテーマがあったら、PowerShell Advent Calendar 2015で共有していただければ嬉しいなあと思います。

というわけで、例年にない感じの初日記事を書いてみました。今回のアドベントカレンダーもどうぞよろしくおねがいします。

2015/07/01

6/27、兵庫県芦屋市で開催されたAsiyan Automation Alliance 2015でのセッション資料を公開します。

Asiyan Automation Alliance 2015はその名の通り、自動化をテーマにした勉強会で、みうみう氏を中心とした運営メンバーにより開催されました。実は前年もAsian Automation Alliance 2014として兵庫県尼崎市で開催されており、今回はその続編であったようです。

実は私は芦屋市在住なんですが、地元で開催されるIT系勉強会に参加するのも、登壇するのも初めてで、中々貴重な経験でした。(単なるダジャレかと思いましたが、芦屋市民センターでのIT勉強会の開催実績は他にもあるそうです)

ちなみにAAAには前回も参加したのですが、前回はPowerShellのセッションがないからという理由で「PowerShell「再」入門2014〜short version〜」という突撃LTをしてきました(この時の資料は上げてませんが、http://winscript.jp/powershell/275と大体同じです。)。

今回は、1セッションの時間を頂けたので、改めてPowerShellを中心としたMicrosoftの提供する最新の自動化手法についてご紹介しました。割と総集編的な内容としましたが、いかがでしたでしょうか。

オンプレのWindows ServerやMicrosoft Azureはもちろん、最近はLinuxなど他プラットフォームへの浸食(?)も目立つようになってきました。この辺りの情報は非Microsoftクラスタの方にも積極的に情報提供したいと思っていますし、いろいろ情報交換させていただきたいですね。

2015/06/14

わんくま同盟大阪勉強会#63でのセッション資料を公開します。

デモで使用したサンプルスクリプトも併せてご利用ください。

わんくま同盟の勉強会は今回の大阪#63で10年目に入ったのですが、実は私も9年前の大阪#4で勉強会セッションデビューをしていたりします。

さて、今回はPowerShell DSCリソースを作成するというテーマで話しました。DSCでは管理対象ごとにロジック(リソース)と設定(Configuration)を分離でき、一貫性を持ったインフラ構成の自動化が可能になる素敵な機能です。が、いかんせん、ビルトインリソース(OS標準で含まれるリソース)の種類が少ないので、実際の業務で使うにはカスタムリソースを作成する必要が出てくると思います。

今回のデモでは、テキストファイルの中身を自動構成するという、ごく単純なサンプルを作成して実演してみましたが、考え方や実装方法の基本はこれでカバーできるのではないかと思います。

より詳しくは、ぎたぱそ氏の記事を読んでいただければ良いかと思います。本番で使えるPowerShell DSCリソース作成入門 - Build Insider

サンプルスクリプトの説明
  1. 事前準備

    今回のデモはWin10 Insider Preview(PowerShell 5.0)上で行いましたが、PowerShell 4.0環境でもおそらく動作すると思います。なお、今回のConfigurationはローカルコンピュータに対しPush適用(Start-DscConfigurationコマンドレットによる手動適用)することを想定しています。あらかじめ、DSCが実行可能な環境(スクリプト実行ポリシー、PSリモーティング、Local Configuration Managerの設定等)を整えておいてください。また、スクリプトはすべて管理者権限で実行してください。

  2. xDSCResourceDesignerのインストール

    DSCリソースのひな形を作成するためのxDSCResourceDesignerをインストールします。v5環境であればPowerShellGetを用い、Install-Module xDSCResourceDesigner で入ります。v4環境の場合はTechnetからDSC Resource KitをDLしてください。

  3. xDSCResourceDesignerの使用方法の確認

    xDSCResourceDesignerの使用方法を確認します。make_Foo_resource_template.ps1を実行すると、xDSCResourceDesignerを用いてDSCリソースFooのひな形が$env:ProgramFiles\WindowsPowerShell\Modules\TestResourceに作成されます。ひな形がどのように作成されるかを確認してください。また、Get-DscResource -Name Fooとして、DSCリソースがきちんと認識されているか、確認してください。

  4. TextFileLineリソースの作成

    今回のデモで作成したTextFileLineリソースは、make_TextFileLine_resource_template.ps1を実行してまずひな形を作成しました。作成されたひな形を用いて、TextFileLine.psm1に実際のロジックを記述し、DSCリソースを完成させました。zipに含まれるTestResourceフォルダの中身が、今回作成したDSCリソースモジュールになりますので、まずは内容を確認してみてください。特に、Set-TargetResource関数はどのように実装すると冪等性を保持して作成できるのかを念頭に置いてみてください。

  5. TextFileLineリソースの展開

    zipに含まれるTestResourceフォルダを$env:ProgramFiles\WindowsPowerShell\Modules\の下にコピーしてください。

    Get-DscResource -Name TextFileLineとしてDSCリソースが認識されていることを確認してください。

  6. TextFileLineリソースを用いたConfigurationの作成

    start_dsc_configuration.ps1に含まれる、TextFileLineTestが、今回適用してみるConfigurationになります。

    start_dsc_configuration.ps1を実行すると、ドキュメントフォルダにmofファイルを生成し、Start-DscConfigurationコマンドレットにより設定を反映させます。

    正しくConfigurationが適用されれば、ドキュメントフォルダにlist.txtというファイルが生成し、中にプログラム言語のリストが記入されているはずです。

  7. Configurationが反映されたことを確認

    Test-DscConfigurationコマンドレットを実行すると、現在の状態とConfigurationに書かれた状態が一致していればTrueと表示されます。今はConfigurationを適用した直後なのでTrueになるはずです。

    またGet-DscConfigurationコマンドレットを実行すると、現在の各プロパティの状態を表示してくれます。

    list.txtに含まれる行をテキストエディタで編集して上書きしたりすると、Test-DscConfigurationの結果はFalseになるはずです。

    list.txtを手動で変更した状態で、再度start_dsc_configuration.ps1を実行すると、再びConfiguration通りの状態に戻ると思います。その際、変更のなかったプロパティに関しては、処理がスキップされていることをログをみて確認してください。

  8. その他

    Configurationを色々書き換えて試してください。例えばEnsure="Absent"にすると対象項目が存在しない状態になります。

2015/01/06

あけましておめでとうございます。

2015年、直近の私のセッション予定について告知します。ご都合がよければ、ぜひぜひお越しくださいませ。

2015/01/31(土)

イベント:2015 MVP Community Camp大阪会場

タイトル:「PowerShellスクリプトを書いてラクしよう」

セッション概要:

コンピューター上で定型作業を手動でちまちまやるのは効率が悪いです。スクリプトを書いて自動化しましょう。幸い、最近のWindowsにはPowerShellというステキな環境が最初から入っています。これを使わない手はありませんね! PowerShellはサーバー管理の自動化ツールとして重要ですが、本セッションではPowerShellでのスクリプトの書き方を、まずは身近なテーマの具体例を交えて伝授いたします。もうすぐリリースされるv5.0の紹介もちょっとだけします。

ひとこと:

日本を含むアジアパシフィック地域で同時開催されるコミュニティイベント、2015 MVP Community Camp大阪会場で、わんくま同盟大阪勉強会代表としてセッションさせていただきます。

今回のイベントのテーマとして、最新の技術をわかりやすく、初心者や学生に伝えるというのがあります。そこで私の方からは、初心に返って、本来PowerShellがターゲットとしているサーバーOSというよりかは、クライアントOSで日常的に使えそうなスクリプトを題材に、PowerShellの紹介をしていこうと思っています。

なお、大阪会場ではJapan PowerShell User Group大阪の主催者であるwakaさんによる「PowerShellで変わるサーバ構築と管理」というセッションもあります。こちらはPowerShellによるサーバー構築、管理のお話なので、どちらかというと本筋の話だと思います。併せてぜひ、どうぞ。

2015/02/14(土)

イベント:オープンセミナー2015@広島

タイトル:「PowerShell DSCによるインフラ構成管理の自動化手法について」

セッション概要:

PowerShell Desired State Configuration(DSC)の登場により、いよいよWindows Server、Microsoft AzureでもInfrastructure as Code(インフラ構成をコード記述により自動化する手法)が可能となりました。 またWindowsのみならずLinuxなど他プラットフォームについてもDSCで横断的に構成管理を行える世界が来ようとしています。 本セッションでは、PowerShell DSCを用いた最新のMicrosoft系インフラ構成管理の手法について、間もなくリリースされる予定のPowerShell 5.0の新機能も交えて紹介したいと思います。

ひとこと:

オープンセミナー広島というIT系無料セミナーでセッションをさせていただくことになりました。2015のテーマは「クラウド時代の構成管理入門」ということで、私の方からはPowerShell DSCをキーワードに、Windows Server、Microsoft AzureといったMicrosoft系サーバー、クラウド環境の構成管理のお話をします。

これまでずっと、どちらかというとMicrosoft系のイベントばかりでセッションしてきたので、ちょっとドキドキしています。

今回のイベントでは、Chef、Docker、Ansibleなど旬のお話が聞けるので私も勉強しにいこうと思っています。ご存じのとおり、Microsoftの昨今の戦略変更で、これからはMicrosoft技術のみならず、オープンソースのソフトウェアについてもちゃんと知っておかないといけませんし!

2015/03/14(土)?

イベント:わんくま同盟大阪勉強会

タイトル:「未定」

ひとこと:

PowerShell関係で何かセッションをしようと思っています。

2012/05/14

来月6/2と6/9にPowerShell3.0のセッションをしますので告知です。

PowerShell 3.0 を使ったリモート管理(2012/06/02 わんくま同盟 大阪勉強会 #49

2月のセッションではPowerShell3.0新機能を網羅しましたが、今回はその中でも特に重要なPSリモーティングの強化ポイントを、実際に Windows8クライアントからWindows Server2012のリモートサーバーを管理するデモを交えてご紹介します。
PowerShellの基本概念をおさらいするパートもやりますので、この機会に「PowerShell再入門」してみませんか?

6/2のわんくま大阪#49では、jz5さんによるWeb APIのセッション、あおおにくんによるMonoのセッション、さおさんによるMetro+DirectXのセッションのほか、私によるPowerShell3.0のセッションがあります。PowerShell3.0を使ったリモート管理を実際のデモをまじえてご紹介します。

PowerShell 3.0 概要(2012/06/09 Community Open Day 2012 大阪会場

PowerShellはWindows Serverの管理、自動化の要となるシェル・スクリプト環境です。今年中にもリリースされるWindows Server 2012とWindows 8の登場とともに、PowerShellはバージョン3.0にアップデートされます。今回のセッションではPowerShellの基本を軽くおさらいし、3.0になって追加された新機能と改善点をご紹介します。

6/9のCommunity Open Day 2012 (COD2012)は全国のIT系コミュニティで共催されるイベントです。マイクロソフト社員の方によるキーノートから始まり、各コミュニティのスピーカーが各会場でセッションを行います。大阪会場では私は森理麟さんとわんくま同盟大阪から登壇させていただき、PowerShell3.0の新機能をすべて網羅してご紹介します。内容はbeta(間に合えばRelease Preview)対応版となります。森理麟さんはWSHなどを使ったWindowsクライアントの自動化の話、私はPowerShellでサーバー管理・自動化の話となり、わんくま大阪としては「Windows自動化」をテーマにCOD2012に参加します。

私のセッションに関しては、6/2と6/9のどちらか一方、あるいは両方聴いても楽しめるようにしたいと思っています。

ご興味のある方はぜひお越しください。会場はどちらもマイクロソフト関西支店です。

2012/03/07

3/24(土)に広島の日本マイクロソフト株式会社中四国支店で第27回.NET 勉強会 / ヒーロー島が開催されます。今回のテーマは「ハンズオンでPowerShellに触れてみよう」ということで、丸一日かけてPowerShellセッションとハンズオンが行われます。

.NET 勉強会 / ヒーロー島 - 第27回勉強会

私はこのうちハンズオンのスピーカー(進行?)を担当させていただきます。ハンズオンの前に行われるセッションにはマイクロソフトエバンジェリストの安納さんがスピーカーをされ、PowerShell概要、そして3.0のお話をしていただきます。

ハンズオンというのは通常のセッションのようにスピーカーの話を聴くのがメインのスタイルではなく、講師の指示にしたがいながら実際に自分のノートPCで操作を行い、学習を進めていく方式になります。今回はPowerShellの基本操作を学ぶハンズオンにしていきたいと考えています。

ハンズオンに参加していただくにはノートPCが必須になります。ぜひ、ご自分のノートPCをお持ちいただきますようお願いします。Windows 7でしたら特に前準備は必要ありません。Vista, XPの場合は.NET Framework 3.5 sp1以上とPowerShell 2.0をあらかじめインストールしておいていただきますようお願いいたします。Windows 8 のプレビュー版やPowerShell 3.0 beta版をさっそくインストールされている方もそのままご参加いただけます。

ハンズオン内容に関しては現在構成中ですが、もし「これをやってみたい!」というのがありましたらコメント欄やTwitterなどでご連絡いただければ、参考にさせていただきたいと思います。

お近くの方でご興味がございましたら、ぜひご参加ください!丸一日PowerShell漬けの勉強会というのはなかなかないですので!スタートメニューにある謎の(?)プログラム、この機会に触ってみませんか!それとエバンジェリストによるPowerShell 3.0話を聴けるめったにないチャンスですよ!

というわけでみなさまのご参加、お待ちしております。

2011/12/13

はじめに

この記事はPowerShell Advent Calendar 2011の13日目、そして私の2回目の記事となります。

今日のテーマは前回の続きで、PowerShellのバックグラウンドジョブの結果を読み取ったり、バックグラウンドジョブに値を与えたりして、ジョブと通信を行う方法を解説します。

ジョブから呼び出し元に値を返却する

ジョブの結果を取得するにはReceive-Jobコマンドレットを使用すれば良いと前回書きましたが、今回はジョブ側から結果を返す実際の方法を示します。

基本的にPowerShellのスクリプトやスクリプトブロックが呼び出し元に返却する値というのは、そのスクリプト(or ブロック)でパイプラインを通じて最終的にデフォルト出力に渡されたすべての値です。複数行に渡って出力されている場合は、呼び出し元にはその配列(object[])として返却されます。

ジョブにおいてもそれは同様で、基本的にStart-Jobなどで生成したスクリプトやスクリプトブロックが出力したすべての値がジョブの出力となり、呼び出し元からはReceive-Jobコマンドレットで受け取ることができます。

以下に現在の日付時刻を出力するサンプルを示します。サンプルなのでジョブなのに同期的な処理になってますがご了承を。

$job=Start-Job {
    Start-Sleep -sec 5
    Get-Date
}
Wait-Job $job|Receive-Job

複数だと以下のようになります。

$job=Start-Job {
    Start-Sleep -sec 1
    "Give me job."
    Get-Date
    1+1
}
Wait-Job $job|Receive-Job

この場合だと文字列、日付時刻、数値の3種類のオブジェクトが出力されますので、結果は長さ3のobject配列になります。そのためこれらの値を個別に取り出す場合は次のようにします。

$job=Start-Job {
    Start-Sleep -sec 1
    "Give me job."
    Get-Date
    1+1
}
$result=Wait-Job $job|Receive-Job
Write-Host $result[0]
Write-Host $result[1].ToString("yyyyMMdd")
Write-Host $result[2]

このように配列のインデックスで各値にアクセスできますが、これだと受け取り側での処理が分かりにくいと思われるかもしれませんね。

そこでお勧めなのが、このように複数値を返却するのではなく、カスタムオブジェクトを1つだけ返却するようにする方法です。

$job = Start-Job {
    Start-Sleep -sec 1
    $ret = New-Object PSObject -property @{
        String = "Give me job.";
        Date = Get-Date;
        Number = 1+1
    }
    $ret
}
$result = Wait-Job $job|Receive-Job
Write-Host $result.String
Write-Host $result.Date.ToString("yyyyMMdd")
Write-Host $result.Number

この方法ではジョブの中でNew-Objectコマンドレットでカスタムオブジェクトを作成し、それを返却しています。返却値は1つのオブジェクトでそのプロパティに値が格納されているのでドット演算子で値を参照できるようになりました。

ただしこの方法にも欠点があって、Receive-Objectで結果を参照するとき、ジョブが終了するまですべての値が参照できません。実はジョブが完了してない段階でも、Receive-Objectを実行するとジョブがそこまで出力した値を逐次取得することができるのです。よって

$job=Start-Job {
    Start-Sleep -sec 3
    "Give me job."
    Start-Sleep -sec 3
    Get-Date
    Start-Sleep -sec 3
    1+1
}

のようにしてジョブを走らせた後、適当な間隔で

$job|Receive-Job

を実行すると、それまでに出力した部分までを取得して書き出します。先程の例のように出力をカスタムオブジェクトでまとめてしまうとこの手法が使えなくなってしまいます。

どちらもメリット、デメリットがあるのでうまく使い分けると良いかと思います。具体的にはジョブの実行途中では結果を取得せず、ジョブ完了後の最終的な結果のみまとめて参照したい場合はカスタムオブジェクトで返却し、それ以外はそのまま随時値を返却するようにすればいいと思います。

さて、ジョブの結果を受け取る際にもう一点注意しなければならないことがあります。それはジョブが返すオブジェクトの型です。PowerShellのジョブ機能はリモーティング機構の上に構築されているというのは前回も書きましたが、その関係上、呼び出し元とジョブとの間でオブジェクトを受け渡しする場合は一度シリアル化され、受け取り側でデシリアライズされます。

オブジェクトのクラスもしくは構造体がシリアライズ可能(Serializable属性がついている)なら、PowerShellによりシリアル化→デシリアライズされたオブジェクトはシリアル化される前のオブジェクトと同一のものです。しかしそうではないオブジェクトの場合だと完全に元と同じオブジェクトには復元されません。

たとえば(Get-Process)[0]をジョブで実行するとSystem.Diagnostics.Processオブジェクトが得られますが、それをジョブの呼び出し元に返却するとDeserialized.System.Diagnostics.Processというカスタムオブジェクトに変換されます。このオブジェクトは各プロパティ値は(シリアル化可能なものだけ)保持しているものの、メソッド定義などは消失しているのでこのオブジェクトのメソッドを実行することはできません。

ちなみにSystem.StringクラスやSystem.Int32やSystem.DateTime構造体はSerializable属性がついているのでジョブの結果として取得しても元のオブジェクトと同一なので、メソッドなどが呼び出し可能です。

ジョブに呼び出し元の値を渡す

今度は逆の場合です。ジョブを走らせるとき、呼び出し元からジョブに値を渡す方法です。

$job = Start-Job {
    param($date,$value)
    Start-Sleep -sec 1
    "${date}の${value}日後の日付は" + $date.AddDays($value).ToString("yyyy/MM/dd") + "です。"
} -argumentList @((Get-Date),1)
Wait-Job $job|Receive-Job

このようにStart-Jobコマンドレットの-argumentListパラメータに、ジョブに渡したい値を指定すればOKです。複数ある場合はこのように配列指定も可能です。

ジョブ側ではparamキーワードで仮引数を指定しておけば、スクリプトブロック内で呼び出し元の値が格納された変数を使用できます。ここではparamを使いましたが、paramを使用しない場合は$argsに実引数が配列として格納されているので、これを利用するのでもOKです。

値を渡す場合でもシリアライズとデシリアライズが行われるので、その点だけは注意が必要です。

ジョブは呼び出し元と別インスタンスなので、呼び出し元に読み込まれた関数を参照することはできません。よってジョブでも呼び出し元で定義した関数を実行したい場合は同様に-argumentListで関数の実体であるスクリプトブロックを送ってやる必要があります。

function Get-Test
{
    "テスト!" + (1+1)
}

$job = Start-Job {
    param($sb)
    &([scriptblock]::Create($sb))
} -argumentList (Get-Item Function:\Get-Test).ScriptBlock

Wait-Job $job|Receive-Job

-argumentListでスクリプトブロックを渡すとStringにキャストされてしまうので、ジョブ内でそれをCreateメソッドでスクリプトブロックに戻してから実行演算子&で実行するという回りくどいことになってしまいました。関数にこだわらなければ呼び出し側でスクリプトブロックを作って変数に入れ、それを-argumentListに入れてやると少しだけ記述がシンプルになりますが、ジョブ内でスクリプトブロックを復元しなければならないのは同様です。

いずれにせよあんまり美しくないのでお勧めしません。こんなことをやるくらいならジョブの中あるいは -InitializationScriptパラメータの中で関数やスクリプトブロックを定義してやるか、関数を別スクリプトファイルに切り出して、そのスクリプトファイルをジョブ内で読み込むほうが良いかと思います。前者の場合だと呼び出し元とジョブ内で関数を共有することはできませんが、後者の方法だとファイルとしては分割してしまいますが可能です。

おわりに

今回はジョブと通信する方法として、ジョブから結果を出力したり、ジョブに値を渡したりする方法をまとめました。意外と落とし穴が多いので注意してください。

このシリーズはあと1回だけ続く予定です。お楽しみに。

2011/12/02

はじめに

このたび、技術系アドベントカレンダーイベントの1つとして、PowerShell Advent Calendar 2011を企画しました。この記事はその2日目の記事となります。アドベントカレンダーについてはリンク先を参照してください。

今日のテーマはPowerShellのバックグラウンドジョブ機能の使い方についてのまとめです。

バックグラウンドジョブとは

バックグラウンドジョブ機能はその名の通り、ジョブ(具体的にはスクリプト)をバックグラウンドで非同期に実行するものです。PowerShell v2で追加された機能の一つです。インタラクティブシェルでStart-Jobコマンドレットを使用してバックグラウンドジョブ(以下、単に「ジョブ」と表記)を実行すると、新しくpowershell.exeのプロセスが起動しそのままシェルに制御が戻りユーザーは後続の処理を行うことができます。もちろんスクリプトからジョブを実行することも可能です。時間のかかる処理をバックグラウンドで走らせたり、数多くの処理を並列で実行したりするのに重宝します。

起動されたジョブは操作中のpowershell.exeとは別のジョブ用のプロセスで実行され、処理が完了すると呼び出し元でその結果をReceive-Jobコマンドレットを使って受け取ることができます。ジョブは並列して何個も同時に実行できます。なおPowerShellのジョブは1ジョブ=1プロセスです。スレッドではないので注意。

PowerShellのジョブシステムはリモート処理インフラストラクチャの上に構築されているので、たとえローカルPCでもジョブ実行するにはローカルPCをリモート用構成にしておく必要があります。詳しくはabout_Remote_Requirementsを参照のこと。

ジョブはローカルでもリモートでも走らせることができます。以下に具体的な方法を述べていきます。

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

ローカルコンピュータ上に新しくジョブを作成して開始するにはStart-Jobコマンドレットを用います。

Start-Job {ジョブとして実行したいコマンド、スクリプト}

とするとジョブを実行します。

$job=Start-Job {..}

のようにするとJobオブジェクト(System.Management.Automation.PSRemotingJob)を変数に格納してあとで利用できます。変数で受けない場合はJobオブジェクトの内容が表示されます。

存在するジョブを取得するにはGet-Jobコマンドレットを用います。

Get-Job

で現在実行中のジョブ一覧を表示します。以下に出力例を示します。

Id              Name            State      HasMoreData     Location             Command
--              ----            -----      -----------     --------             -------
1               Job1            Completed  True            localhost            "test"
3               Job3            Running    True            localhost            start-sleep -sec 120;"...

以下の表は各項目の意味です。

Id ジョブID番号
Name ジョブの名前
State

Running=実行中のジョブ

Stopped=停止したジョブ

Complete=完了したジョブ

Failed=エラーが出たジョブ

HasMoreData 返却されたデータがあるかどうか
Location ジョブが実行されているコンピュータ名
Command ジョブで実行されているコマンド、スクリプト

ジョブの終了を待つにはWait-Jobコマンドレットを用います。

Get-Job|Wait-Job

とすると実行中のジョブすべてが完了するまで待ちます。-timeoutパラメータを使うと最大待ち時間(秒)を指定できます。

Get-Job|Wait-Job -any

とすると実行中のいずれかのジョブが完了するまで待ちます。正確には「対象のジョブが一つ以上完了するまで待つ」という効果なので、完了済みのジョブが1つ以上ある場合に新たにジョブを追加した場合などは想定の動作になりません。あらかじめRemove-Jobで完了済みのジョブを削除するか、Where-ObjectコマンドレットでRunningのみ対象にするようフィルタをかけるかしてください。

ジョブを中止するにはStop-Jobコマンドレットを用います。

Get-Job -id 1|Stop-Job

とするとジョブIDが1のジョブを中止します。

$jobにJobオブジェクトが格納されている場合は

$job|Stop-Job

でもOKです。

ジョブを削除するにはRemove-Jobコマンドレットを用います。

Get-Job|where {$_.state -eq "Completed" -or $_.state -eq "Stopped"}|Remove-Job

とすると完了済みと中止したジョブを削除します。実行中のジョブは削除できませんが-forceパラメータを使って強制削除することは可能です。

ジョブの実行結果データを取得するにはReceive-Jobコマンドレットを用います。

Get-Job|Receive-Job

とすると完了済みのジョブのうち、結果を返却しているもの(HasMoreDataがTrueのジョブ)があればその結果を表示します。-keepパラメータをつければ結果データを保持しますが付けてない場合は参照後破棄します。

*-Job系のコマンドレットの多くはJobオブジェクトを返却するので、パイプラインでどんどん繋げていけます。

Get-Job|Wait-Job -timeout 10|Receive-Job

のように。

ジョブの基本的な使い方に関して詳しくはabout_jobsを参照してください。

イベントサブスクライブ

PowerShell 2.0では.NET Frameworkのオブジェクトのイベントをサブスクライブすることができます。すなわちイベントハンドラを記述することができます。このイベントサブスクライブ機能もジョブ機能を元に構築されています。

たとえばTimerオブジェクトのElapsedイベントをサブスクライブし、タイマーの実行間隔(ここでは1秒)ごとにtest.txtファイルに乱数を追記していくサンプルは次のようになります。

$timer=new-object System.Timers.Timer
$timer.Interval=1000
Register-ObjectEvent -EventName Elapsed -SourceIdentifier test -Action {get-random|add-content c:\users\daisuke\test.txt} -InputObject $timer
$timer.Enabled=$true

Register-ObjectEventの結果、新しくジョブが生成しそのJobオブジェクトが返却されます。このジョブは-EventNameパラメータで指定したイベントが発生するたび、-Actionパラメータで指定したスクリプトブロックを実行します。

なお、イベントサブスクライブを解除するには

Unregister-Event test

のように-SourceIdentifierパラメータで指定した値を指定してUnregister-Eventコマンドレットを実行することで可能です。サブスクライブを解除してもジョブ自体は削除されない(StateがStoppedになるだけ)ので、必要であればRemove-Jobで削除します。

なお.NETオブジェクトの他にPowerShellスクリプトのカスタムイベント(Register-EngineEvent)、WMIオブジェクトのイベント(Register-WmiEvent)をサブスクライブすることもできます。これらのコマンドレットも同様にイベント発生時の処理をジョブとして登録します。詳しくは各コマンドレットのヘルプを参照してください。

リモートコンピュータでのジョブ実行

最初に述べたとおりPowerShellのジョブ機能はリモートインフラストラクチャの上に構築されています。よってローカルのみならずリモートコンピュータに対してジョブを実行することができます。もちろんリモートコンピュータにもリモート構成されていることが条件です。

基本はInvoke-Commandコマンドレットを用い、

$job=Invoke-Command -ComputerName リモートコンピュータ名 {リモートで実行するコマンド、スクリプト} -asjob

となります。これで{}内の処理がリモートコンピュータ上のPowerShellインスタンスで実行されます。-asJobパラメータをつけることでジョブとして(ローカルPCから見て)非同期に処理できますが、-asJobパラメータを省略すると同期的に実行されます。この場合ジョブは作成されず、リモートでの処理が終了するまでローカル側は待機することになります。

リモートコンピュータに接続するための資格情報を別途入力する必要がある場合は-credentialパラメータを使用します。

Invoke-Command -ComputerName リモートコンピュータ名 {リモートで実行するコマンド、スクリプト} -asjob -credential ユーザー名

とするとパスワードを入力するダイアログが表示されます。なお、スクリプトで動かすときなどあらかじめ入力したパスワードを指定したい場合の方法は以前書きました

同じコマンドを複数のリモートPCで同時実行することも可能で、その場合は-computerNameパラメータにリモートコンピュータ名の配列を指定します(「,」区切り)。この場合ローカルPCで見えるジョブとしては1つですが、そのジョブにリモートコンピュータの数だけ子ジョブ(ChildJobs)が作成されています。

このように子ジョブが複数ある場合にReceive-Jobするときは

$job|Receive-Job -location リモートコンピュータ名

あるいは

$job.ChildJobs

として表示される子ジョブの名前(Name)を調べ、

Receive-Job -name 子ジョブの名前

とすることでリモートコンピュータごとに結果を取得できます。

すべての結果をまとめて取得するなら

Receive-Job $job

とします。

$job|Receive-Jobはなぜか駄目なようです。

固定セッションを用いたリモーティング

同じリモートPCに対して何度もコマンドを実行させたい場合、毎回リモートコンピュータ名を指定してセッションを張るのは非効率的なので、リモートセッションを確立したあとその固定セッションを何度も使用する方法が用意されています。新しく固定セッションを確立するにはNew-PSSessionコマンドレットを用い、

$session=New-PSSession リモートコンピュータ名

とすると固定セッションが確立され、$session変数にそのセッションオブジェクトが格納されます。あとは

Invoke-Command $session {リモートで実行するコマンド、スクリプト} -asjob

とすればそのたびにそのセッションを用いてリモートでコマンドを実行できるようになります。

ここまでの説明はリモートコンピュータでしてきましたが、ローカルコンピュータに対して固定セッションを張ることも可能です。

さらに、Enter-PSSessionコマンドレットを用いると作成したセッションに入ってリモートコンピュータ上のPowerShellを対話実行することも可能です。

Enter-PSSession $session

とすると、プロンプトが

PS カレントディレクトリ>

から

[リモートコンピュータ名]: PS カレントディレクトリ> 

に変化し、以降リモートのPowerShellをローカルPCから対話実行できます。

なおこの状態から抜けるにはexitもしくはExit-PSSessionと入力して実行します。

ジョブ実行できるそのほかのコマンドレット

これまで述べたコマンドレット以外にも、いくつかのコマンドレットはジョブ実行(ローカルorリモート)することができます。ジョブ実行するには-asJobパラメータを使用します。以下にv2の段階で-asJobパラメータが定義されているそのほかのコマンドレットを示します。

これらのコマンドレットはコマンドレット自体にジョブ実行機能がついているので、単独で実行するだけならStart-JobやInvoke-Commandを用いる必要がありません。v2ではWMIを扱うコマンドレットにのみ-asJobパラメータが存在するようです(ここに挙げたコマンドレットはすべてWMIの機能を呼び出すもの)。なお、-asJobパラメータが使用できるコマンドレットの一覧を取得するのに、fsugiyamaさんの1日目の記事の問15のスクリプトを使用させていただきました。

おわりに

PowerShell Advent Calendar 2011二日目は、PowerShellのバックグラウンドジョブ機能概要についてまとめてみました。実はバックグランドジョブ機能のTipsを書こうと思ってその前ふりとして書き始めたのですが、これだけでかなりの量になってしまったので概要だけ一記事としてまとめることにしました。おそらくPSアドベントカレンダーに私はあと何回か登場することになりそうですので、Tips編はその際に書こうと思います。

さて、明日三日目は@jsakamotoさんのご登場ですね。よろしくお願いします!

そして参加者はまだまだ募集中ですよ!→PowerShell Advent Calendar 2011

2011/11/14

PowerShell Advent Calendar 2011というイベントを12/1より開催します。
こちら:PowerShell Advent Calendar 2011 : ATND

現在、参加者募集中です。

以下はイベント告知ページのコピペです。

概要

今年はPowerShellもAdvent Calendarをやりましょう!
Advent Calendarとは技術系コミュニティで行われるイベントの一つで、ある特定技術分野をテーマに、12/1から12/25までの25日間、参加者が交代で毎日ブログ記事を書いてクリスマスを迎えるイベントです。

ルール

PowerShell Advent Calendar 2011ではその名の通り、Windows PowerShellに関する記事を参加者みんなで書いていきます。Tips、コード、等々、PowerShellに関する内容であれば何でもOKです。基本的にATNDの参加表明順が執筆担当日になります。たとえば5番目に参加表明した方は12/5の記事を執筆します。参加者の方は担当日に記事をご自分のブログに書いていただき、そのURLをコメント欄に書いてください。都合で担当日に投稿できない、担当日を変えてほしいなどがありましたらコメント欄でお願いします。

参加者が25人に達した時点で締切りです。逆に期日までに参加者が現れない場合は、すでに執筆した参加者が再度執筆しても良いこととします(その場合はコメント欄で宣言を)。

あなたの参加、お待ちしています!
ぜひがんばって完走させましょう!

参考記事

ここまでコピペでした。

まだ参加希望者が少ないのですが、ぜひぜひ、ご参加くださいませ。お題はPowerShellがからんでいれば何でもOKです。PowerShellを触ってみた感想とか、試しにこういうコマンドを実行してみたorコードを試しに書いてみた、など何でも結構です。Advent Calendarはゆるふわなイベントなのであまり身構えず気軽にご参加いただけると嬉しいです。

元記事:http://blogs.wankuma.com/mutaguchi/archive/2011/11/14/212019.aspx

2008/02/19

先日エルおおさかで行われたわんくま勉強会におこし頂きありがとうございました。

ご報告が遅れましたがレポートです。

ふたコマいただいたんですが、ひとコマ目は音楽とDTM(MIDI)の基礎のお話をやりました。ドレミとは、音符とは、音階とは、和音とは、とかごく基礎のところを触れただけなので初心者の方には喜んでいただけたようですが、上級者の方には物足りなかったようで少し工夫をすべきでしたね。

後半はテキスト音楽「サクラ」を用いて実際に曲を作るところを3分間クッキング形式でどんどん作っていきました(実際はデータ作成に7,8時間かかっています)。なにより、ずったずったでドラムを打ち込めるところがウケてましたねwミク講演といっておきながらよく考えるとオケを作る方が時間かかるので実質サクラ講演に近くなってしまいました。でもミクの歌唱力に驚いた方もいらっしゃったようでよかったかなと。ミクの濃い話は私はちょっと無理なのでできればどなたかやっていただけると嬉しいなぁ、と思ったり。ミク単体で歌わせるのもいいですが、オケをつけるとぐっと「それっぽく」なることが示せたかな、と思います。

Audacityのファイルが壊れていた原因はよくわからないのですが、制作環境とデモ環境が違うといろいろ問題のようですね。どこかのファイルが絶対パスでデータを持ってたのが原因みたいです。一回デモ機でやったときはうまくいったんですけどねー?古いファイルを上書きしたのかも?

でもミク&サクラでこれだけのことができるということが示せてよかったように思います。アンケートもおおむね高評価をいただきました。ありがとうございます。これを機にDTMやってみよう、あるいは再開してみよう、サクラを触ってみようという方が結構おられたのがうれしかったです。あとミクのかわいい絵をアンケートに描いてくれた方どうもありがとうございますv

DTMと化学とスクリプトの関係は何かあるのかと聞かれたんですがとくにないですw

春編夏編とか、応用編とか、DTM本執筆とかわんくまテーマソング作曲とかいろいろ振られたんですけどごめんなさい、当分実現しそうにないですw

あと私の講演がやまにょんの濃いー講演にうまくつながったようでよかったです。私だけの話だと物足りなかった方もいたようですし。やまにょん遠いところからありがとー

 

講演資料、データ(完成版、作りかけのも含む)は一足先に自宅サーバーで公開しておきます。

mutaの作った音楽
http://winscript.jp/music/ (下の方)

ソフトのDL・紹介サイト

テキスト音楽「サクラ」 http://oto.chu.jp/

VOCALOID2 初音ミクhttp://www.crypton.co.jp/mp/pages/prod/vocaloid/cv01.jsp

Audacity http://audacity.sourceforge.net/

 

追伸。

この講演はまぁ、ちゃっぴさんが私をそそのかしたことがきっかけで実現したんですが、実はちゃっぴさんから贈り物が届いていました。最後にちょっとだけみなさんにお見せしたんですけど家で写真撮りました。

080219-092146

こんなメッセージが入っていました。これ会場で読むべきだったんですがてんぱってて読めませんでした、ごめんなさい

080219-092500

えーと。これ、「式場 エルおおさか」 で届いたんですけど・・・wwwww

というか、これはあれですね、結婚したいしたいと某所でわめいていた私に、じゃあミクと結婚しちゃえばというちゃっぴ先生のきっついシャレですなw

 

というわけで、みなさんどうもありがとうございました。

次回は3/29 PowerShellの話をやりますのでよろしくお願いします。

元記事:http://blogs.wankuma.com/mutaguchi/archive/2008/02/19/123810.aspx

古い記事のページへ |


Copyright © 2005-2018 Daisuke Mutaguchi All rights reserved
mailto: mutaguchi at roy.hi-ho.ne.jp
プライバシーポリシー

Books

Twitter