Powershell 从对象中选择 NoteProperty 类型对象
Powershell Selecting NoteProperty Type Objects From Object
我正在使用深度嵌套的 JSON,并且在 convertfrom-json 之后,需要能够遍历 convertfrom-json cmdlet 生成的对象的各个部分.
我无法提前知道对象中可能包含或不包含哪些 属性 名称,据我所知,可能存在数百种不同的属性。幸运的是,我看到的有帮助的一件事是我关心的每个属性都是“NoteProperty”类型。
这是一个例子:
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()
definition NoteProperty System.Management.Automation.PSCustomObject definition=@{$schema=https://schema.management.azure.com/providers/Microsof...
integrationAccount NoteProperty System.Management.Automation.PSCustomObject integrationAccount=@{id=[parameters('integrationAccounts_xxx_integration...
parameters NoteProperty System.Management.Automation.PSCustomObject parameters=@{$connections=}
state NoteProperty string state=Enabled
所以我认为创建一个函数会很简单,它 select 只有对象,对于当前正在处理的级别,'MemberType' 'NoteProperty'.
我已经尝试将对象通过管道传输到:
where-object { $_.MemberType -eq "NoteProperty" }
没有。
我也尝试过各种形式的 select-object,但似乎无法 select 正是我需要的。我从脚本专家那里找到了一篇关于使用标签和表达式的旧文章——但这似乎有点过分了,不是吗?有人能告诉我 select 只有 NoteProperty 项目的简单方法吗?
谢谢!
您可以使用隐藏的 .psobject.properties
遍历成员。
$json = @'
{
"users": [
{
"userId": 1,
"firstName": "Krish",
"lastName": "Lee",
"phoneNumber": "123456",
"emailAddress": "krish.lee@learningcontainer.com"
},
{
"userId": 2,
"firstName": "racks",
"lastName": "jacson",
"phoneNumber": "123456",
"emailAddress": "racks.jacson@learningcontainer.com"
}
]
}
'@ | ConvertFrom-Json
$json | foreach {
$_.psobject.properties | foreach {
Write-Host Property Name: $_.name
Write-Host Values: $_.value
}
}
您可以根据需要继续。
$json | foreach {
$_.psobject.properties | foreach {
$_.value | foreach {
$_.psobject.properties | foreach {
write-host Property name: $_.name
write-host Property value: $_.value
}
}
}
}
Property name: userId
Property value: 1
Property name: firstName
Property value: Krish
Property name: lastName
Property value: Lee
Property name: phoneNumber
Property value: 123456
Property name: emailAddress
Property value: krish.lee@learningcontainer.com
Property name: userId
Property value: 2
Property name: firstName
Property value: racks
Property name: lastName
Property value: jacson
Property name: phoneNumber
Property value: 123456
Property name: emailAddress
Property value: racks.jacson@learningcontainer.com
用通用解决方案补充:
以下代码段定义并调用 函数 Get-LeafProperty
,它递归遍历对象图 - 例如 ConvertFrom-Json
返回的 - 和 输出所有 leaf 属性 值,以及它们在层次结构 .
中的 name paths
# Define a walker function for object graphs:
# Get all leaf properties in a given object's hierarchy,
# namely properties of primitive and quasi-primitive types
# (.NET primitive types, plus those that serialize to JSON as a single value).
# Output:
# A flat collection of [pscustomobject] instances with .NamePath and .Value
# properties; e.g.:
# [pscustomobject] @{ NamePath = 'results.users[0].userId'; Value = 1 }
function Get-LeafProperty {
param([Parameter(ValueFromPipeline)] [object] $InputObject, [string] $NamePath)
process {
if ($null -eq $InputObject -or $InputObject -is [DbNull] -or $InputObject.GetType().IsPrimitive -or $InputObject.GetType() -in [string], [datetime], [datetimeoffset], [decimal], [bigint]) {
# A null-like value or a primitive / quasi-primitive type -> output.
# Note: Returning a 2-element ValueTuple would result in better performance, both time- and space-wise:
# [ValueTuple]::Create($NamePath, $InputObject)
[pscustomobject] @{ NamePath = $NamePath; Value = $InputObject }
}
elseif ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [System.Collections.IDictionary]) {
# A collection of sorts (other than a string or dictionary (hash table)),
# recurse on its elements.
$i = 0
foreach ($o in $InputObject) { Get-LeafProperty $o ($NamePath + '[' + $i++ + ']') }
}
else {
# A non-quasi-primitive scalar object or a dictionary:
# enumerate its properties / entries.
$props = if ($InputObject -is [System.Collections.IDictionary]) { $InputObject.GetEnumerator() } else { $InputObject.psobject.properties }
$sep = '.' * ($NamePath -ne '')
foreach ($p in $props) {
Get-LeafProperty $p.Value ($NamePath + $sep + $p.Name)
}
}
}
}
使用示例:
# Parse sample JSON with multiple hierarchy levels into a [pscustomobject]
# graph using ConvertFrom-Json.
$objectGraphFromJson = @'
{
"results": {
"users": [
{
"userId": 1,
"emailAddress": "jane.doe@example.com",
"attributes": {
"height": 165,
"weight": 60
}
},
{
"userId": 2,
"emailAddress": "john.doe@example.com",
"attributes": {
"height": 180,
"weight": 72
}
}
]
}
}
'@ | ConvertFrom-Json
# Get all leaf properties.
Get-LeafProperty $objectGraphFromJson
以上结果:
NamePath Value
-------- -----
results.users[0].userId 1
results.users[0].emailAddress jane.doe@example.com
results.users[0].attributes.height 165
results.users[0].attributes.weight 60
results.users[1].userId 2
results.users[1].emailAddress john.doe@example.com
results.users[1].attributes.height 180
results.users[1].attributes.weight 72
我正在使用深度嵌套的 JSON,并且在 convertfrom-json 之后,需要能够遍历 convertfrom-json cmdlet 生成的对象的各个部分.
我无法提前知道对象中可能包含或不包含哪些 属性 名称,据我所知,可能存在数百种不同的属性。幸运的是,我看到的有帮助的一件事是我关心的每个属性都是“NoteProperty”类型。
这是一个例子:
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()
definition NoteProperty System.Management.Automation.PSCustomObject definition=@{$schema=https://schema.management.azure.com/providers/Microsof...
integrationAccount NoteProperty System.Management.Automation.PSCustomObject integrationAccount=@{id=[parameters('integrationAccounts_xxx_integration...
parameters NoteProperty System.Management.Automation.PSCustomObject parameters=@{$connections=}
state NoteProperty string state=Enabled
所以我认为创建一个函数会很简单,它 select 只有对象,对于当前正在处理的级别,'MemberType' 'NoteProperty'.
我已经尝试将对象通过管道传输到:
where-object { $_.MemberType -eq "NoteProperty" }
没有。
我也尝试过各种形式的 select-object,但似乎无法 select 正是我需要的。我从脚本专家那里找到了一篇关于使用标签和表达式的旧文章——但这似乎有点过分了,不是吗?有人能告诉我 select 只有 NoteProperty 项目的简单方法吗?
谢谢!
您可以使用隐藏的 .psobject.properties
遍历成员。
$json = @'
{
"users": [
{
"userId": 1,
"firstName": "Krish",
"lastName": "Lee",
"phoneNumber": "123456",
"emailAddress": "krish.lee@learningcontainer.com"
},
{
"userId": 2,
"firstName": "racks",
"lastName": "jacson",
"phoneNumber": "123456",
"emailAddress": "racks.jacson@learningcontainer.com"
}
]
}
'@ | ConvertFrom-Json
$json | foreach {
$_.psobject.properties | foreach {
Write-Host Property Name: $_.name
Write-Host Values: $_.value
}
}
您可以根据需要继续。
$json | foreach {
$_.psobject.properties | foreach {
$_.value | foreach {
$_.psobject.properties | foreach {
write-host Property name: $_.name
write-host Property value: $_.value
}
}
}
}
Property name: userId
Property value: 1
Property name: firstName
Property value: Krish
Property name: lastName
Property value: Lee
Property name: phoneNumber
Property value: 123456
Property name: emailAddress
Property value: krish.lee@learningcontainer.com
Property name: userId
Property value: 2
Property name: firstName
Property value: racks
Property name: lastName
Property value: jacson
Property name: phoneNumber
Property value: 123456
Property name: emailAddress
Property value: racks.jacson@learningcontainer.com
用通用解决方案补充
以下代码段定义并调用 函数 Get-LeafProperty
,它递归遍历对象图 - 例如 ConvertFrom-Json
返回的 - 和 输出所有 leaf 属性 值,以及它们在层次结构 .
# Define a walker function for object graphs:
# Get all leaf properties in a given object's hierarchy,
# namely properties of primitive and quasi-primitive types
# (.NET primitive types, plus those that serialize to JSON as a single value).
# Output:
# A flat collection of [pscustomobject] instances with .NamePath and .Value
# properties; e.g.:
# [pscustomobject] @{ NamePath = 'results.users[0].userId'; Value = 1 }
function Get-LeafProperty {
param([Parameter(ValueFromPipeline)] [object] $InputObject, [string] $NamePath)
process {
if ($null -eq $InputObject -or $InputObject -is [DbNull] -or $InputObject.GetType().IsPrimitive -or $InputObject.GetType() -in [string], [datetime], [datetimeoffset], [decimal], [bigint]) {
# A null-like value or a primitive / quasi-primitive type -> output.
# Note: Returning a 2-element ValueTuple would result in better performance, both time- and space-wise:
# [ValueTuple]::Create($NamePath, $InputObject)
[pscustomobject] @{ NamePath = $NamePath; Value = $InputObject }
}
elseif ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [System.Collections.IDictionary]) {
# A collection of sorts (other than a string or dictionary (hash table)),
# recurse on its elements.
$i = 0
foreach ($o in $InputObject) { Get-LeafProperty $o ($NamePath + '[' + $i++ + ']') }
}
else {
# A non-quasi-primitive scalar object or a dictionary:
# enumerate its properties / entries.
$props = if ($InputObject -is [System.Collections.IDictionary]) { $InputObject.GetEnumerator() } else { $InputObject.psobject.properties }
$sep = '.' * ($NamePath -ne '')
foreach ($p in $props) {
Get-LeafProperty $p.Value ($NamePath + $sep + $p.Name)
}
}
}
}
使用示例:
# Parse sample JSON with multiple hierarchy levels into a [pscustomobject]
# graph using ConvertFrom-Json.
$objectGraphFromJson = @'
{
"results": {
"users": [
{
"userId": 1,
"emailAddress": "jane.doe@example.com",
"attributes": {
"height": 165,
"weight": 60
}
},
{
"userId": 2,
"emailAddress": "john.doe@example.com",
"attributes": {
"height": 180,
"weight": 72
}
}
]
}
}
'@ | ConvertFrom-Json
# Get all leaf properties.
Get-LeafProperty $objectGraphFromJson
以上结果:
NamePath Value
-------- -----
results.users[0].userId 1
results.users[0].emailAddress jane.doe@example.com
results.users[0].attributes.height 165
results.users[0].attributes.weight 60
results.users[1].userId 2
results.users[1].emailAddress john.doe@example.com
results.users[1].attributes.height 180
results.users[1].attributes.weight 72