PowerShell中Set-Variable读取JSON无法覆盖脚本参数问题
问题根因
赋值不生效是两个逻辑错误导致的:
- 作用域指定错误:
param块定义的$Dir属于脚本级作用域(script作用域),你在函数里用-Scope Global修改的是全局作用域的独立同名变量,根本不会影响脚本本身的参数变量。 - 值类型不匹配:你对JSON读取到的字段值做了
[array]强转,而你的JSON配置里所有字段都包在数组中,最终拿到的$elem_node是长度为1的数组(比如@("./source")),和param定义的[string]类型$Dir类型不匹配,就算作用域写对也会出现赋值异常。
修复方法
只需要修改两处逻辑即可:
- 把
Set-Variable的作用域参数从Global改为Script,直接操作脚本级变量,同时避免污染PowerShell全局会话环境。 - 读取JSON配置值时,根据参数类型做适配:单值字符串参数取配置数组的第0项即可,如果是支持多值的数组类参数,直接传递完整数组。
修复后的完整可运行代码:
param( [string]$Dir = "." ) function read_tool_json { $tool_json = "./tool.json" if (-not(Test-Path $tool_json)) { throw "Missing ./tool.json file" } Write-Host "Reading file: $tool_json" $tool_config = Get-Content -Raw $tool_json | ConvertFrom-Json foreach ($top_item in $tool_config.psobject.Properties) { Write-Host "Load config group: $($top_item.Name)" $config_node = $top_item.Value foreach ($config_item in $config_node.psobject.Properties) { $elem_name = $config_item.Name # 适配当前JSON字段均为数组包裹的格式,单值参数取首项 $elem_value = $config_item.Value | Select-Object -First 1 Write-Host "Override script param: $elem_name = $elem_value" # 指定script作用域强制覆盖同名脚本参数 Set-Variable -Name $elem_name -Value $elem_value -Scope Script -Force } } } read_tool_json $script:Dir.GetType() Write-Host "dir:($Dir)"
补充说明
- 如果后续需要让部分配置支持多值(比如
ExcludeVhd需要配置多个匹配规则),只需要把param块中对应参数的类型改为[string[]],赋值时去掉Select-Object -First 1的逻辑直接传完整数组即可。 - 非必要不要使用
Global作用域修改变量,会污染当前PowerShell会话的变量空间,导致其他脚本运行异常。
内容的提问来源于stack exchange,提问作者Bimo
相关产品推荐
相关产品推荐

