【问题标题】:How to access powershell PSCustomObject variable with variable (from json)如何使用变量访问powershell PSCustomObject变量(来自json)
【发布时间】:2020-02-06 13:39:45
【问题描述】:

我有一个 PSCustomObject,其中包含如下子对象列表:

vmssSystemUpdatesMonitoringEffect                                   : @{type=String; metadata=; allowedValues=System.Object[]; defaultValue=AuditIfNotExists}
vmssEndpointProtectionMonitoringEffect                              : @{type=String; metadata=; allowedValues=System.Object[]; defaultValue=AuditIfNotExists}
vmssOsVulnerabilitiesMonitoringEffect                               : @{type=String; metadata=; allowedValues=System.Object[]; defaultValue=AuditIfNotExists}
systemUpdatesMonitoringEffect                                       : @{type=String; metadata=; allowedValues=System.Object[]; defaultValue=AuditIfNotExists}
systemConfigurationsMonitoringEffect                                : @{type=String; metadata=; allowedValues=System.Object[]; defaultValue=AuditIfNotExists}

等等

部分对象为 JSON:

{
  "vmssSystemUpdatesMonitoringEffect": {
    "type": "String",
    "metadata": {
      "displayName": "System updates on virtual machine scale sets should be installed",
      "description": "Enable or disable virtual machine scale sets reporting of system updates"
    },
    "allowedValues": [
      "AuditIfNotExists",
      "Disabled"
    ],
    "defaultValue": "AuditIfNotExists"
  },
  "vmssEndpointProtectionMonitoringEffect": {
    "type": "String",
    "metadata": {
      "displayName": "Endpoint protection solution should be installed on virtual machine scale sets",
      "description": "Enable or disable virtual machine scale sets endpoint protection monitoring"
    },
    "allowedValues": [
      "AuditIfNotExists",
      "Disabled"
    ],
    "defaultValue": "AuditIfNotExists"
  },
  "vmssOsVulnerabilitiesMonitoringEffect": {
    "type": "String",
    "metadata": {
      "displayName": "Vulnerabilities in security configuration on your virtual machine scale sets should be remediated",
      "description": "Enable or disable virtual machine scale sets OS vulnerabilities monitoring"
    },
    "allowedValues": [
      "AuditIfNotExists",
      "Disabled"
    ],
    "defaultValue": "AuditIfNotExists"
  }
}

我得到数组的键

$Keys = $Hash | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name

我可以将键放入数组并对其进行迭代,但我无法通过为键提供变量来访问属性:

foreach ($key in $Keys) {
        Write-Host "key" $key
        $data = $KeyValue.$key  
}

结果: 关键 aadAuthenticationInServiceFabricMonitoringEffect

数据为空

但是,这是可行的:

$KeyValue.vmssSystemUpdatesMonitoringEffect

还有这个:

$key= "aadAuthenticationInServiceFabricMonitoringEffect"
$KeyValue.$key

我怎样才能让这个与变量一起工作?

【问题讨论】:

  • 如果我在导入您的 json 后查看$json.vmssEndpointProtectionMonitoringEffect.psobject.Properties.name,它会起作用...如果您在aadAuthenticationInServiceFabricMonitoringEffect 上执行.gettype(),那么对象类型是什么? (因为您遇到的问题不在 json 示例中)
  • 对象类型为 PSCustomObject
  • 恐怕在提供可重复的样本之前无法进行诊断。 PSCustomObject 将返回它的成员。也许尝试Get-Member 看看它的属性是否可能不是NoteProperty 类型。还要确保aadAuthenticationInServiceFabricMonitoringEffect 的路径与$Keyvalue.aadAuthenticationInServiceFabricMonitoringEffect 的路径相同,而实际路径是其他路径,例如:$Keyvalue.Me.aadAuthenticationInServiceFabricMonitoringEffect 那么这可以解释为什么你没有得到数据。
  • 如果您碰巧安装了 Azure Az 模块,那么您可以运行: $Policyset = Get-AzPolicySetDefinition -Name 1f3afdf9-d0c9-4c3d-847f-89da613e70a8 $policyHash = $Policyset.Properties.parameters
  • 查看我编辑的答案。这与我在原始答案中公开的原理相同,但我使用了您提供的确切命令并且它正在工作。让我知道我是否误解了您要执行的操作,或者如果它有效,请将其标记为已接受:)

标签: json powershell pscustomobject


【解决方案1】:

要遍历 PSObject 的属性,您需要使用 $YourObject.psobject.Properties.Name 循环访问属性

请参阅下面的示例,该示例基于您提供的信息。

$Policyset = Get-AzPolicySetDefinition
$Policyset = Get-AzPolicySetDefinition -Name 1f3afdf9-d0c9-4c3d-847f-89da613e70a8 
$policyHash = $Policyset.Properties.parameters

$DataSet = $policyHash.aadAuthenticationInServiceFabricMonitoringEffect
$Keys = $DataSet.psobject.Properties.name

foreach ($key in $Keys) {
    Write-Host $Key -ForegroundColor Cyan
    Write-Host $DataSet.$key
}

结果

补充说明 由于您添加了您想要迭代嵌套属性,请查看此处提供的答案。 iterate-over-psobject-properties-in-powershell。由于对父对象的引用,请注意有关无限循环的一点,因为这确实适用于您的情况。

【讨论】:

  • $data = $KeyValue.$key 你是说$item.$key 吗?
  • @MikeL'Angelo 绝对。我分心了。谢谢你的收获:)
  • 这就是我认为它的工作方式。但是,正如我在我的问题上所写的那样,由于某种原因,这对我不起作用。
  • @Kamsiinov 你能拿走你的对象,在上面使用Convert-to-Json 并将其添加到你的问题中(在编辑了其他值不应该看到的任何内容之后)?如果我们看到实际的对象结构并将其转换回对象,将很容易提供准确的答案。
  • 我添加的是 JSON。这个对象对我来说看起来很正常,但它的行为不像普通对象,因为它是 PSCustomObject
【解决方案2】:

在你的例子中,不是吗:

$hash = get-content file.json | convertfrom-json
$Keys = $Hash | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name
$data = foreach ($key in $Keys) {
  $hash.$key  
}
$data


type   metadata                     allowedValues
----   --------                     -------------
String @{displayName=Endpoint prote {AuditIfNotExists, Disabled}
String @{displayName=Vulnerabilitie {AuditIfNotExists, Disabled}
String @{displayName=System updates {AuditIfNotExists, Disabled}

对我来说,如果对象很难使用,那么设计就是糟糕的。我更喜欢这种方式,作为 3 个相似对象的数组:

[
    {
        "header":  "vmssSystemUpdatesMonitoringEffect",
        "type":  "String",
        "metadata":  {
                         "displayName":  "System updates on virtual machine scale sets should be installed",
                         "description":  "Enable or disable virtual machine scale sets reporting of system updates"
                     },
        "allowedValues":  [
                              "AuditIfNotExists",
                              "Disabled"
                          ],
        "defaultValue":  "AuditIfNotExists"
    },
    {
        "header":  "vmssEndpointProtectionMonitoringEffect",
        "type":  "String",
        "metadata":  {
                         "displayName":  "Endpoint protection solution should be installed on virtual machine scale sets",
                         "description":  "Enable or disable virtual machine scale sets endpoint protection monitoring"
                     },
        "allowedValues":  [
                              "AuditIfNotExists",
                              "Disabled"
                          ],
        "defaultValue":  "AuditIfNotExists"
    },
    {
        "header":  "vmssOsVulnerabilitiesMonitoringEffect",
        "type":  "String",
        "metadata":  {
                         "displayName":  "Vulnerabilities in security configuration on your virtual machine scale sets should be remediated",
                         "description":  "Enable or disable virtual machine scale sets OS vulnerabilities monitoring"
                     },
        "allowedValues":  [
                              "AuditIfNotExists",
                              "Disabled"
                          ],
        "defaultValue":  "AuditIfNotExists"
    }
]

然后:

cat file.json | convertfrom-json

header        : vmssSystemUpdatesMonitoringEffect
type          : String
metadata      : @{displayName=System updates on virtual machine scale sets should be installed; description=Enable or disable virtual machine scale sets reporting of system updates}
allowedValues : {AuditIfNotExists, Disabled}
defaultValue  : AuditIfNotExists

header        : vmssEndpointProtectionMonitoringEffect
type          : String
metadata      : @{displayName=Endpoint protection solution should be installed on virtual machine scale sets; description=Enable or disable virtual machine scale sets endpoint
                protection monitoring}
allowedValues : {AuditIfNotExists, Disabled}
defaultValue  : AuditIfNotExists

header        : vmssOsVulnerabilitiesMonitoringEffect
type          : String
metadata      : @{displayName=Vulnerabilities in security configuration on your virtual machine scale sets should be remediated; description=Enable or disable virtual machine scale
                sets OS vulnerabilities monitoring}
allowedValues : {AuditIfNotExists, Disabled}
defaultValue  : AuditIfNotExists

【讨论】:

  • 是的,应该是这样的。最初,我将对象作为 PSCustomObject。然后我需要将其转换为 JSON,将其放入磁盘,从那里读取内容并将其读回 PSObject。相反,我想跳过 JSON 的内容并直接使用 PS。
【解决方案3】:

假设您有一个类似于此的对象:

$KeyValue = @{
vmssSystemUpdatesMonitoringEffect = @{
    type='String'; 
    metadata=''; 
    allowedValues=@(1,2,3); 
    defaultValue='AuditIfNotExists'}
}

我们基本上有一个键值对,其中顶层只包含一个键vmssSystemUpdatesMonitoringEffect,其值是它自己的嵌套哈希表。

我们可以通过首先在哈希表中查找和.Keys,然后在其中的foreach 中查找任何.Keys 并获取它们的值来非常容易地解析。

$KeyValue = @{vmssSystemUpdatesMonitoringEffect = @{type='String'; metadata=''; allowedValues=@(1,2,3); defaultValue='AuditIfNotExists'}}
foreach($key in $KeyValue.Keys){
    $nestedKeys = $KeyValue.$key.Keys
    "parsing node $key in `$KeyValue` which has $($nestedKeys.Count) nested keys"

    foreach($nestedkey in $nestedKeys){
        "--parsing nested key $nestedKey"
        "--$($KeyValue.$key.$nestedKey)"
        }
}

这会给我们一个输出:

parsing node vmssSystemUpdatesMonitoringEffect in $KeyValue which has 4 nested keys
--parsing nested key defaultValue
--AuditIfNotExists
--parsing nested key allowedValues
--1 2 3
--parsing nested key type
--String
--parsing nested key metadata
--

这应该会让你开始你感兴趣的道路。

如果你有一个包含哈希表的 PSCustomObject

首先,我非常非常抱歉,让您最终遭受这种痛苦。

其次,如果你在这种情况下,你必须使用两种技术来枚举你的邪恶混蛋对象的节点。

$KeyValue = [pscustomobject]@{vmssSystemUpdatesMonitoringEffect = @{type='String'; metadata=''; allowedValues=@(1,2,3); defaultValue='AuditIfNotExists'}}
$keys = get-member -InputObject $keyvalue -MemberType NoteProperty 
foreach($key in $keys){
    $nestedKeys = $KeyValue.$($key.Name).Keys
    "parsing node $($key.Name) in `$KeyValue` which has $($nestedKeys.Count) nested keys"

    foreach($nestedkey in $nestedKeys){
        "--parsing nested key $nestedKey"
        "--$($KeyValue.$($key.Name).$nestedKey)"
        }
}

最大的区别是我们必须使用Get-Member cmdlet 检索所有键,并指定我们要检索具有NoteProperty 类型的成员。这为我们提供了 CustomObject 的所有属性,然后我们将逐步了解这些属性,查找具有属性的哈希表。

下一组奇怪的是$nestedKeys = $KeyValue.$($key.Name).Keys 这一行,它使用 PowerShell 的 subExpression 运算符运行 $( )symbols 中的项目并将输出视为字符串。类似于运行$KeyValue.vmssSystemUpdatesMonitoringEffect.Keys

除此之外,语法基本相同。

【讨论】:

  • 这个对象是一个 PSCustomObject 所以它看起来不像正常的 keyValue 对。
  • 我更新了一个将其作为 PowerShell 对象执行的示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-24
  • 2021-03-16
  • 1970-01-01
相关资源
最近更新 更多