Home > Windows にまつわる e.t.c.

PowerShell 的な使い方(2)


前回は、PowerShell ぽい使い方を解説しました。

PowerShell 的な使い方(1)
http://www.vwnet.jp/Windows/PowerShell/2018040502/GettingStartedWithPowerShell-02.htm

 

今回は実践的な PowerShell の使い方を解説します。

 

出力を整える

デフォルトのコマンドレット出力は、代表的なプロパティがテーブル表示されますが、必要なプロパティが表示されていないとか、出力が長くて途中で切れているとか残念な事も良くありますよね。

そんな時は、出力を一工夫するとぐっと使いやすくなります。

 

Format-Table(ft)

Format-Table は、指定したプロパティをテーブル表示しますので一覧で見たいときに便利です。-AutoSize を使うと項目幅が自動調整されます。

Get-ChildItem C:\Windows\System32\drivers\etc\ | Format-Table FullName, LastWriteTime, Length -AutoSize

 

Format-List(fl)

Format-List は、指定したプロパティをリスト表示しますので長いプロパティを見たいときに便利です。

Get-ChildItem C:\Windows\System32\drivers\etc\ | Format-List FullName, LastWriteTime, Length

 

Select-Object

Select-Object は、対象となるプロパティを選択し、必要なオブジェクトに絞るのに使います。

全てのプロパティを指定する場合は、* を使います。

Get-ChildItem C:\Windows\System32\drivers\etc\ | Select-Object *

 

Out-GridView

Out-GridView はグリッドビューに格納します。グリッドビューは簡単なデータ操作が出来ます。

Format-Table、Format-List と違い、格納するプロパティを指定できないので、Select-Object でプロパティを絞ります。
Select-Object せずに Out-GridView に渡すと、default 表示されるプロパティだけが対象になります。

Get-ChildItem C:\Windows\System32\drivers\etc\ | Select-Object FullName, LastWriteTime, Length | Out-GridView

 

テキスト整形

値だけを扱うのであればこれまでの表示方法で事足りますが、人が有意文として読む事を想定した場合には物足りないですね。
そんな時は、テキスト整形をします。

例えば以下のような有意文にするケースで説明しましょう。

只今の気温は 23 ℃、湿度は 45 % です。

 

既に値は以下変数に格納されているとします。

$Temperature = 23
$Humidity = 45

 

ダブルクォーテーションで囲む

PowerShell の文字列は、ダブルクォーテーションで囲むと変数が展開される仕様を使います。

$Sentence = "只今の気温は $Temperature ℃、湿度は $Humidity % です。"

 

+/+= でつなげる

文字列としてつなげていく事も出来ます。

$Sentence = "只今の気温は " + $Temperature + " ℃、湿度は " + $Humidity + " % です。"

 

あるいは、こんな方法でもイケます。

$Sentence = "只今の気温は "
$Sentence += $Temperature
$Sentence += " ℃、湿度は "
$Sentence += $Humidity
$Sentence += " % です。"

 

フォーマットする(-f を使う)

プログラミングをした事ある方ならフォーマットは出来ないの? と思われますよね。
もちろん出来ます。

$Sentence = "只今の気温は {0} ℃、湿度は {1} % です。" -f $Temperature, $Humidity

 

大かっこ { } 内の数字が引数の並び順です。

項目の表示幅は「{n,s}」のように s で表現します。s だけだと右揃え、-s にすると左揃えになります。

数値を編集する場合は「{n,s:format}」で表現します。

 

フォーマットする([String]::Format を使う)

もう一つのフォーマット方法は、.NET framework String クラスの Format メソッドを使う方法です。

$Sentence = [String]::Format("只今の気温は {0} ℃、湿度は {1} % です。", $Temperature, $Humidity)

 

大かっこ {} 内は -f と同じで、幅指定、右寄せ左寄せ、編集ができます。

 

編集

フォーマットする時にでよく使われる編集にはこんなのがあります。

カンマ編集 #,#
固定長にしてリーディングゼロをつける 0000000
少数以下桁数指定 0.00
4桁の小文字16進数 x4
4桁の大文字16進数 X4

 

これを使うとこんな感じに編集できます。

$Sentence = "只今の気温は {0:0.00} ℃、湿度は {1:0.00} % です。" -f $Temperature, $Humidity

 

PowerSehll がハンドリングできるもの

PowerShell は様々なものが簡単にハンドリングできるので、ツールとしてとても使い勝手があります。

 

コマンドレッド

PowerShell といえば、コマンドレッドですよね。

コマンドレッドはオブジェクトを出力するので、必要なプロパティを使ったり、メソッドを使って様々なことができます。
コマンドレットとオブジェクトについては既に説明済みなので、これ以上の説明は割愛します。

 

一般コマンド

ipconfig 等の一般的な DOS コマンドは、オブジェクトではなく、テキストしか出力できません。

コマンドレットと違い、一般コマンドが出力した内容をハンドリングするにはちょっとした工夫が必要になります。

一般コマンドが出力形式は、一行が文字列型(String)の配列になっています。

例えば、ipconfig の出力のうち「IPv4」が含まれている行を抽出する場合は、正規表現検索をする Select-String コマンドレットを使い以下のようにします。

ipconfig | Select-String IPv4

 

これで「IPv4」が含まれている行が取れました。

このうち IP アドレスが欲しい場合は、「:」で分割し、2つ目の要素を取り出します。

文字列を指定文字で分割するには -split 演算子を使用し、分解された1番目の要素が目的のIPアドレスです。(0から数えるので、1つ目の要素は0番目、2つ目は1番目の要素と表現されます)

オブジェクト配列なので、ForEach-Object コマンドレットの Alias である % で要素分解し、各要素に対して分割します。

こんな感じですね。

ipconfig | Select-String IPv4 | % {($_ -Split ":")[1]}

 

このままでは、先頭に余分な空白が含まれているので、Trim メソッドで余分な空白を取り除きます。

ipconfig | Select-String IPv4 | % {($_ -Split ":")[1]} | %{$_.Trim()}

 

これで IPv4 アドレスだけを取り出すことができました。

 

ファイルシステム

PowerShell でよく扱うのがファイルシステムです。

指定したフォルダやファイルそのものを情報を得る場合は、Get-Item あるいは Get-ItemProperty を使います。

フォルダを指定する場合に絶対 Path を使う場合は、ドライブレターを含めた Full Path を指定します。

Get-Item C:\Windows\

 

カレントディレクトリを移動するには、Set-Location を使います。コマンドプロンプトに慣れている方であれば、Set-Location の Alias である cd の方が馴染みがありますね。

cd C:\Windows\

 

相対 Path を指定する場合、PowerShell ではカレントディレクトリを「.\」と表現しますので、System32 サブディレクトリを指定する場合は以下のようにします。

cd .\System32\

 

1つ上のディレクトリは「..」なので、カレントディレクトリから見て1つ上のディレクトリは「.\..」と表現します。

cd .\..

 

指定したディレクトリ下にあるファイルやディレクトリ情報を得る場合は、Get-ChildItem を使います。

Get-ChildItem .\System32\drivers\etc\

 

共有

Windows の共有をアクセスする場合は、\\サーバー名\共有名 の UNC がポピュラーですね。
PowerShell でもアクセス権のある共有であれば UNC でアクセスすることが可能です。

Get-Item \\file01\common\

 

UNC でうまくアクセスできない時は、「Filesystem::」をつけるとうまくアクセスできることがあります。

Get-Item Filesystem::\\file01\common

 

net use で認証する場合

問題は権限が無い共有にアクセスする場合です。

アクセス権の無い UNC にアクセスするとエラーになってアクセスすることができません。

このような場合は、昔ながらの net use コマンドを使って認証を受ける手があります。

net use \\192.168.33.63 パスワード /user:ホスト名\アカウント(ドメイン名\アカウント)

 

net use コマンドを使って認証を受けると $IPC で認証が取れているのがわかります。

共有を使い終わったら、net use /delete で接続を解除します。

net use /delete * /yes

 

PSDrive を使う

net use を使うより、xxx-PSDrive コマンドレットを使うのが PowerShell らしいと言えるでしょう。

共有を接続するには、New-PSDrive を使って以下のようにします。

New-PSDrive -Name 接続名 -Root UNC -PSProvider FileSystem -Credential ホスト名\アカウント(ドメイン名\アカウント)

 

New-PSDrive で接続した共有にアクセスするには、接続名: にアクセスします。

Get-Item Private:

 

接続を解除するときは、Remove-PSDrive で切断します。

 

レジストリ

レジストリも、ファイルシステムと同様に Get-Item、Get-ItemProperty、Get-ChildItem、Set-Location が使えますし、権限があれば編集も可能です。

ハイブはデフォルトで HKEY_CURRENT_USER と HKEY_LOCAL_MACHINE が割り当てされていますが、これ以外のハイブも必要に応じて New-PSDrive で割り当てしてアクセスします。

ハイブ 割り当て 備考
HKEY_CURRENT_USER HKCU: 標準割り当て済み
HKEY_LOCAL_MACHINE HKLM: 標準割り当て済み
HKEY_CURRENT_CONFIG HKCC: New-PSDrive -Name HKCC -PSProvider Registry -Root HKEY_CURRENT_CONFIG
HKEY_CLASSES_ROOT HKCR: New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT
HKEY_USERS HKU: New-PSDrive -Name HKU -PSProvider Registry -Root HKEY_USERS

 

例えば、HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows をカレントにし、直下を確認するには場合は以下のようにします。

 

Set-Location HKLM:\SOFTWARE\Policies\Microsoft\Windows
Get-ChildItem

 

フルパスを指定する場合は以下のようにします

Get-ChildItem HKLM:\SOFTWARE\Policies\Microsoft\Windows

 

割り当て状況は Get-PSDrive で確認できます。

 

WMI

WMI ハンドリングは、WMI クラスをオブジェクトにしてハンドリングします。

例えば、OS 名を見る場合は Win32_OperatingSystem クラスの Caption プロパティを見ます。

$Win32_OperatingSystem = Get-WmiObject -Class Win32_OperatingSystem
$Win32_OperatingSystem.Caption

 

取ってきた物はオブジェクトなので、プロパティだけではなくメソッドもあるので WMI に対しての操作も可能です。

 

.NET オブジェクト

.NET のハンドリングは、スタティックメソッドを扱う場合と、クラスをオブジェクトにしてハンドリングする方法の2種類があります。

スタティックメンバーを使う場合は、以下ののようにします。

[クラス]::メソッド(引数)

 

例えば、System.Math の Pow メソッド(べき乗を求めるスタティックメソッド)を使う場合は以下のようにします。

$a = [System.Math]::Pow(5,3)

 

クラスをオブジェクトにする場合は、New-Object を使います。コンストラクタに渡す引数をセットしない場合は () を省略します。

New-Object クラス(コンストラクタに渡す引数)

 

例えば、System.Random を使って 1000 以下のランダム値を求める場合は以下のようにします。

$a = New-Object System.Random
$a.Next(1000)

 

New-Object した場合、オブジェクトが Dispose メソッドを持っていることがあります。

この場合は、使用した後に Dispose してオブジェクトを開放するとメモリーの節約になります。

明示的に Dispose しないと動作がおかしくなるクラスもあるので、必ず Dispose で後始末するのがおすすめです。

 

汎用形式データファイルを操作する

PowerShell はデータファイルのハンドリングも得意です。

 

テキストファイル

テキストファイルのハンドリング コマンドレットは沢山ありますが、僕が良く使う Get-Content / Set-Content で説明します。

Read

テキストファイルを読む場合は、以下のようにします。

受け取り変数 = Get-Content -Path ファイルパス

文字コードを指定して読む場合は、-Encoding オプションを使います。

日本語環境で SJIS として読む場合は、-Encoding Default を指定します。

データハンドリング

読み込んだデータは、文字列の配列になっているので、Where-Object(?)、ForEach-Object(%) でぐるぐる回して処理します。

Write

ファイルの書き込みは、以下のようにします

Set-Content -Path ファイルパス -Value セットするデータ

文字コードを指定する場合は、Get-Content と同様に -Encoding で指定します。

 

CSV

CSV はよく使われるので専用のコマンドレットがあります。

Read

CSV ファイルを読む場合は、以下のようにします。

受け取り変数 = Import-Csv -Path ファイルパス

文字コードは -Encoding で指定します、

データハンドリング

CSV ファイルはオブジェクトの配列になっているので、通常の PowerShell オブジェクトと同様に扱うことができます。

CSV のヘッダー(1行目)がオブジェクト名になるので、ヘッダーのついていない CSV はハンドリングできません。

Write

CSV ファイルの書き込みは、リダイレクトを使って以下のようにします

セットするデータ | Export-Csv -Path ファイルパス

データに日本語が含まれているときは、-Encoding Default で SJIS を指定するか、-Encoding UTF8 で UTF-8 を指定します。

 

JSON

CSV は2次元配列なので、2次元以外のデータをファイルにハンドリングする場合 JSON を使います。

JSON は WebAPI でよく使われるデータ形式なので、Web Service Client を実装する場合には必須のデータ形式です。

JSON はテキストファイルとしてハンドリングし、ConvertFrom-Json と ConvertTo-Json で JSON 変換をハンドリングします。

Read

JSON データは、一旦テキストファイルとして読んで、ConvertFrom-Json にリダイレクトしてオブジェクトの配列にします。

$JsonData = Get-Content -Path C:\Test\test.json
$ObjectData = $JsonData | ConvertFrom-Json

データハンドリング

データはオブジェクト配列になっていますが、JSON そのものにデータの型が無いので、プロパティは値を見て型が自動適用された状態になっています。

Write

出力時は、ConvertTo-Json で JSON 形式のテキストに変換し、テキストファイルとして出力します。

$JsonData = $ObjectData | ConvertTo-Json
Set-Content -Path C:\Test\test2.json -Value $JsonData

 

XML

Read

Get-Content でテキストファイルとして読んで、[xml] で XML にキャストします。

[xml]$XmlData = Get-Content "C:\Test\test.xml"

データハンドリング

XML はピリオドで階層をたどれます。

プロパティに文字列がセットできます(文字列以外は NG)

XML ブラウザー(Web ブラウザー等)で構造を見た方が操作しやすいです。

メソッドがあるので、メソッドでの操作も可能です。

例えば、要素を追加するのであれば CreateElement/AppendChild、属性の追加は SetAttribute を使います(詳しい情報は割愛するのでクグって w)

Write

Save メソッドで出力します

$XmlData.Save("C:\Test\Test2.xml")

 

cmd を使う

PowerShell プロンプトからうまく扱うことができない DOS コマンドは、cmd モードで操作します。

例えば、実行ファイルの存在場所を確認する where は PowerShell の Where-Object のエイリアスとかぶっているので where コマンドはそのままでは使えません。

 

cmd モード

そんな時は cmd モード(僕がつけた呼称)で where を実行します。

 

「cmd」で cmd モードに入って where を実行(プロンプトが変わるので、それでモード確認)
その後「exit」で cmd モードから抜けます

 

cmd /c

cmd /c で where コマンド実行します

cmd /c where notepad

 

関連情報

今日から使う PowerShell
http://www.vwnet.jp/Windows/etc.asp#GettingStartedWithPowerShell

 

back.gif (1980 バイト)

home.gif (1907 バイト)

Copyright © MURA All rights reserved.