「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>PowerShell]] * 目次 [#a65a66fe] #contents * 概要 [#c192162a] 以前から、オブジェクトベースのプログラム、スクリプト(perl、[[WSH>VBS]])などは存在したが、~ PowerShellが唯一のオブジェクト・ベースのシェル(perlに似ている)である。~ # OSレイヤから少々遠いため[[シェル]]というより[[シェルスクリプト>スクリプティング]]という意見もある。 *詳細 [#gf337538] **テキストベースからオブジェクトベースへ。 [#z99a6bd1] 皆、 -テキストベースの[[シェル]]と -オブジェクトベースの[[シェル]]の 違いに混乱する。 -パイプで渡せる型はある。 -パイプで何が渡るかはGet-Memberコマンドレット調べる~ http://mojibake.seesaa.net/article/53585441.html --[[シェル]]だが、プログラム、スクリプト(perl)のような仕様。 --変数、配列、Property、Method(.NETライク)、また、~ 無名関数、delegate、検索条件をラムダ式的に・・・なども可能。~ Like This ↓パイプ ↓ラムダ式的な get-service | where-object {$_.Status -eq "Running"} パイプしなくてもキャスト(暗黙)でつなげられる。 **オブジェクトのパイプラインとは? [#cac4db70] -Unix/Linuxのshellコマンドや、Windowsのコマンドプロンプトでも、~ 「|」を使って、コマンドを複数並べてパイプラインが記述できます。 -ですが、それらは、標準出力のテキストを次のコマンドの標準入力へ渡す、にすぎません。 -PowerShellでは、PowerShellのオブジェクトをパイプで渡すことができます。 --そして、ほとんどのPowerShellコマンドがオブジェクトを出力します。 --また、オブジェクトには、多くのプロパティを含んでいます。 --後処理のために、オブジェクトにプロパティを追加することもできます。 --このため、プロパティを判定してフィルタしたり、プロパティを使ってソートできます。 --最後に Format-List や Format-Table などのコマンドを使って、一部のプロパティを整形して表示します。 -.ps1スクリプト内で定義する関数(function)や、自作のCmdletでも、~ オブジェクトを返すようにしておくと、再利用しやすくなります。 -パイプラインの例は、~ 後述の [[オブジェクトへメンバー追加>#pbe1b175]] の例を参照ください。 -パイプラインの詳細は、~ PowerShellコマンドプロンプトで「get-help about_pipeline」を参照ください。 **オブジェクトへメンバー追加する。 [#pbe1b175] -PowerShellでは、Add-Member を使って、オブジェクトに動的にメンバーを追加できます。 -OSや他のライブラリが返したオブジェクトに、情報を追加しながら、~ パイプラインを使って、順次処理する。といったことができます。~ ***スクリプト [#l3010bb9] function dirinfo { param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [object]$dir, [boolean]$totalup = $false ) # 空っぽの配列 $dirs = @() # $dir へ プロパティ追加 $dir | Add-Member -MemberType NoteProperty -Name TotalFiles -Value 0 $dir | Add-Member -MemberType NoteProperty -Name TotalSize -Value 0 foreach ($f in (get-childitem $dir.FullName)) { if ( $f.Attributes -band [System.IO.FileAttributes]::Directory ) { # サブフォルダの情報 $ret = dirinfo $f $totalup if ( $totalup ) { # 末尾の情報を $dir へ加算 $dir.TotalFiles += $ret[-1].TotalFiles $dir.TotalSize += $ret[-1].TotalSize } $dirs += $ret # サブフォルダ全体を覚える } else { $dir.TotalFiles += 1 $dir.TotalSize += $f.Length $dirs += $f } } $dirs += $dir # $dir自身を末尾に覚える # 覚えたものをまとめて返す write-output $dirs } ***実行例 [#k8ba911b] -実行例のパイプライン dirinfo (get-item "c:\program files") | sort-object totalsize -Descending | where { $_.TotalSize -gt 1 } | select-object -first 5 | format-list -Property TotalFiles, TotalSize, Fullname (行は折り返して表示しています。実行する際は、1行に入力してください。) -ココでは、以下のことをしています > +get-item で C:\Program Files フォルダのオブジェクトを取得して、~ +dirinfo でサブフォルダのサイズを集計、~ +sort-obejct で TotalSize の大きい順に並び替えて、~ +where で TotalSize が 1以上のオブジェクトだけ抽出して、~ +select-object で 最初の 5 個だけ取り出し、~ +format-list で 特定のプロパティのみ表示。 *参考 [#e644e1b9] -PowerShell:Windowsでおそらく最高のシェル~ http://programming-aip.blogspot.jp/2013/01/powershellwindows.html --最近は、コマンドレットも充実してきて人気も出てきていると思います。 --分析中で面白いのは、~ 「大量の出力を扱う場合は、オブジェクト・ベースが仇となる場合もある」~ という所である。 ---理由は、大量テキスト処理可能なCUIのEXEにパイプさせれば上手く編集できるため。 ---しかし、そもそも、Windowsの場合、強力なテキスト処理を実装するCUIのEXEが充実していない。 -Windows PowerShell: オブジェクトをカスタマイズするさまざまな方法~ http://technet.microsoft.com/ja-jp/magazine/hh750381.aspx~ -コンピューターで多くの領域を占有しているフォルダーを確認する方法はありますか~ http://gallery.technet.microsoft.com/scriptcenter/4e83afe2-ebdf-414a-bfc9-36e76b7e9750 ---- Tags: [[:シェル]], [[:インフラストラクチャ]], [[:Windows]]