如何让PowerShell导出Azure防火墙规则时无数据仍保留CSV表头
解决Azure防火墙规则导出无数据时生成带表头CSV的问题
修改后的完整脚本
function create($path) { $exists = Test-Path -path $path Write-Host "tried the following path: $path, it" $(If ($exists) {"Exists"} Else {"Does not Exist!"}) if (!($exists)) { New-Item $path -itemType Directory } } # reading file contents $subs_file = "C:\script\Subscriptions.xlsx" $azSubs = Import-Excel $subs_file $azSubs $output_folder = "C:\audit-automation" # creating folder for outputing data create("$output_folder") # 定义CSV表头属性(与Select-Object中的label对应) $csvHeaders = @( 'NSG Name', 'NSG Location', 'Rule Name', 'Source', 'Source Application Security Group', 'Source Port Range', 'Access', 'Priority', 'Direction', 'Destination', 'Destination Application Security Group', 'Destination Port Range', 'Resource Group Name', 'Subscription Name' ) # iterating over subscriptions ForEach ( $sub in $azSubs ) { $azsub = $sub.Subscription $app = $sub.Application $azsub $app # setting config for azure Set-AzContext -SubscriptionName $azsub # FIREWALL RULES $azNsgs = Get-AzNetworkSecurityGroup # iterating over retrieved NSGs $Output = ForEach ( $azNsg in $azNsgs ) { #Export custom rules Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $azNsg | ` Select-Object @{label = 'NSG Name'; expression = { $azNsg.Name } }, ` @{label = 'NSG Location'; expression = { $azNsg.Location } }, ` @{label = 'Rule Name'; expression = { $_.Name } }, ` @{label = 'Source'; expression = { $_.SourceAddressPrefix } }, ` @{label = 'Source Application Security Group'; expression = { if ($_.SourceApplicationSecurityGroups) { $_.SourceApplicationSecurityGroups.id.Split('/')[-1] } else { $null } } }, @{label = 'Source Port Range'; expression = { $_.SourcePortRange } }, Access, Priority, Direction, ` @{label = 'Destination'; expression = { $_.DestinationAddressPrefix } }, ` @{label = 'Destination Application Security Group'; expression = { if ($_.DestinationApplicationSecurityGroups) { $_.DestinationApplicationSecurityGroups.id.Split('/')[-1] } else { $null } } }, ` @{label = 'Destination Port Range'; expression = { $_.DestinationPortRange } }, ` @{label = 'Resource Group Name'; expression = { $azNsg.ResourceGroupName } }, @{label = 'Subscription Name'; expression = { $azsub } } } # creating folder to save create("$output_folder\$app") $csvPath = "$output_folder\$app\$app-firewall_rules_data$((Get-Date).ToString("yyyy-MM-dd")).csv" # 处理无数据情况:生成带表头的空CSV if (-not $Output) { # 创建包含所有表头属性的空对象 $emptyRow = New-Object PSObject foreach ($header in $csvHeaders) { Add-Member -InputObject $emptyRow -MemberType NoteProperty -Name $header -Value $null } $emptyRow | Export-Csv -Path $csvPath -NoTypeInformation -Append } else { $Output | Export-Csv -Path $csvPath -NoTypeInformation -Append } }
关键改动说明
- 定义表头数组:提前声明所有CSV列名,确保空数据场景下表头与有数据时完全一致
- 空数据处理逻辑:检查
$Output是否为空,若为空则创建包含所有表头的空对象并导出,保证CSV文件生成完整表头 - 空值安全处理:优化安全组的取值逻辑,避免空值时执行拆分操作导致的报错
- 添加
-NoTypeInformation参数:移除CSV文件开头多余的类型信息行,让输出更简洁规范
内容的提问来源于stack exchange,提问作者Rav
相关产品推荐
相关产品推荐

