Private/Get-ArgusProperty.ps1
|
function Get-ArgusProperty { <# .SYNOPSIS Reads a (nested) property from a Graph object, returning $Default when any part is missing. .DESCRIPTION Graph responses omit properties that were not selected, and strict mode throws on missing properties. Use a dotted path for nested values, e.g. 'signInActivity.lastSuccessfulSignInDateTime'. Collection values are enumerated: use @(Get-ArgusProperty $x 'items' @()) to always get an array. #> [CmdletBinding()] [OutputType([object])] param( [Parameter(Mandatory, Position = 0)] [AllowNull()] [object] $InputObject, [Parameter(Mandatory, Position = 1)] [string] $Name, [Parameter(Position = 2)] [AllowNull()] [object] $Default = $null ) # A property whose name itself contains a dot (e.g. '@odata.type') wins over path navigation. if ($null -ne $InputObject -and $InputObject -isnot [System.Collections.IDictionary] -and $InputObject.PSObject.Properties[$Name]) { $value = $InputObject.PSObject.Properties[$Name].Value if ($null -eq $value) { return $Default } return $value } $current = $InputObject foreach ($part in $Name.Split('.')) { if ($null -eq $current) { return $Default } if ($current -is [System.Collections.IDictionary]) { if (-not $current.Contains($part)) { return $Default } $current = $current[$part] continue } $property = $current.PSObject.Properties[$part] if ($null -eq $property) { return $Default } $current = $property.Value } if ($null -eq $current) { return $Default } # Arrays are enumerated like any PowerShell output: wrap the call in @() to get a collection. $current } |