次の方法で共有


about_PSCustomObject

簡単な説明

型アクセラレータと [pscustomobject] 型アクセラレータの[psobject]違いについて説明します。

長い説明

型アクセラレータは [pscustomobject] PowerShell 3.0 で追加されました。

この型アクセラレータを追加する前は、メンバーのプロパティと値を使用してオブジェクトを作成する方が複雑でした。 最初は、 を使用 New-Object して オブジェクトを作成し、 Add-Member プロパティを追加する必要がありました。 例:

PS> $object1 = New-Object -TypeName PSObject
PS> Add-Member -InputObject $object1 -MemberType NoteProperty -Name one -Value 1
PS> Add-Member -InputObject $object1 -MemberType NoteProperty -Name two -Value 2
PS> $object1 | Get-Member

   TypeName: System.Management.Automation.PSCustomObject

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
one         NoteProperty int one=1
two         NoteProperty int two=2

PS> $object1

one two
--- ---
  1   2

後で、 の New-ObjectProperty パラメーターを使用して、メンバーと値を含む Hashtable を渡すことができます。 例:

PS> $object2 = New-Object -TypeName PSObject -Property @{one=1; two=2}
PS> $object2 | Get-Member

   TypeName: System.Management.Automation.PSCustomObject

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
one         NoteProperty int one=1
two         NoteProperty int two=2

PS> $object2

one two
--- ---
  1   2

PowerShell 3.0 以降、 Hashtable をキャストすると [pscustomobject] 同じ結果が得られます。

PS> $object3 = [pscustomobject]@{one=1; two=2}
PS> $object3 | Get-Member

   TypeName: System.Management.Automation.PSCustomObject

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
one         NoteProperty int one=1
two         NoteProperty int two=2

PS> $object3

one two
--- ---
  1   2

PSObject 型オブジェクトは、メンバーがオブジェクトに追加された順序でメンバーの一覧を保持します。 Hashtable オブジェクトはキーと値のペアの順序を保証しませんが、リテラル ハッシュテーブルをキャストして[pscustomobject]順序を維持します。

ハッシュテーブルはリテラルである必要があります。 ハッシュテーブルをかっこで囲む場合、またはハッシュテーブルを含む変数をキャストした場合、順序が保持される保証はありません。

$hash = @{
    Name      = "Server30"
    System    = "Server Core"
    PSVersion = "4.0"
}
$Asset = [pscustomobject]$hash
$Asset
System      Name     PSVersion
------      ----     ---------
Server Core Server30 4.0

型アクセラレータについて

[psobject][pscustomobject] は型アクセラレータです。

詳細については、「 about_Type_Accelerators」を参照してください。

System.Management.Automation.PSCustomObject にマップする必要があると思われる[pscustomobject]場合でも、型は異なります。

PS> [pscustomobject] -eq [System.Management.Automation.PSCustomObject]
False

どちらの型アクセラレータも、同じクラス PSObject にマップされます。

PS> [pscustomobject]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     PSObject                                 System.Object

PS> [psobject]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     PSObject                                 System.Object

型アクセラレータが [pscustomobject] PowerShell に追加されると、 ハッシュテーブル から PSObject 型への変換を処理するための追加のコードが含まれていました。 この追加のコードは、新しいオブジェクトが作成されている場合にのみ呼び出されます。 したがって、すべてのオブジェクトが PSObject 型として扱われるため、型強制型または型比較には を使用[pscustomobject]できません。

たとえば、 演算子を-is使用して、 コマンドレットによって返されるオブジェクトが であることをチェックすることは[pscustomobject]、 と比較した場合[psobject]と同じです。

PS> (Get-Item /) -is [pscustomobject]
True

PS> (Get-Item /) -is [psobject]
True

オブジェクト [psobject] をキャストすると、元のオブジェクトの型が取得されます。 したがって、 Hashtable 以外のものをキャストすると [pscustomobject] 、同じ型になります。

PS> ([psobject]@{Property = 'Value'}).GetType().FullName
System.Collections.Hashtable

PS> ([pscustomobject]123).GetType().Name
Int32

PS> ([pscustomobject]@{Property = 'Value'}).GetType().FullName
System.Management.Automation.PSCustomObject

オブジェクトをキャストしても [psobject] 型には影響を与えないように見えますが、PowerShell はオブジェクトの周囲に 非表示[psobject] のラッパーを追加します。 これは微妙な副作用を持つことができます。

  • ラップされたオブジェクトは、元の型と型と [psobject] 一致します。

    PS> 1 -is [Int32]
    True
    PS> 1 -is [psobject]
    False
    PS> ([psobject] 1) -is [Int32]
    True
    PS> ([psobject] 1) -is [psobject]
    True
    
  • format 演算子 (-f) は、 によって [psobject]ラップされた配列を認識しません。

    PS> '{0} {1}' -f (1, 2)
    1 2
    PS> '{0} {1}' -f ([psobject] (1, 2))
    Error formatting a string: Index (zero based) must be greater than or equal
    to zero and less than the size of the argument list..
    

メモ

Windows PowerShellでは、Hashtable[pscustomobject]キャストして作成されたオブジェクトに Length プロパティまたは Count プロパティがありません。 これらのメンバーにアクセスしようとすると、 が返されます $null

例:

PS> $object = [PSCustomObject]@{key = 'value'}
PS> $object

key
---
value

PS> $object.Count
PS> $object.Length

PowerShell 6 以降では、Hashtable[pscustomobject] をキャストして作成されたオブジェクトは、Length プロパティと Count プロパティの値が常に の1値になります。

こちらもご覧ください