オブジェクトに特定のプロパティがあるかどうかをどのようにテストできますか?


93

オブジェクトに特定のプロパティがあるかどうかをどのようにテストできますか?

私にできることを感謝します...

$members = Get-Member -InputObject $myobject 

次に、をforeach介して$members、オブジェクトに特定のプロパティがあるかどうかをテストする関数はありますか?

追加情報: 問題は、2つの異なる種類のCSVファイルをインポートしていることです。1つは2つの列で、もう1つは3つの列です。「Property」でチェックを機能させることができず、「NoteProperty」でのみ機能しました...違いが何であれ

if ( ($member.MemberType -eq "NoteProperty" ) -and ($member.Name -eq $propertyName) ) 

6
($object.property -ne $null)
arco444 2014年

2
プロパティが存在するが$null値があるかどうかは重要ですか
Matt

1
@ arco444nope-成功するにはプロパティが存在する必要があります。-一部の行でそのプロパティが指定されていない動的データ(つまり、Webリクエストからのデータ)がある場合、そのチェックは失敗します。:(
BrainSlugs83 2018年

回答:


103

このような?

 [bool]($myObject.PSobject.Properties.name -match "myPropertyNameToTest")

16
この回答は、PowerShellv3以降でのみ機能します。以下は、powerShell v2以降でも機能するはずです。[bool]($ file.psobject.Properties | where {$ _。Name-eq "myPropertyNameToTest"})
Patrick

33
$myObject.PSobject.Properties.Name -contains "myPropertyNameToTest"優れている。パターンマッチングの可能性について心配する必要はありません。また、ブール値にキャストする必要もありません。
ベーコンビット2016

2
オブジェクトにプロパティがThisisMyPropertyあり、チェックしたい場合はどうなりますMyPropertyか?この回答のすべての解決策は、誤検知になります。
ゾルタンTamási

3
@KolobCanyonこれは厳密モードでは機能しません。
user2864740 2018

1
たとえば、「Count」のテストでオブジェクトに「ThingCount」というプロパティがある場合、このコードは誤検知を返します。
dan-gph 2018

71

使用できます Get-Member

if(Get-Member -inputobject $var -name "Property" -Membertype Properties){
#Property exists
}

12
ベストアンサー私見。これは、PSobjectメンバーを持たない.NETオブジェクトで機能します。オブジェクトに含まれるメンバーのタイプを気にしない場合は、-Membertypeオプションを削除することもできます-メンバー名だけです。Invoke-RestMethodまたはConvertFrom-Jsonオブジェクトで非常に便利です!
Mister_Tom 2017

2
タイプをチェックしない短い構文:if($var | Get-Member Property){ }、さらに短いが読みにくい:if($var | gm Property){ }
zett 4219

これが私の意見では最良の答えです。
キランヘグデ

25

これは簡潔で読みやすいです:

"MyProperty" -in $MyObject.PSobject.Properties.Name

それを関数に入れることができます:

function HasProperty($object, $propertyName)
{
    $propertyName -in $object.PSobject.Properties.Name
}

私はこの答えが大好きですが、CBの答えが機能する場合には機能しないようです。
エドウィン

または、「succinct」=「適切なフォールバックユースケースなしで厳密モードを介して導入された不要なジャンク」(つまり、?.同等のものがない):| これは、特定のバリエーション$MyObject、特に$ nullでも失敗します。厳密モード以外のヌルチェーンの場合はそうではありませんでした。
user28647 4019

5

「プロパティ」が存在し、ランダムな例外をスローしない場合は、を介してアクセスされるため、プロパティ値$thing.$prop返す次のものを使用しています。プロパティが「存在しない」(またはnull値を持っている)場合$nullは、返されます。このアプローチは、厳密モードで機能します。これは、すべてをキャッチするためです。

このアプローチは、PSカスタムオブジェクト、通常の.NETオブジェクト、PS HashTables、およびDictionaryなどの.NETコレクションを「ダックタイプの同等物」として扱うことができるため便利です。これはPowerShellにかなり適しています。

もちろん、これは「プロパティを持っている」という厳密な定義を満たしていません。この質問は明示的に限定される可能性があります。ここで想定されている「プロパティ」のより大きな定義を受け入れる場合は、ブール値を返すようにメソッドを簡単に変更できます。

Function Get-PropOrNull {
    param($thing, [string]$prop)
    Try {
        $thing.$prop
    } Catch {
    }
}

例:

Get-PropOrNull (Get-Date) "Date"                   # => Monday, February 05, 2018 12:00:00 AM
Get-PropOrNull (Get-Date) "flub"                   # => $null
Get-PropOrNull (@{x="HashTable"}) "x"              # => "HashTable"
Get-PropOrNull ([PSCustomObject]@{x="Custom"}) "x" # => "Custom"
$oldDict = New-Object "System.Collections.HashTable"
$oldDict["x"] = "OldDict"
Get-PropOrNull $d "x"                              # => "OldDict"

そして、この振る舞いは[常に]望まれないかもしれません。それは区別することはできませんx.Countx["Count"]


3

MyProperty" -in $MyObject.PSobject.Properties.Nameしかし、私にとってはうまくいきませんでした

$MyObject.PSobject.Properties.Name.Contains("MyProperty")

動作します


2

StrictModeを使用していて、psobjectが空である可能性がある場合は、エラーが発生します。

すべての目的のために、これは行います:

    if (($json.PSobject.Properties | Foreach {$_.Name}) -contains $variable)

1

javascriptチェックに本当に似ています:

foreach($member in $members)
{
    if($member.PropertyName)
    {
        Write $member.PropertyName
    }
    else
    {
        Write "Nope!"
    }
}

1
プロパティの値が実際に$ nullの場合、これは機能しない可能性があります。
Tola Odejayi 2017年

8
PowerShellが厳密モードの場合、これは失敗します。
イアン・ケンプ

@IanKemp厳密モードとは何ですか?実行ポリシーが好きですか?
コロブキャニオン2017

1
@ KolobCanyondocs.microsoft.com / en - za / powershell / module / -基本的にはJavaScriptと同等のPSuse strictです。
イアンケンプ2017年

1
プロパティが存在し、$ falseに設定されている場合も、これは機能しません。

1

次のオブジェクトを前提として明確にするために

$Object

以下の特性を持つ

type        : message
user        : john.doe@company.com
text        : 
ts          : 11/21/2016 8:59:30 PM

以下は真実です

$Object.text -eq $NULL
$Object.NotPresent -eq $NULL

-not $Object.text
-not $Object.NotPresent

したがって、名前でプロパティを明示的にチェックする以前の回答は、そのプロパティが存在しないことを確認するための最も正しい方法です。


1

nullに対してチェックするだけです。

($myObject.MyProperty -ne $null)

PowerShellをStrictMode設定していない場合、これはプロパティが存在しない場合でも機能します。

$obj = New-Object PSObject;                                                   
Add-Member -InputObject $obj -MemberType NoteProperty -Name Foo -Value "Bar";
$obj.Foo; # Bar                                                                  
($obj.MyProperty -ne $null);  # False, no exception

2
私が見る限り、これはプロパティが存在し、$ nullの場合は機能しますが、プロパティが存在しない場合は機能しません。nullチェックを実行するためにアクセスしようとすると、例外がスローされます。
ピーター

@Peterプロパティが存在しない場合に例外をスローするnullチェックの例を提供できますか。プロパティが存在せず、例外がない例を追加しました。
Shaun Luttin 2017

2
これを実行Set-Strictmode -version Latest;$obj = ConvertFrom-Json -InputObject '{"name":"test", "version":"1.1.0"}';If($obj.StartDate -ne $null){Write-Verbose -Message $obj.startDate -Verbose}すると、エラーが発生します。プロパティ 'StartDate'がこのオブジェクトに見つかりません。 ただし、コメントを修飾する必要があります。Strictmodeが設定されていない場合はコメントを取得できません。私はいつもそれを設定しているので、これをテストするまで気付かなかった!それでも、ほとんどの人は「Set-Strictmode」を使用している(または使用する必要がある)と思います。
ピーター

2
あなたがあなたの答えを修飾するならおそらく最高です、そして私は私の反対票を削除しますか?誰もが何かを学びました、それがポイントです:-)
ピーター

0

私は次の機能に行き着きました...

function HasNoteProperty(
    [object]$testObject,
    [string]$propertyName
)
{
    $members = Get-Member -InputObject $testObject 
    if ($members -ne $null -and $members.count -gt 0) 
    { 
        foreach($member in $members) 
        { 
            if ( ($member.MemberType -eq "NoteProperty" )  -and `
                 ($member.Name       -eq $propertyName) ) 
            { 
                return $true 
            } 
        } 
        return $false 
    } 
    else 
    { 
        return $false; 
    }
}

0

最近、strict-mode -version 2.0を設定するように切り替えましたが、nullテストが失敗しました。

関数を追加しました:

#use in strict mode to validate property exists before using
function exists {
  param($obj,$prop)
  try {
    if ($null -ne $obj[$prop]) {return $true}
    return $false
  } catch {
    return $false
  }
  return $false
}

今私はコーディングします

if (exists $run main) { ...

のではなく

if ($run.main -ne $null) { ...

そして、私たちは道を進んでいます。オブジェクトとハッシュテーブルで動作するようです

意図しない利点として、タイピングが少なくなります。


nullまたは空の場合、私は常に次を使用しました: IF([string] :: IsNullOrEmpty($ userID)){write-host "Null or empty"}

0

他の場所で機能するコードのデバッグに何時間も費やしたので、ディスカッションに追加したかっただけです。

CBによる回答変数をプロパティの名前(文字列として)と照合するのに適しています。変数がプロパティ名の一部と一致したときに問題が発生しました。

if([bool]($allFiles.PSobject.Properties.name -match $_.Name) -ne $true){

後でそれを使用してオブジェクトのプロパティを参照しましたが、別のプロパティの一部にしか一致せず、その正確な名前の実際のプロパティが存在しなかったため、操作は値 'null'を返しました。

後になってようやくdan-gphによって提案されたソリューションを使用しました。これは非常に優れています。

if([bool]($_.Name -in $allFiles.PSobject.Properties.Name) -ne $true){

これにより、2つの値が同一であることが保証されました。どこを見ればよいかはわかっていましたが、問題が2文字の文字列と一致するいくつかの名前であることがわかっても苦痛でした。プレフィックスですが、それ以外は同じです。


-1

PowerShell Core 6.0(ベータ版)でPowerShellを使い始めたところですが、次のように機能します。

if ($members.NoteProperty) {
   # NoteProperty exist
}

または

if (-not $members.NoteProperty) {
   # NoteProperty does not exist
}

1
strictmodeがオンになっていない
Casper

-1

あなたはチェックすることができます:

($Member.PropertyNames -contains "Name") これにより、Namedプロパティがチェックされます


-1

配列内のどのオブジェクトにプロパティがあるかを識別するため

$HasProperty = $ArrayOfObjects | Where-Object {$_.MyProperty}

プロパティが存在しない場合、StrictModeで失敗します。
user28647 4019
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.