How can you test if an object has a specific property?
Appreciate I can do ...
$members = Get-Member -InputObject $myobject
and then foreach
through the $members
, but is there a function to test if the object has a specific property?
Additional Info: The issue is I'm importing two different sorts of CSV file, one with two columns, the other with three. I couldn't get the check to work with "Property", only with "NoteProperty" ... whatever the difference is
if ( ($member.MemberType -eq "NoteProperty" ) -and ($member.Name -eq $propertyName) )
This question is related to
powershell
powershell-3.0
Just to clarify given the following object
$Object
With the following properties
type : message
user : [email protected]
text :
ts : 11/21/2016 8:59:30 PM
The following are true
$Object.text -eq $NULL
$Object.NotPresent -eq $NULL
-not $Object.text
-not $Object.NotPresent
So the earlier answers that explicitly check for the property by name is the most correct way to verify that that property is not present.
I ended up with the following function ...
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;
}
}
Real similar to a javascript check:
foreach($member in $members)
{
if($member.PropertyName)
{
Write $member.PropertyName
}
else
{
Write "Nope!"
}
}
I just started using PowerShell with PowerShell Core 6.0 (beta) and following simply works:
if ($members.NoteProperty) {
# NoteProperty exist
}
or
if (-not $members.NoteProperty) {
# NoteProperty does not exist
}
This is succinct and readable:
"MyProperty" -in $MyObject.PSobject.Properties.Name
We can put it in a function:
function HasProperty($object, $propertyName)
{
$propertyName -in $object.PSobject.Properties.Name
}
For identifying which of the objects in an array have a property
$HasProperty = $ArrayOfObjects | Where-Object {$_.MyProperty}
For me MyProperty" -in $MyObject.PSobject.Properties.Name
didn't work, however
$MyObject.PSobject.Properties.Name.Contains("MyProperty")
works
Just check against null.
($myObject.MyProperty -ne $null)
If you have not set PowerShell to StrictMode, this works even if the property does not exist:
$obj = New-Object PSObject;
Add-Member -InputObject $obj -MemberType NoteProperty -Name Foo -Value "Bar";
$obj.Foo; # Bar
($obj.MyProperty -ne $null); # False, no exception
I've been using the following which returns the property value, as it would be accessed via $thing.$prop
, if the "property" would be to exist and not throw a random exception. If the property "doesn't exist" (or has a null value) then $null
is returned: this approach functions in/is useful for strict mode, because, well, Gonna Catch 'em All.
I find this approach useful because it allows PS Custom Objects, normal .NET objects, PS HashTables, and .NET collections like Dictionary to be treated as "duck-typed equivalent", which I find is a fairly good fit for PowerShell.
Of course, this does not meet the strict definition of "has a property".. which this question may be explicitly limited to. If accepting the larger definition of "property" assumed here, the method can be trivially modified to return a boolean.
Function Get-PropOrNull {
param($thing, [string]$prop)
Try {
$thing.$prop
} Catch {
}
}
Examples:
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"
And, this behavior might not [always] be desired.. ie. it's not possible to distinguish between x.Count
and x["Count"]
.
You could check with:
($Member.PropertyNames -contains "Name")
this will check for the Named property
You can use Get-Member
if(Get-Member -inputobject $var -name "Property" -Membertype Properties){
#Property exists
}
If you are using StrictMode and the psobject might be empty, it will give you an error.
For all purposes this will do:
if (($json.PSobject.Properties | Foreach {$_.Name}) -contains $variable)
I recently switch to set strict-mode -version 2.0 and my null tests failed.
I added a function:
#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
}
Now I code
if (exists $run main) { ...
rather than
if ($run.main -ne $null) { ...
and we are on our way. Seems to work on objects and hashtables
As an unintended benefit it is less typing.
Try this for a one liner that is strict safe.
[bool]$myobject.PSObject.Properties[$propertyName]
For example:
Set-StrictMode -Version latest;
$propertyName = 'Property1';
$myobject = [PSCustomObject]@{ Property0 = 'Value0' };
if ([bool]$myobject.PSObject.Properties[$propertyName]) {
$value = $myobject.$propertyName;
}
Source: Stackoverflow.com