Slide 1

Slide 1 text

”オブジェクト”から学ぶ PowerShell 2016/04/23 CLR/H #99 ~サクラサク~ 素敵なおひげ

Slide 2

Slide 2 text

自己紹介  素敵なおひげ ◦Twitter - @stknohg ◦Blog - http://stknohg.hatenablog.jp/  何者? ◦CLR/HとJAZUG札幌(きたあず)の裏方です。 ◦札幌市内のSI屋さんで働いてます。 ◦PowerShell絶賛勉強中! 2

Slide 3

Slide 3 text

はじめに PowerShellは”オブジェクト“を扱う シェルです。 今日はこの”オブジェクト“を通して PowerShellの基本的な仕組みを 学びます。 3

Slide 4

Slide 4 text

アジェンダ 1.PowerShellのオブジェクト 2.ストリームと標準入出力 3.コマンドレット 4.PowerShellのパイプライン 5.オブジェクトの出力 4

Slide 5

Slide 5 text

本セッションでやらないこと PowerShellの文法に関すること ◦細かい文法には触れません スクリプトの書き方に関すること ◦コーディングはしません コマンドの機能説明 ◦個別の機能説明はしません 5

Slide 6

Slide 6 text

1. PowerShellのオブジェクト 6

Slide 7

Slide 7 text

他シェルとの比較  PowerShellはオブジェクトを扱うシェル  簡単なスクリプトで、 ◦コマンドプロンプト(cmd.exe) ◦Bash ◦PowerShell の三者の違いを比較する 7

Slide 8

Slide 8 text

コマンドプロンプト(cmd.exe)  実行結果 8 > SET Now=%DATE% > echo %Now%

Slide 9

Slide 9 text

コマンドプロンプト(cmd.exe) 1. %DATE%環境変数に設定されている 文字列の日付を%Now%変数に代入 2. echoコマンドで%Now%変数の内容を 標準出力に出力 3. 出力結果がそのままコンソールに 表示される 9

Slide 10

Slide 10 text

Bash  実行結果 10 # Now=`date` # echo $Now

Slide 11

Slide 11 text

Bash 1. dateコマンドを実行し、結果の文字列 を変数$Nowに代入 2. echoコマンドで$Now変数の内容を 標準出力に出力 3. 出力結果がそのままコンソールに 表示される 11

Slide 12

Slide 12 text

PowerShell  実行結果 12 > $Now = Get-Date > Write-Output $Now

Slide 13

Slide 13 text

PowerShell 1. Get-Dateコマンドレットを実行し、 System.DateTime型の結果を$Now変数 に代入 2. Write-Outputコマンドレットで$Now変数 の内容を出力ストリームに出力 3. 出力結果が文字列としてコンソールに 表示される 13

Slide 14

Slide 14 text

PowerShell  オブジェクトなのでメソッドも呼べる  また、従来のSystem.DateTime型には無い プロパティを持っていたりする 14 # AddDaysメソッドを呼び出して翌日の日付を取得 $Tomorrow = $Now.AddDays(1) Write-Output $Tomorrow # 本来System.DateTime型のオブジェクトには無い # DisplayHintプロパティを使用することができる Write-Output $Now.DisplayHint

Slide 15

Slide 15 text

PowerShellのオブジェクト  PowerShellでは.NET Frameworkの型を もつオブジェクトを扱う  純粋な.NET Frameworkのオブジェクトとは 異なり独自のプロパティを拡張可能(ETS)  そして、.NET Frameworkをベースにして ◦ WMI ◦ COM ◦ ADSI ◦ ADO.NET ◦ XML など のオブジェクトを統一的に扱える(ATS) 15 ※本セッションではETS/ATSの詳細には触れません

Slide 16

Slide 16 text

PowerShellのオブジェクト PSObject ◦ [System.Management.Automation.PSObject] ◦ PowerShellで扱うオブジェクトの実体 ◦ [System.Object]の様な基底クラスではない 実際のオブジェクトインスタンスを内包する 委譲モデル  PSObjectは PowerShellの利用者には隠蔽されている 16 ※PowerShellの深淵を見ることになるので、 PSObjectの詳細には触れません!

Slide 17

Slide 17 text

2. ストリームと標準入出力 17

Slide 18

Slide 18 text

ストリームと標準入出力  PowerShellのストリーム ◦ PowerShellではオブジェクトを入出力するため、 他のシェルとは異なり標準入出力に相当する 部分はストリームと呼ばれる  ストリームと標準入出力 ◦ ストリームと標準入出力は似ているが別物 ◦ PowerShellと外部のExeが連携する場合、 ストリーム(オブジェクト) ⇔ 標準入出力(テキスト) の変換が発生する 18

Slide 19

Slide 19 text

PowerShellのストリーム ストリーム リダイレクト 出力方法 Version 特記事項 Input - - All 標準入力に相当 Standard output 1> Write-Output など All 標準出力に相当 “出力ストリーム” Error output 2> Write-Error All 標準エラー出力に相当 “エラーストリーム” Warning output 3> Write-Waring 3.0以上 Verbose output 4> Write-Verbose 3.0以上 Debug output 5> Write-Debug 3.0以上 Information 6> Write- Information 5.0以上 Write-Hostの結果が ストリームに乗る様に Progress - Write-Progress All 19

Slide 20

Slide 20 text

ストリーム標準入出力  PowerShell → 外部Exe ◦ コンソールに表示される文字列を 標準入力へ渡す ◦ $OutputEncoding で設定されている エンコーディング(デフォルト ASCII)でエンコード ◦ 最後に必ず改行(CRLF)が付く  外部Exe → PowerShell ◦ 標準出力を文字列([stirng[]]型)に変換 ◦ [Console]::OutputEncoding で設定されている エンコーディング(デフォルト MS932)でエンコード ◦ バイナリ出力も文字列化される 20

Slide 21

Slide 21 text

全体像 21 http://stknohg.hatenablog.jp/entry/2015/06/26/001944 より

Slide 22

Slide 22 text

3. コマンドレット 22

Slide 23

Slide 23 text

PowerShellのコマンド  PowerShellは他のシェルと違い、 コマンドによる入出力はテキスト ではなくオブジェクトになる  このため、PowerShellには オブジェクトを入出力する独自の コマンド体系(コマンドレット) が存在する 23

Slide 24

Slide 24 text

コマンドレット(Cmdlet)とは  簡単に言うとPowerShellの内部コマンド ◦ 組み込み済み+自作可能  実体は.NET Frameworkのクラス ◦ [System.Management.Automation.Cmdlet] クラスを継承したもの  格納単位はスナップインまたはモジュール (Dll or psm1) ◦ ただし、スナップインはもうほとんど使われない ◦ モジュールだけ覚えておけば良い 24

Slide 25

Slide 25 text

コマンドレット(Cmdlet)の例 25

Slide 26

Slide 26 text

関数(ファンクション)  PowerShellではコマンドレットのほか に関数(ファンクション)を定義できる  関数には用途に応じた複数の種類 がある 26

Slide 27

Slide 27 text

関数(ファンクション)の種類 1. 関数(ファンクション) 通常の関数 2. 高度な関数 PowerShell 2.0から利用可能 ファンクションにコマンドレットと同等の属性を付ける 事ができる様になったもの 3. フィルター パイプラインでパイプすることを前提とした簡易的な関数 4. ワークフロー PowerShell 3.0から利用可能 ワークフロー用の特殊な関数 27 ※本セッションではワークフローには触れません

Slide 28

Slide 28 text

関数(ファンクション)の例 1. 関数 3. フィルター 2. 高度な関数 28

Slide 29

Slide 29 text

(補足) コマンドレットの命名規則  コマンドレットには [Verb]-[Noun] な 命名規則が採用されている ◦ 例) Write-Output  [Verb]については”Get-Verb”コマンドレット で使用すべき動詞を取得できる ◦ 使用すべきでない動詞を使ったモジュールを 公開すると警告が出る  [Noun]については自由 29

Slide 30

Slide 30 text

(補足) コマンドレットの命名規則  これは “コマンドレット” に対する規則 なので “関数” は従わなくても問題ない  ただし、従った方が統一感が出て良い ◦ 私見では公開する関数は [Verb]-[Noun]な名前にするのが良いと考える 30

Slide 31

Slide 31 text

4. PowerShellのパイプライン 31

Slide 32

Slide 32 text

PowerShellのパイプライン  PowerShellは他のシェルと違い、 標準出力に相当する出力ストリーム にはテキストでなくオブジェクトが 出力される  このため、パイプラインを使う場合は オブジェクトがパイプされる 32

Slide 33

Slide 33 text

PowerShellのパイプライン  オブジェクトパイプライン  1オブジェクトずつパイプされる ◦ 配列などのコレクションは要素ごとに展開される ◦ 配列の配列は展開されない  実行例 33 @(1,2,@(3,4),5) | ` % { Write-Host “$($_.GetType())型の値 $($_) がパイプされました…”}

Slide 34

Slide 34 text

PowerShellのパイプライン  3つのブロック ◦Begin 最初のオブジェクトがパイプされる直前に呼び出される ◦Process 各オブジェクトがパイプされる毎に呼びされる ◦End 最後のオブジェクトがパイプされた後に呼び出される 34

Slide 35

Slide 35 text

PowerShellのパイプライン  動作例 35 > @(1..5) | Command1 | Command2 Command1 Command2 Begin Process End Begin Process End Int[] 配列 1 2 3 4 5 1 2 3 4 5 6

Slide 36

Slide 36 text

(比較) bashのパイプライン  Pipeシステムコールでプロセスは並列実行  入出力はテキスト(バイナリ)をストリーミング ◦ OS毎に異なるバッファサイズ 36 Process1 Process2 pipe write read

Slide 37

Slide 37 text

5. オブジェクトの出力 37

Slide 38

Slide 38 text

コンソールに文字が出るということ  PowerShellは他のシェルと違い、 標準出力に相当する出力ストリームには テキストでなくオブジェクトが出力される (2回目)  このため、コンソールに文字を出すため には何らかの方法で、 オブジェクト ⇒ 文字列への変換 を行う必要がある 38

Slide 39

Slide 39 text

Write(Get) | Format | Out  PowerShellではストリームに出力された オブジェクトは原則、 1. Format-*なコマンドレットによって 表示書式が設定され 2. Out-*なコマンドレットによって コンソールやファイル等へ文字列の 最終出力が行われる  これらのコマンドレットは明示的または 暗黙的にパイプラインでパイプされる 39

Slide 40

Slide 40 text

Write(Get) | Format | Out  明示的な実行例  暗黙的な実行例 40 # Get-ChildItem(ls)の実行例 Get-ChildItem | Format-Wide | Out-Host # Out-* を明示しない場合 Get-ChildItem | Format-Wide # Format-* Out-* を明示しない場合 Get-ChildItem

Slide 41

Slide 41 text

Format-*なコマンドレット 名称 表示形式 特記事項 Format-List リスト形式 Format-Table 表形式 Format-Wide 複数列形式 Format-Custom 独自の表示形式 Update-FormatDataで 書式を設定 Format-Defualt 既定の フォーマット PowerShell内部用 Format-*を明示しない場合 に内部的に使用される 41

Slide 42

Slide 42 text

既定のフォーマット Format-Default  既定の書式指定を行う  PowerShell内部用でユーザーは利用 できない  Format-*なコマンドレットを明示しない 場合にOut-*なコマンドレットの内部で 呼び出されている ※一部例外あり 42

Slide 43

Slide 43 text

format.ps1xml  各オブジェクト(型)が既定でどの様な 表示書式を持つかは、 *.format.ps1xml というXMLファイルに定義されている  このXMLファイルはpowershell.exeと同じ ディレクトリに存在  このXMLファイルは編集不可 ◦ 署名付きXML 43 ※本セッションでは詳細には触れません

Slide 44

Slide 44 text

Out-*なコマンドレット 名称 出力先 特記事項 Out-Host ホスト(=実行環境) PowerShellコンソール、 PowerShell ISEなど Out-File ファイル Out-GridView グリッド形式のウィンドウ Foramt-*からパイプすると エラーになる Out-Null 出力なし /dev/null に相当 Out-Printer プリンター Out-String 書式設定されたオブジェクト を文字列に変換し出力 これだけ例外的に後続に パイプすることが可能 Out-Default 既定の出力 Out-Hostと同等 Out-*を明示しない場合に 暗黙的に呼び出される 44

Slide 45

Slide 45 text

既定の出力 Out-Default  既定の出力先  出力先は基本的にホストとなる (≒Out-Hostと考えてよい)  Out-*を明示しない場合、 PowerShell内部で自動的にパイプライン の最後に Out-Default が追加される 45 Get-ChildItem # ↓ PowerShell内部で(| Out-Default)を追加 Get-ChildItem | Out-Default

Slide 46

Slide 46 text

まとめ 1. PowerShellは.NET Frameworkの型をベース としたオブジェクトを扱う 2. PowerShellでは標準入出力に相当するもの はストリームと呼ばれ、オブジェクトを入出力 する 3. PowerShellのコマンドと関数はオブジェクトを 扱う 4. PowerShellのパイプラインはオブジェクトを パイプする 5. PowerShellのオブジェクトはFormat-*なコマン ドレットにより書式指定され、Out-*なコマンド レットで文字列として最終出力される 46

Slide 47

Slide 47 text

参考資料  Windows PowerShell Language Specification Version 3.0 ◦ https://www.microsoft.com/en-us/download/details.aspx?id=36389  PSObject and the Adapted and Extended Type Systems (ATS and ETS) ◦ https://blogs.msdn.microsoft.com/besidethepoint/2011/11/22/psobject-and-the-adapted- and-extended-type-systems-ats-and-ets/  PowerShellのストリームと標準入出力、リダイレクトとパイプラインの話 ◦ http://stknohg.hatenablog.jp/entry/2015/06/26/001944  Windows PowerShell: 高度な関数のライフサイクル ◦ https://technet.microsoft.com/ja-jp/magazine/hh413265.aspx  Write-HostとWrite-Outputの違い ◦ http://stknohg.hatenablog.jp/entry/2016/01/11/151201  about_Format.ps1xml ◦ https://technet.microsoft.com/ja-jp/library/hh847831.aspx 47

Slide 48

Slide 48 text

48 ご清聴ありがとうございました