Everything you wanted to know about PSCustomObject

author
1 minute, 38 seconds Read
  • 10/05/2020
  • 8 minutes to read
    • j
    • m
    • s
    • j
    • c

PSCustomObjectはPowerShellツールベルトに加えたいすばらしいツールです。 基本的なことから始めて、より高度な機能へと進んでいきましょう。 PSCustomObject の使用目的は、構造化データを作成する簡単な方法を提供することです。

Note

The original version of this article appeared on the blog written by @KevinMarquette.NetSupport.jp ———————————————————————————————— この記事のオリジナルは @KevinMarquette 氏のブログです。 PowerShell チームは、このコンテンツを共有してくださった Kevin に感謝します。 彼のブログ atPowerShellExplained.com をチェックしてください。

Creating a PSCustomObject

私は PowerShell で を使用するのが大好きです。 そのため、オブジェクトを作成する他のすべての方法は省略しますが、これらの例のほとんどは PowerShell v3.0 以降であることを言及する必要があります。

$myObject = @{ Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}

私はほぼすべてにハッシュテーブルを使用しているので、この方法は私にとってうまく機能します。 しかし、PowerShell でハッシュテーブルをよりオブジェクトのように扱いたい場合もあります。 この違いに最初に気づくのは、Format-Table または Export-CSV を使用したいときに、ハッシュテーブルが単なるキー/値ペアのコレクションであることに気づくときです。

$myObject.Name

Converting a hashtable

この話題のついでに、こんなこともできることをご存知ですか:

$myHashtable = @{ Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}$myObject = $myHashtable

私は最初からオブジェクトを作成したいのですが、最初にhashtableで作業しなければならない場合があります。 この例は、コンストラクタがオブジェクトのプロパティをハッシュテーブルで受け取るので動作します。 重要な注意点として、この方法は動作しますが、完全に等価というわけではありません。 最大の違いは、プロパティの順序が保持されないことです。

Legacy approach

カスタム オブジェクトを作成するために New-Object を使用する人を見たことがあるかもしれません。

$myHashtable = @{ Name = 'Kevin' Language = 'PowerShell' State = 'Texas'}$myObject = New-Object -TypeName PSObject -Property $myHashtable

この方法はかなり遅いですが、PowerShell の初期のバージョンでは最良の選択肢かもしれません。

ファイルに保存する

ハッシュテーブルをファイルに保存する最善の方法は、それを JSON として保存することだと思います。 ファイルにオブジェクトを保存する他の方法については、「ファイルへの読み取りと書き込みの多くの方法」の記事で説明しています。

Working with properties

Adding properties

Add-Member を使用して、PSCustomObject に新しいプロパティを追加できます。

$myObject | Add-Member -MemberType NoteProperty -Name 'ID' -Value 'KevinMarquette'$myObject.ID

Remove properties

また、オブジェクトからプロパティを削除することも可能です。

$myObject.psobject.properties.remove('ID')

psobject はベース オブジェクト メタデータにアクセスするための隠しプロパティです。

Enumerating property names

時には、オブジェクト上のすべてのプロパティ名のリストが必要な場合があります。

$myObject | Get-Member -MemberType NoteProperty | Select -ExpandProperty Name

これと同じリストを psobject プロパティから取得することもできます。

$myobject.psobject.properties.name

Dynamically accessing properties

私はすでに、プロパティ値に直接アクセスすることができることを述べました。

$myObject.Name

プロパティ名に文字列を使用しても動作します。

$myObject.'Name'

これをもう一歩進めて、プロパティ名に変数を使用することができます。

$property = 'Name'$myObject.$property

奇妙に見えますが、これは動作します。

PSCustomObject をハッシュテーブルに変換する

最後のセクションから続けるには、プロパティを動的に歩き、それらからハッシュテーブルを作成することが可能です。

$hashtable = @{}foreach( $property in $myobject.psobject.properties.name ){ $hashtable = $myObject.$property}

プロパティのテスト

プロパティが存在するかどうかを知る必要がある場合、そのプロパティが値を持っているかどうかをチェックすればよいのです。

if( $null -ne $myObject.ID )

しかし、もしその値が$nullであり得るなら、psobject.propertiesをチェックすることでそれが存在するかどうかを確認できます。

if( $myobject.psobject.properties.match('ID').Count )

オブジェクトメソッドの追加

もしオブジェクトにスクリプトメソッドを加える必要があるなら、Add-MemberとaScriptBlockでそれをすることができます。 現在のオブジェクトを参照する自動変数 this を使用しなければならない。 以下は、オブジェクトをハッシュテーブルにするためのascriptblockです。 (最後の例と同じコード)

次に、それをスクリプト プロパティとしてオブジェクトに追加します。

$myObject.ToHashtable()

オブジェクト vs 値型

オブジェクトと値型は、変数の割り当てを同じようには処理しません。

$first = 1$second = $first$second = 2

この場合、$first は 1、$second は 2 です。

オブジェクト変数は、実際のオブジェクトへの参照を保持します。 あるオブジェクトをnewvariableに代入しても、それらは同じオブジェクトを参照しています。

$third = @{Key=3}$fourth = $third$fourth.Key = 4

$third$fourthはオブジェクトの同じインスタンスを参照しているので、$third.key$fourth.Keyは両方とも4です。

psobject.copy()

オブジェクトの真のコピーが必要な場合、それを複製することができます。

$third = @{Key=3}$fourth = $third.psobject.copy()$fourth.Key = 4

複製すると、オブジェクトの浅いコピーが作成されます。 この例では、$third.key は 3、$fourth.Key は 4 です。

私がこれを浅いコピーと呼ぶのは、ネストしたオブジェクトがある場合、そのインスタンスを作成するためです。 (プロパティが他のオブジェクトを含む場合)。 トップレベルの値のみがコピーされます。 子オブジェクトは互いを参照します。

PSTypeName for custom object types

さて、オブジェクトができたので、それを使ってできることがいくつかありますが、ほとんど明らかではないかもしれません。 最初に行う必要があるのは、それに PSTypeName を与えることです。 これは、私が見た中で最も一般的な方法です:

$myObject.PSObject.TypeNames.Insert(0,"My.Object")

私は最近、/u/markekraus によるこの投稿からこれを行う別の方法を発見しました。 Adam Bertram と Mike Shepard のアイデアについて少し調べてみたところ、彼らはインラインで定義することができるこのアプローチについて話していました。

Note

PowerShell クラスを使用して、カスタムの PowerShell タイプを作成することもできます。 詳細については、PowerShell クラスの概要を参照してください。

Using DefaultPropertySet (the long way)

PowerShellは、デフォルトで表示するプロパティを私たちのために決定してくれます。 ネイティブ コマンドの多くには、すべての重要な作業を行う .ps1xml フォーマット ファイルがあります。 Boe Prox によるこの投稿から、PowerShell のみを使用してカスタム オブジェクトでこれを行う別の方法があります。

これで、私のオブジェクトがシェルに落ちたとき、デフォルトでこれらのプロパティのみが表示されます。

Update-TypeData with DefaultPropertySet

これは素晴らしいですが、最近 Jeffrey Snover & Don Jones と PowerShell unplugged 2016 を見ていてよりよい方法を知りました。 Jeffrey はデフォルトのプロパティを指定するために Update-TypeData を使用していました。

$TypeData = @{ TypeName = 'My.Object' DefaultDisplayPropertySet = 'Name','Language'}Update-TypeData @TypeData

この投稿をクイックリファレンスとして持っていなければ、ほとんど覚えてしまうほど簡単な方法です。 これで、たくさんのプロパティを持つオブジェクトを簡単に作成でき、かつシェルから見たときにきれいなビューを与えることができるようになりました。

$myObject | Format-List *

Update-TypeData with ScriptProperty

Something I got out of that video was creating script properties for your objects.このビデオから得た他のことは、オブジェクトのスクリプト プロパティを作成することでした。 これは、既存のオブジェクトでも機能することを指摘する良い機会でしょう。

これは、オブジェクトが作成される前でも後でも行うことができます。 これは、スクリプト プロパティで Add-Member を使用する場合と異なる点です。 先ほどの方法で Add-Member を使用した場合、それはオブジェクトの特定のインスタンスにのみ存在します。 これは、この TypeName を持つすべてのオブジェクトに適用されます。

関数パラメータ

関数やスクリプトのパラメータにこれらのカスタム タイプを使用できるようになりました。 ある関数でこれらのカスタム オブジェクトを作成し、他の関数に渡すことができます。

param( $Data )

PowerShell は、オブジェクトが指定された型であることを要求します。 それは、タイプがあなたのコードでそれをテストするステップを節約するために自動的に一致しない場合、検証エラーをスローします。

Function OutputType

高度な関数用に OutputType を定義することもできます。

function Get-MyObject{ param ( ...

OutputType 属性値は単なるドキュメント ノートです。 それは、関数コードから派生したり、実際の関数出力と比較されることはありません。

出力タイプを使用する主な理由は、関数に関するメタ情報が意図を反映するようにするためです。 開発環境が利用できる Get-CommandGet-Help のようなものです。 より多くの情報が必要な場合は、ヘルプの about_Functions_OutputTypeAttribute.

With said, if you’re using Pester to unit test your functions, it would be a good ideaato validate the output objects match your OutputType.

With the way that you’re using Pester to units test for your functions. 2694>

Closing thoughts

この文脈はすべて についてでしたが、この情報の多くはオブジェクト一般に当てはまります。 ちょうどこの先週、別のものを偶然見つけ、今まで見たことがなかったことに驚きました。 私は、これらのアイデアをすべてまとめて、皆さんが全体像を把握し、それらを使用する機会があったときに意識できるようにしたいと思いました。 あなたが何かを学び、これをあなたのスクリプトに取り入れる方法を見つけることができれば幸いです。

Similar Posts

コメントを残す

メールアドレスが公開されることはありません。