PowerShellで面倒なオブジェクトはPSCustomObjectに変換するのが早道
ASCII.jp / 2024年9月8日 10時0分
PSCustomObjectとはそもそもなんぞや
PowerShellのパイプラインは、オブジェクトを流すようになっている。なので、複雑な情報はPowerShellのオブジェクトにすると、あとの処理が簡単になる。
そのためにあるのが、「PSCustomObject」と呼ばれる汎用のオブジェクトだ。このオブジェクトであれば、Format-*や*-ObjectといったPowerShellの汎用コマンドを適用できる。
逆に言えば、PowerShellの汎用コマンドは、フラットな構造のオブジェクトを想定しており、プロパティの値がオブジェクトになっているようなものは扱いにくい。このような場合に、PSCustomObjectを作ってフラットな構造にすることで、以後は処理しやすくなる。
なお、PSCustomObjectの基本的なことは、Microsoftのサイトにページ(https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_pscustomobject?view=powershell-7.4)がある。
PSCustomObjectの作り方
PSCustomObjectを作るには、ハッシュテーブル(連想配列)を作り、それをPSCustomObjectにキャストすればいい。まず、ハッシュテーブルは、「名前=値;」を「@{」と「}」で囲む。たとえば、
@{Name="shioda"; Country="Japan"; Job="Writor" }
とする。
![PSCustomObject](https://ascii.jp/img/2024/09/08/3793110/x/788a938a56a2b43d.png)
PSCustomObjectにするには、前に「[PSCustomObject]」を置く(キャストという)。
[PSCustomObject]@{Name="shioda"; Country="Japan"; Job="Writor" }
これが基本パターンだが、多くの場合、パイプラインを流れてくるオブジェクトを利用してPSCustomObjectを作る。その基本パターンは、
<ソースコマンド> | Foreach-Object {[PSCustomObject] @{<名前>=<値>;…… }
となる。たとえば、PowerShellでは、「1..10」で1から10までの整数オブジェクトを発生させることができる。これをパイプラインでForeach-Objectで処理する。
0x41..0x45 | ForEach-Object { [PSCustomObject]@{ Code=$_; Hex=$_.ToString("X2"); Char=[char]$_ }}
![PSCustomObject](https://ascii.jp/img/2024/09/08/3793111/x/c8e255856df21f49.png)
PSCustomObjectになったらSort-ObjectやWhere-Object、Select-Objectで処理が可能だ。
もう少し複雑な例を挙げてみよう
PowerShellでは、XMLデータを扱えるが、多くの場合でXMLデータは階層構造を持ち、PowerShellからはデータのアクセスが面倒だ。このようなときに、PSCustomObjectに必要な情報だけを入れることで、フラットなオブジェクトとして扱うことができる。
PowerShellでは、XMLオブジェクトを作り、これを使ってXMLファイルを読み込む。具体的な手順としては、
$myxml=New-Object System.Xml.XmlDocument $myxml.Load(<XMLフルファイルパス>)
となる。Loadメソッドにはフルパスが必要な点に注意してほしい。
![PSCustomObject](https://ascii.jp/img/2024/09/08/3793112/x/664a34d005f17ca4.png)
XMLファイルがXMLオブジェクトに読み込まれたら、アクセス方法は2つ。正統な方法は、Select-XMLコマンドを使って、XPATHで要素にアクセスする方法。もう1つは、PowerShellのオブジェクトのようにドット記法を使って要素にアクセスする方法だ。
ただし、後者はプロパティ名の大文字小文字の区別がないため、大文字小文字だけが異なる要素を区別できない。簡易的には、後者の方法でも問題ないことが多いのだが、厳密には、XMLではタグ名や属性名では大文字小文字が区別されているため、XMLファイルによっては、対象を混同してしまうことがある。
ここでは、OpenTypeフォント(Cascadia Codeフォント)のソースコードから、グリフ名やユニコードのコードポイントなどを取得してみる。Select-Xmlコマンドを使うと、
(Select-Xml $myxml -XPath "//unicode/@hex").node
となる(大文字小文字が区別されるのでXPATHの記述に注意)。大文字小文字を区別できない簡易な方法では、
$myxml.glyph.unicode.hex
だけでよい。これでもプロパティ指定が煩雑で、一覧表にするのが面倒になる。
そこで、以下のコマンドを使ってPSCustomObjectに変換する。
Get-ChildItem -Recurse -Filter *.glif | ForEach-Object { $myxml.Load($_.FullName); [PSCustomObject]@{Name=$myxml.glyph.name; Unicode=$myxml.glyph.unicode.hex; Width=$myxml.glyph.advance.width; File=$_.Name} }
![PSCustomObject](https://ascii.jp/img/2024/09/08/3793113/x/bcdad1f3c55a13e1.png)
少し長いので、改行とインデントを入れてわかりやすくしたのが、以下のリストである。
Get-ChildItem -Recurse -Filter *.glif | ForEach-Object { $myxml.Load($_.FullName); [PSCustomObject]@{ Name=$myxml.glyph.name; Unicode=$myxml.glyph.unicode.hex; Width=$myxml.glyph.advance.width; File=$_.Name } }
対象のフォルダには、大量のglifファイルがあるので、出力も大量になるが、Where-ObjectやSelect-Objectコマンドが使えるためコンパクトな出力が可能になる。また、Sort-ObjectでUnicodeプロパティをキーに並べ替えることも可能だ。Sort-ObjectやSelect-Objectは、ドット記法を解釈しないため、XMLオブジェクトを直接扱えない。
このような場合、PSCustomObjectを使い、一旦PowerShell用のフラットなオブジェクトを作る。あとの作業は、Select-ObjectやWhere-Objectなど、ハイフンの後ろに「Object」を持つコマンドや、コマンド名のハイフンよりも前に「Format」を持つコマンドが利用できるようになる。
PowerShellは、パイプラインでオブジェクトを扱えるのが「自慢」だが、フラットでない構造のオブジェクト(プロパティにオブジェクトが入っているなど)はあまり得意ではない。オブジェクトへのアクセスが面倒な場合、PSCustomObjectを作るのが早道である。
この記事に関連するニュース
-
Googleスプレッドシートを悪用、税務署偽るフィッシングメールに警戒を
マイナビニュース / 2024年9月2日 12時22分
-
Chromeのゼロデイ脆弱性を北朝鮮の攻撃者が悪用、すぐ更新を
マイナビニュース / 2024年9月2日 10時49分
-
Windows Terminal ベスト設定 第17回「フォント 設定編」
マイナビニュース / 2024年8月25日 15時45分
-
Chromeに保存された認証情報を大量に窃取するサイバー攻撃確認、注意を
マイナビニュース / 2024年8月24日 19時51分
-
窓辺の小石 第180回 モニター No.6
マイナビニュース / 2024年8月23日 15時51分
ランキング
-
1トレンドマイクロがディープフェイク映像を警告するアプリのβ版を公開/Bluetooth 6.0リリース 新機能も追加
ITmedia PC USER / 2024年9月8日 6時5分
-
2実は始まっていた「povo3.0」への布石 povo2.0は他社対抗も含め“完成形”に
ITmedia Mobile / 2024年9月7日 6時5分
-
3「信じられん」「まじかよ」 “おじいちゃん”に孫がガチメイクしたら…… 次元も年齢も超えた「超絶イケメン」への変身が2600万再生
ねとらぼ / 2024年9月8日 8時30分
-
4お寺の魅力を学べるWebアプリ「仏門GO」誕生
おたくま経済新聞 / 2024年9月7日 18時0分
-
5黒いスマホやケースは発熱しやすい? 白いスマホケースと比べながら実験してみた
ITmedia Mobile / 2024年9月8日 6時5分
記事ミッション中・・・
記事にリアクションする
![](/pc/img/mission/mission_close_icon.png)
記事ミッション中・・・
記事にリアクションする
![](/pc/img/mission/point-loading.png)
エラーが発生しました
ページを再読み込みして
ください
![](/pc/img/mission/mission_close_icon.png)