使用PowerShell获取Azure网络信息的脚本问题排查与优化
解决Azure子网信息批量导出CSV的问题
直接上可运行的脚本,完全满足你的需求——每个子网对应一条记录,包含订阅名、资源组、VNet、子网、NSG、路由表等所有字段,导出的CSV可以直接在Excel里分析:
# 登录Azure(如果未登录的话) Connect-AzAccount # 获取所有订阅 $subscriptions = Get-AzSubscription # 初始化结果数组 $results = @() foreach ($sub in $subscriptions) { # 切换到当前订阅 Select-AzSubscription -SubscriptionObject $sub | Out-Null # 获取当前订阅下所有虚拟网络 $vnets = Get-AzVirtualNetwork foreach ($vnet in $vnets) { # 遍历VNet下的每个子网 foreach ($subnet in $vnet.Subnets) { # 获取子网关联的NSG(如果有) $nsg = $null if ($subnet.NetworkSecurityGroup.Id) { $nsgName = ($subnet.NetworkSecurityGroup.Id -split '/')[-1] $nsg = Get-AzNetworkSecurityGroup -Name $nsgName -ResourceGroupName $vnet.ResourceGroupName } # 获取子网关联的路由表(如果有) $routeTable = $null if ($subnet.RouteTable.Id) { $rtName = ($subnet.RouteTable.Id -split '/')[-1] $routeTable = Get-AzRouteTable -Name $rtName -ResourceGroupName $vnet.ResourceGroupName } # 为每个子网创建独立的自定义对象(扁平结构,避免数组) $resultObj = [PSCustomObject]@{ SubscriptionName = $sub.Name ResourceGroupName = $vnet.ResourceGroupName VNetName = $vnet.Name VNetAddressSpace = $vnet.AddressSpace.AddressPrefixes -join ';' SubnetName = $subnet.Name SubnetAddressPrefix = $subnet.AddressPrefix NSGName = if ($nsg) { $nsg.Name } else { "无" } NSGRulesCount = if ($nsg) { $nsg.SecurityRules.Count } else { 0 } RouteTableName = if ($routeTable) { $routeTable.Name } else { "无" } RouteTableRoutesCount = if ($routeTable) { $routeTable.Routes.Count } else { 0 } } # 添加到结果数组 $results += $resultObj } } } # 导出到CSV文件 $results | Export-Csv -Path "AzureSubnetDetails.csv" -NoTypeInformation -Encoding UTF8
关键解决点说明:
- 按子网拆分记录:不再把多个子网塞到一个对象的数组字段里,而是为每个子网单独生成一条记录,完美适配Excel的行式分析需求。
- 避免System.Object[]显示:所有字段都用扁平结构,数组类型的内容(比如VNet的地址空间)用
-join ';'转成字符串,方便Excel里查看和拆分。 - 关联NSG和路由表:通过子网对象里的
NetworkSecurityGroup.Id和RouteTable.Id字段,提取名称后查询对应的资源,把NSG名称、规则数,路由表名称、路由数都明确展示出来。 - 遍历所有订阅:自动处理当前账号下的所有订阅,不用手动切换。
运行脚本后,打开导出的CSV就能看到每条子网的完整信息,直接在Excel里排序、筛选、透视都没问题。
内容的提问来源于stack exchange,提问作者learner
相关产品推荐
相关产品推荐

