如何在Powershell中更新散列表中数组中的数组?

eyh26e7m  于 2023-01-26  发布在  Shell
关注(0)|答案(1)|浏览(113)

我正在使用Powershell所需的状态配置,并且有一个单独的定义文档(psd 1),我通过

$ConfigData = Import-PowerShellDataFile "$Path"

这里我想根据一个环境变量来更新节点名,整个psd 1文件显示它的类型为哈希表(name和basetype如下),然后allnodes显示为一个数组,然后nodename显示为另一个数组。

Hashtable  System.Object                                                                                                 
Object[]   System.Array                                                                                                  
Object[]   System.Array

替换不持久(如下所示)。如果尝试将其重新分配给自身或副本,“在此对象上找不到属性”nodename“。请验证该属性是否存在yadda”

$ConfigData.AllNodes.NodeName -replace 'vms','vmp'
or
$ConfigDataHolder.AllNodes.NodeName = $ConfigData.AllNodes.NodeName -replace 'vms','vmp'

直接引用/赋值不会持续,下面的输出仍然是以前的服务器名,即使在克隆场景中也是如此。

$ConfigData.AllNodes.NodeName[2] = "something"
ttcibm8c

ttcibm8c1#

  • 由于您在 arrays 上使用属性访问来访问其 elements 的值,因此您利用了member-access enumeration
  • 然而,*成员访问枚举--按照设计--只适用于 * 获取 * 值,而不适用于 * 设置 (更新)它们
  • 不幸的是,尝试更新时的行为是 * 模糊的*,正如您所经历的:
  • 当您尝试将一个成员访问枚举属性 * 作为一个整体 * 赋值时,* 错误消息 * 是模糊的:它告诉你这样的属性不存在,因为在 setting 上它只查看 *array对象本身 *,即使它在 * geting * 上找到它,当它查看数组 elements 时;举个最小的例子:
$data = @{ arr = @(@{ subarr = 1, 2 }, @{ subarr = 3, 4 }) } 
 # !! ERROR " property 'subarr' cannot be found on this object"
 $data.arr.subarr = @(42, 43)
  • 如果你尝试一个特定的索引(例如[2]),但是索引所应用的数组本身是 * 通过成员访问枚举 * 获得的,那么赋值实际上是在一个 * 临时数组 * 上操作的,因此实际上被悄悄地丢弃了;举个最小的例子:
$data = @{ arr = @(@{ subarr = 1, 2 }, @{ subarr = 3, 4 }) } 
 # !! IGNORED, because .arr.subarr is the result of
 # !! member-access enumeration.
 $data.arr.subarr[0] = 42
  • 解决方案是将数组元素 * 单独地 * 作为更新的目标,或者使用单个索引(例如,[2]),或者在 * 循环 * 中,一个接一个地。

一个简单的例子:

$configData = @{
  AllNodes = @(
     @{
       NodeName = @(
        'Node1a', 
        'Node1b'
       ) 
     },
     @{ 
       NodeName = @(
         'Node2a',
         'Node2b'
       ) 
     }
  )
}

# OK: a specific element of *both* arrays involved - .AllNodes and .NodeName -
#     is targeted and can therefore be assigned to.
$configData.AllNodes[0].NodeName[1] = 'NewNode1b'

相关问题