You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell哈希表从模板添加新元素时引用重复问题求助

PowerShell哈希表复制后引用同步修改问题解决

你遇到的问题核心是PowerShell中哈希表的赋值为引用传递,而非值复制。直接将$test.serverTest赋值给新键时,所有新键都会指向同一个哈希表对象,修改其中一个的属性,其他引用该对象的键会同步变化。

原代码

$test=@{
    "serverTest"=@{
        "hostname"="abc"
        "services"=@{
            "serviceTest"=@{
                "filePath"="C:\hi";
                "group"=@("TEST" )
            }
        }
    }
}

$serverList = @{"server1"="group1"; "server2"="group2";}

Foreach($server in $serverList.Keys){
    $test[$server]=$test.serverTest
    Foreach($service in $test.serviceTest.services){
        $test[$server].services[$service].group+= $serverList[$server]
    }
}
$test.remove('serviceTest')

期望输出

$test=@{
    "server1"=@{
        "hostname"="abc"
        "services"=@{
            "serviceTest"=@{
                "filePath"="C:\hi";
                "group"=@("TEST","group1" )
            }
        }
    }
    "server2"=@{
        "hostname"="abc"
        "services"=@{
            "serviceTest"=@{
                "filePath"="C:\hi";
                "group"=@("TEST","group2" )
            }
        }
    }
}

实际输出

$test=@{
    "server1"=@{
        "hostname"="abc"
        "services"=@{
            "serviceTest"=@{
                "filePath"="C:\hi";
                "group"=@("TEST","group1","group2")
            }
        }
    }
    "server2"=@{
        "hostname"="abc"
        "services"=@{
            "serviceTest"=@{
                "filePath"="C:\hi";
                "group"=@("TEST","group1","group2")
            }
        }
    }
}

解决办法

要实现深度值复制,可以通过ConvertTo-Json和ConvertFrom-Json将哈希表序列化为JSON再反序列化,生成完全独立的新对象。修改循环中的赋值逻辑即可:

$test=@{
    "serverTest"=@{
        "hostname"="abc"
        "services"=@{
            "serviceTest"=@{
                "filePath"="C:\hi";
                "group"=@("TEST" )
            }
        }
    }
}

$serverList = @{"server1"="group1"; "server2"="group2";}

Foreach($server in $serverList.Keys){
    # 深度复制模板哈希表,生成独立对象
    $test[$server] = $test.serverTest | ConvertTo-Json -Depth 10 | ConvertFrom-Json -AsHashtable
    Foreach($serviceName in $test[$server].services.Keys){
        $test[$server].services[$serviceName].group += $serverList[$server]
    }
}
$test.remove('serverTest') # 修正原代码的键名错误,需删除模板键serverTest

关键说明

  • -Depth 10确保嵌套的多层哈希表能被完整序列化,可根据实际嵌套层数调整数值。
  • -AsHashtable让反序列化后的对象保持哈希表类型,方便后续属性修改操作。
  • 原代码末尾删除键名错误,需删除的是模板键serverTest而非serviceTest。

内容的提问来源于stack exchange,提问作者CaptainObv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 14:39:55