【问题标题】:Add key/value pair to hashtable (nested in an array, nested in a hashtable)将键/值对添加到哈希表(嵌套在数组中,嵌套在哈希表中)
【发布时间】:2018-04-21 07:02:43
【问题描述】:

请原谅,但我不知道正确的术语。

假设如下哈希表:

$ConfigurationData = @{
    AllNodes = @(
        @{
            NodeName="*"
            PSDscAllowPlainTextPassword=$True
            PsDscAllowDomainUser=$True
        }
    )
}

如何让它看起来像这样:

$ConfigurationData = @{
    AllNodes = @(
        @{
            NodeName="*"
            PSDscAllowPlainTextPassword=$True
            PsDscAllowDomainUser=$True
            NewItem = "SomeNewValue"
            AnotherNewItem = "Hello"
        }
    )
}

我能做到:

$ConfigurationData.AllNodes += @{NewItem = "SomeNewValue"}
$ConfigurationData.AllNodes += @{AnotherNewItem  = "Hello"}

$ConfgurationData.AllNodes 看起来不错:

$ConfigurationData.AllNodes

Name                           Value                                                                                                                                            
----                           -----                                                                                                                                            
NodeName                       *                                                                                                                                                
PSDscAllowPlainTextPassword    True                                                                                                                                             
PsDscAllowDomainUser           True                                                                                                                                             
NewItem                        SomeNewValue                                                                                                                                     
AnotherNewItem                 Hello  

但将其转换为 JSON 则另当别论:

$ConfigurationData | ConvertTo-Json
{
    "AllNodes":  [
                     {
                         "NodeName":  "*",
                         "PSDscAllowPlainTextPassword":  true,
                         "PsDscAllowDomainUser":  true
                     },
                     {
                         "NewItem":  "SomeNewValue"
                     },
                     {
                         "AnotherNewItem":  "Hello"
                     }
                 ]
}

NewItemAnotherNewItem 在它们自己的哈希表中,而不是在第一个哈希表中,这会导致 DSC 不稳定:

ValidateUpdate-ConfigurationData : all elements of AllNodes need to be hashtable and has a property NodeName.


我可以执行以下操作,从而得到正确的结果:

$ConfigurationData = @{
    AllNodes = @(
        @{
            NodeName="*"
            PSDscAllowPlainTextPassword=$True
            PsDscAllowDomainUser=$True
        }
    )
}

#$ConfigurationData.AllNodes += @{NewItem = "SomeNewValue"}
#$ConfigurationData.AllNodes += @{AnotherNewItem  = "Hello"}

foreach($Node in $ConfigurationData.AllNodes.GetEnumerator() | Where-Object{$_.NodeName -eq "*"}) 
{
            $node.add("NewItem", "SomeNewValue")
            $node.add("AnotherNewItem", "Hello")
}

$ConfigurationData | ConvertTo-Json
{
    "AllNodes":  [
                     {
                         "NodeName":  "*",
                         "PSDscAllowPlainTextPassword":  true,
                         "NewItem":  "SomeNewValue",
                         "AnotherNewItem":  "Hello",
                         "PsDscAllowDomainUser":  true
                     }
                 ]
}

但与$ConfigurationData.AllNodes += @{NewItem = "SomeNewValue"} 这样的行相比,这似乎有点过头了

我也尝试过但失败了:

$ConfigurationData.AllNodes.GetEnumerator() += @{"NewItem" = "SomeNewValue"}

有没有类似的方法来定位正确的“元素”?

【问题讨论】:

    标签: json powershell hashtable


    【解决方案1】:

    这一行在数组级别添加一个项目。

    $ConfigurationData.AllNodes += @{NewItem = "SomeNewValue"}
    

    实际上,您希望添加到数组的第一个元素,这是您的哈希表:

    ($ConfigurationData.AllNodes)[0] += @{"new item" = "test"}
    

    【讨论】:

    • 谢谢。很简单。我怎么没想到。 dsc 编译也很开心。
    【解决方案2】:

    您的问题是由于您在内部哈希表周围的$ConfigurationData 的初始声明中放置了@() 括号,这使它成为一个数组。

    根据 gms0ulman 的回答,您需要使用数组索引运算符来访问该数组的索引,然后修改那里的属性。例如对于第一个元素:

    $ConfigurationData.AllNodes[0].'NewItem' = 'SomeNewValue'
    $ConfigurationData.AllNodes[0].'AnotherNewItem' = 'Hello'
    

    【讨论】:

    • 谢谢。尽管 JSON 输出是正确的,删除​​ @(),但 DSC 无法编译。我在曲中引用了同样的错误。 (我知道我没有明确询问 DSC,但其他人可能会发现此页面遇到了相同的 DSC 问题)。
    • 修改了我的答案,但基本上 gms0ulman 是正确的。 @() 将所有节点声明为一个数组,然后您将使用哈希表填充该数组,因此您需要访问其数组索引。
    【解决方案3】:

    其实我唯一没试过的:

    $ConfigurationData = @{
        AllNodes = @(
            @{
                NodeName="*"
                PSDscAllowPlainTextPassword=$True
                PsDscAllowDomainUser=$True
            }
        )
    }
    
    $ConfigurationData.AllNodes.GetEnumerator().Add("NewItem","SomeNewValue")
    
    $ConfigurationData.AllNodes.GetEnumerator().Add("AnotherNewItem","Hello")
    
    $ConfigurationData | ConvertTo-Json
    
    
    
    
    {
        "AllNodes":  [
                         {
                             "NodeName":  "*",
                             "PSDscAllowPlainTextPassword":  true,
                             "NewItem":  "SomeNewValue",
                             "AnotherNewItem":  "Hello",
                             "PsDscAllowDomainUser":  true
                         }
                     ]
    }
    

    我有点理解GetEnumerator 位。它会创建一个索引,以便 PS 可以处理这些项目。

    但我不明白为什么我必须使用.Add() 方法而+=@{} 不起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-17
      • 2012-08-07
      • 1970-01-01
      • 2017-12-11
      • 1970-01-01
      • 2020-07-02
      • 1970-01-01
      相关资源
      最近更新 更多