主題の通り、Powershellを使用した設定ファイルの読み込んで変数に格納して使う方法のメモ。 日本語でググってもまとまった情報がないのでまとめる。
環境
PS C:\> #OSのVersion PS C:\> "$((get-wmiobject win32_operatingsystem).caption) ($((get-wmiobject win32_operatingsystem).version))" Microsoft Windows 10 Pro (10.0.10586) PS C:\> #Powershellのバージョン PS C:\> $PSVersionTable.PSVersion Major Minor Build Revision ----- ----- ----- -------- 5 0 10586 122
設定ファイルの読み込み方
propertiesファイル
key=valueな形式のファイルから値を読み取る場合にはConvertFrom-StringDataコマンドレットを利用する*1
PS C:\> #設定ファイル($confPath)のファイルを読み込み、連想配列に変換する PS C:\> $conf = Get-Content $confPath -Raw | ConvertFrom-StringData PS C:\> #設定ファイル($confPath)の内容が連想配列(Hashtable)に格納されていることを確認する PS C:\> $conf.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Hashtable System.Object PS C:\> #keyに対応する値の取り出し PS C:\> $conf.key value PS C:\> #key名に'.'が入っているときはエスケープする PS C:\> $conf.'hoge.key' value
XMLファイル
XMLファイルから値を読み取る場合にはxml型にキャストする。*2 *3
PS C:\> #変数をxml型に指定してファイルを読み込む PS C:\> [xml]$conf = Get-Content $confPath PS C:\> #型を確認するとXmlDocument型に格納されている PS C:\> $conf.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True False XmlDocument System.Xml.XmlNode PS C:\> #読んでみる PS C:\> $conf.catalog book ---- {book, book, book, book...} PS C:\> #配列要素は以下のようにアクセス可能 PS C:\> $conf.catalog.book[0].id bk101 PS C:\> #こんな書き方でも読み込める PS C:\> $conf = [xml](Get-Content $confPath)
参考
JSONファイル
JSON形式のファイルから値を読み取る場合にはConvertFrom-Jsonコマンドレットを利用する*4。
以下のような設定ファイルがあったとする。
{ "Address": 0, "AddressFamily": 2, "ScopeId": null, "IsIPv6Multicast": false, "IsIPv6LinkLocal": false, "IsIPv6SiteLocal": false, "IsIPv6Teredo": false, "IsIPv4MappedToIPv6": false, "IPAddressToString": "0.0.0.0" }
上記の読み込みは以下のように書ける
PS C:\> #ConvertFrom-JsonでJsonを変数に格納する PS C:\> $conf = Get-Content $confPath | ConvertFrom-Json PS C:\> #型を調べてみると、PSCustomObject型で格納される。 PS C:\> $conf.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True False PSCustomObject System.Object PS C:\> #値へのアクセスはPowershellでよくある感じでOK PS C:\> $conf.Address 0
CSVファイル
CSV形式のファイルから値を読み取る場合にはConvertFrom-Csvコマンドレットを利用する*5 以下のような設定ファイルがあったとする
value1-1,value2-1,value3-1 value1-2,value2-2,value3-2
上記の読み込みは以下のように書ける
PS C:\> #値の読み込み PS C:\> $conf = Get-Content $confPath | ConvertFrom-Csv -Header "name1","name2","name3" PS C:\> #Objectの配列に値が格納される。 PS C:\> $conf.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Object[] System.Array PS C:\> #特定列のみ取り出す。 PS C:\> $conf.name1 value1-1 value1-2 PS C:\> #特定行のみ取り出す。 PS C:\> $conf[0] name1 name2 name3 ----- ----- ----- value1-1 value2-1 value3-1 PS C:\> #特定の値へのアクセス PS C:\> $conf[0].name1 value1-1
Delimiterパラメーターで区切り記号を指定したりできる また、Headerパラメーターを指定しない場合は一行目がヘッダとして扱われる。
※Import-Csvというコマンドもあるが、個人的にConvertFrom*でそろえたほうがシェルが読みやすいと思うのでこちらを推奨。
その他
整理してみた感想は以下の通り。
*1:互換性確認はしていないがpowershell -v 1 でもコマンドは存在する
*2:powershell -v 1 しても動く
*3:使用したxmlはMSのサンプル サンプル XML ファイル (books.xml)
*4:互換性確認はしていないがpowershell -v 3 以降でコマンドは存在する
*5:互換性確認はしていないがpowershell -v 1 以降でコマンドは存在する
*6:複雑な設定が必要ならXMLという手もあるが、そんな複雑なシェルは作るべきではないと思う。JSONやCSVはコメントが入れられないのでダメ