PowerShell中ForEach-Object内$_变量值丢失问题排查
解决Azure角色分配脚本中Switch语句覆盖$_变量导致自定义属性访问失败的问题
问题场景
拉取Azure角色分配列表后,遍历每个对象添加自定义成员属性,后续通过Switch语句判断对象属性来设置自定义值时,Default分支设置$_.ResourceType时报错,提示属性不存在。追踪发现Switch执行后$_不再指向原角色分配对象。
原因分析
PowerShell的Switch语句在处理单个值(比如角色分配的Scope属性)时,会将块内的$_绑定到当前匹配的分支测试值(例如你定义的Scope字符串),而非原管道对象。此时$_的类型已经变成字符串,自然没有你之前添加的自定义属性,导致赋值报错。
解决方案
在进入Switch语句前,将原对象保存到一个临时变量中,后续所有操作都通过这个临时变量访问原对象,避免$_被覆盖。
修正后的代码示例
Get-AzRoleAssignment | ForEach-Object { # 将当前角色分配对象存入临时变量 $currentRole = $_ # 添加上自定义属性 $currentRole | Add-Member -MemberType NoteProperty -Name ResourceType -Value $null $currentRole | Add-Member -MemberType NoteProperty -Name CustomCategory -Value $null # 基于Scope属性判断,用临时变量操作原对象 switch ($currentRole.Scope) { { $_ -match '/subscriptions/.+/resourceGroups/.+' } { $currentRole.ResourceType = 'ResourceGroup' $currentRole.CustomCategory = '基础资源组' } { $_ -match '/subscriptions/.+/providers/Microsoft.Compute/virtualMachines/.+' } { $currentRole.ResourceType = 'VirtualMachine' $currentRole.CustomCategory = '计算资源' } default { $currentRole.ResourceType = 'Unknown' $currentRole.CustomCategory = '未分类资源' } } # 输出处理后的对象 $currentRole }
额外说明
如果要在Switch分支中同时使用匹配的属性值和原对象,临时变量的方式最直观可靠。也可以通过switch -InputObject $currentRole的方式让$_指向原对象,但需要在分支中额外判断属性值,反而不如临时变量简洁。
内容的提问来源于stack exchange,提问作者Matthew McDonald
相关产品推荐
相关产品推荐

