PowerShell Foreach循环使用PSCustomObject出现重复项问题求助
问题分析与修复
核心问题
- 循环变量误用:创建
PSCustomObject时用了集合变量$vm,而非当前循环的单VM对象$v,导致每次都取所有VM的名称/ID,生成大量重复或错误条目。 - JSON转换时机错误:把每个对象立即转成JSON存入数组,后续遍历时无法直接访问
VMname和scope属性(数组里是字符串,不是对象),同时会积累重复的JSON内容。 - 变量名不一致:数组定义为
$exclusionsVM1,但后续输出和遍历用的是$exclusionsVM,导致数据丢失或逻辑断裂。 - 数组扩展效率低:频繁用
+=扩展数组会反复创建新数组,同时容易引入重复数据。
修正后的脚本
# 初始化空数组存储豁免对象 $exclusionsVM = @() $skus = Get-Content ".\Dseries.txt" $subs = Get-AzSubscription foreach ($sub in $subs) { Set-AzContext -SubscriptionId $sub.Id -WarningAction Ignore | Out-Null # 获取当前订阅下的所有VM,变量名改为$vms避免混淆 $vms = Get-AzVm foreach ($v in $vms) { # 筛选符合条件的VM:D系列SKU且不在允许列表内 if (($v.HardwareProfile.VmSize -match "Standard_D") -and ($v.HardwareProfile.VmSize -notin $skus)) { # 使用当前循环的单个VM对象$v,而非集合$vms $waiverItem = [PSCustomObject]@{ VMname = $v.Name Scope = $v.Id } $exclusionsVM += $waiverItem } } } # 强制去重,彻底解决重复条目问题 $exclusionsVM = $exclusionsVM | Select-Object VMname, Scope -Unique # 统一转换为JSON后输出到文件 $exclusionsVM | ConvertTo-Json | Out-File ".\D_waiverlistVM.txt" Write-Host "共生成 $($exclusionsVM.Count) 条豁免条目" # 批量创建策略豁免 foreach ($exclusionVM in $exclusionsVM) { try { # 确保$Policy变量已提前定义(指向目标策略分配对象) New-AzPolicyExemption -Name $exclusionVM.VMname ` -PolicyAssignment $Policy ` -Scope $exclusionVM.Scope ` -ExemptionCategory Waiver Write-Host "已成功为VM '$($exclusionVM.VMname)' 添加豁免" -ForegroundColor Green } catch { Write-Host "为VM '$($exclusionVM.VMname)' 添加豁免时出错:$_" -ForegroundColor Red } }
关键修改说明
- 把集合变量名改为
$vms,循环内用$v访问单个VM属性,彻底避免取错值导致的重复 - 先收集PSCustomObject到数组,最后统一转JSON输出,保证后续遍历能正常访问对象属性
- 增加
Select-Object -Unique强制去重,从根源解决重复条目问题 - 统一变量名,避免因变量名不一致导致的数据丢失
- 优化执行日志,方便实时查看操作结果
内容的提问来源于stack exchange,提问作者kalyani
相关产品推荐
相关产品推荐

