如何修正Azure PowerShell脚本以获取跨RG的子网NSG与路由表信息
Azure网络信息脚本优化方案
问题说明
现有PowerShell脚本用于获取Azure VNet、子网、NSG及路由表信息,但存在两个问题:
- 部分NSG和路由表与VNet不在同一资源组,原脚本通过错误的资源组参数查询,导致返回空信息;且
$subnet_rg无法正确获取资源组。 - 拼接NSG、路由表名称时,列末尾会多出冗余逗号。
优化后的脚本
$report = @() $path = "C:\Users\xxxx\OneDrive - Microsoft\Desktop\test\khan.csv" # 遍历所有订阅 foreach ($Sub in Get-AzSubscription) { $null = Select-AzSubscription -Subscription $Sub.Id # 用ID更可靠,避免名称重复 $vnets = Get-AzVirtualNetwork foreach ($vnet in $vnets) { foreach ($subnet in $vnet.Subnets) { # 初始化结果对象 $vnetInfo = [PSCustomObject]@{ SubscriptionName = $Sub.Name ResourceGroupName = $vnet.ResourceGroupName VNetName = $vnet.Name AddressSpace = $vnet.AddressSpace.AddressPrefixes -join ',' SubnetName = $subnet.Name SubnetAddressSpace = $subnet.AddressPrefix -join ',' NSG = $null RouteTable = $null RoutePropagationDisabled = $null } # 处理NSG:从子网关联的NSG ID解析资源信息 if ($subnet.NetworkSecurityGroup.Id) { $nsgIdParts = $subnet.NetworkSecurityGroup.Id -split '/' $nsgRg = $nsgIdParts[4] $nsgName = $nsgIdParts[-1] $vnetInfo.NSG = $nsgName } # 处理路由表:从子网关联的路由表ID解析资源信息 if ($subnet.RouteTable.Id) { $rtIdParts = $subnet.RouteTable.Id -split '/' $rtRg = $rtIdParts[4] $rtName = $rtIdParts[-1] # 获取路由表对象获取传播设置 $routeTable = Get-AzRouteTable -ResourceGroupName $rtRg -Name $rtName $vnetInfo.RouteTable = $rtName $vnetInfo.RoutePropagationDisabled = $routeTable.DisableBgpRoutePropagation.ToString() } $report += $vnetInfo } } } # 导出到CSV $report | Export-Csv -Path $path -NoTypeInformation -Encoding ASCII
关键优化点解析
1. 跨资源组NSG/路由表查询
- 子网对象的
NetworkSecurityGroup.Id和RouteTable.Id包含完整的资源路径,通过-split '/'拆分后,第5个元素(索引4)是资源组名称,最后一个元素是资源名称。 - 直接用解析出的资源组和名称查询,避免了原脚本中错误使用
$subnet_rg作为资源组参数的问题,同时支持跨资源组的关联资源查询。 - 注:Azure子网只能关联一个NSG和一个路由表,无需循环拼接,直接赋值即可;若后续有扩展需求,可改用数组收集后
-join ','。
2. 移除末尾逗号
- 摒弃原脚本中
+= "名称,"的字符串拼接方式:- 单个资源场景:直接赋值资源名称,无逗号冗余。
- 多资源场景:先将名称存入数组,最后用
-join ','合并,自动避免末尾逗号。 - 布尔值(如路由传播设置)直接转为字符串,无需拼接操作。
内容的提问来源于stack exchange,提问作者learner
相关产品推荐
相关产品推荐

