- 追加された行はこの色です。
- 削除された行はこの色です。
「[[マイクロソフト系技術情報 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]]