しばたテックブログ

気分で書いている技術ブログです。

CLR/H #clrh99 ~サクラサク~ でPowerShellについて話してきました

先日行われたCLR/H #clrh99 ~サクラサク~で久しぶりに勉強会で登壇しました。

clrh.connpass.com

勉強会について

登壇した時間以外は受付か懇親会の手配をしていたので他のセッションは全然見れませんでした...スイマセン
いつも通りえんぷらさんがTogetterにまとめてくれてるのでこちらで勉強会の雰囲気は伝わるかと思います。

togetter.com

発表資料もこちらにまとまってますのでぜひご覧ください。

"オブジェクト"から学ぶPowerShell

"オブジェクト"から学ぶPowerShell」というタイトルでPowerShellのシェルとしての機能や仕組みついて説明させてもらいました。

セッション中に出したソースコードについてはGithub上で公開しています。

github.com

全体を通して伝えたかったのは、PowerShellはコマンドプロンプトや*shといったテキストベースのシェルとは違いオブジェクトベースであり、それがPowerShell独特の仕組みや機能につながっているという点になります。

以下、セッション後に頂いた質問やTwitterでの反応について幾つか補足しておきます。

ETSとATSについて

PowerShellの型システムの基本であるExtended Type System (ETS)とAdapted Type System (ATS)の詳細については以下の記事に詳しく記載されています。
英語の記事ですが気合で読むとPowerShellへの理解が深まると思います。このへんの話も後日ブログにまとめていきたいですね。

blogs.msdn.microsoft.com

また、プロパティの拡張についてはあえとすさんのこちらの記事がとても詳しいので必見です。

tech.blog.aerie.jp

ストリームについて

ストリームについてはこの過去記事の内容をベースにしています。

stknohg.hatenablog.jp

パイプラインについて

パイプラインについてはサラッとした説明で終わらせてしまいましたが、パイプラインはPowerShellのキモであり、そしてかなり独特の挙動をします。
時間が足りずセッション中には使えなかったのですが、ぜひ以下のサンプルコードを動かして実際の挙動を確かめてみてください。

#
# パイプラインのテスト用コマンド1
#
function Command1
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)]
        $InputObject
    )
    Begin
    {
        Write-Host "Command1 Begin($InputObject)..." -ForegroundColor Green
    }
    Process
    {
        Write-Host "Command1 Process($InputObject)..." -ForegroundColor Green
        Write-Output $InputObject
    }
    End
    {
        Write-Host "Command1 End($InputObject)." -ForegroundColor Green
    }
}

#
# パイプラインのテスト用コマンド2
#
function Command2
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)]
        $InputObject
    )
    Begin
    {
        Write-Host "Command2 Begin($InputObject)..." -ForegroundColor Yellow
    }
    Process
    {
        Write-Host "Command2 Process($InputObject)..." -ForegroundColor Yellow
        Write-Output $InputObject
    }
    End
    {
        Write-Host "Command2 End($InputObject)." -ForegroundColor Yellow
    }
}

#
# パイプラインのテスト
#
@(1..5) | Command1 | Command2

サンプルを動かすとこんな結果になります。
BeginProcessEndブロックがどういった順番で呼ばれるか確認してください。

オブジェクトの出力について

オブジェクトの出力についてはこの過去記事の内容をベースにしています。

stknohg.hatenablog.jp

Format-*およびOut-*を明示、または省略した場合の動作の説明が少し分かりにくかったと思うので補足の図を描きました。

ただOut-GridViewだけは入力データに書式指定する前のオブジェクトが必要なため例外的な挙動をするので注意が必要です。

PowerShellの使いどころについて

セッション終了後にさかもとさんから頂いた質問についてですが、私がPowerShellを使うのは、

  • Windows Serverの構築と設定
  • ちょっとした定型処理
  • VBScriptの置き換え

あたりが多いです。

メインの用途はサーバー構築ですが、まだPowerShell DSCは実践投入しておらず秘伝のスクリプトファイルで頑張っている感じです。
それでもWindows Server 2012から組み込みコマンドレットの数も圧倒的に増えほとんどの作業をNon-GUIで行う事ができる様になったので生産性はいい感じに上がっています。
これだけでも十分PowerShellを学ぶコストに見合うだけの利益を得ています。

加えて個人的にPowerShellを絶対使うべきだとお勧めしたいのはWMIを扱う時ですね。
従来WMIをプログラムから扱うにはVBScriptやC#を使っていたと思いますがそれなりに面倒だったかと思います。
対してPowerShellの、特にGet-WmiObjectGet-CimInstanceコマンドレットのお手軽さは圧倒的です。

最後に

久しぶりの登壇で死ぬほど緊張しましたが話せて良かったです。
この発表の内容で少しでもみなさんのPowerShellに対する理解を深めることができれば幸いです。