I have created a script which exports the firewall rules from Azure and it works Perfectly , However I need to create .csv with headers even if there is no data. Currently it is creating a blank file.
``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:scriptSubscriptions.xlsx"
$azSubs = Import-Excel $subs_file
$azSubs
$output_folder = "C:audit-automation"
# creating folder for outputing data
create("$output_folder")
# New-Item $output_folder -itemType Directory
# iterating over subscriptions
ForEach ( $sub in $azSubs ) {
# sub
$azsub = $sub.Subscription
# app
$app = $sub.Application
$azsub
$app
# creating folder to save data for apps
# New-Item $output_folder$app -itemType Directory
# 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 = { $_.SourceApplicationSecurityGroups.id.Split('/')[-1] } },
@{label = 'Source Port Range'; expression = { $_.SourcePortRange } }, Access, Priority, Direction, `
@{label = 'Destination'; expression = { $_.DestinationAddressPrefix } }, `
@{label = 'Destination Application Security Group'; expression = { $_.DestinationApplicationSecurityGroups.id.Split('/')[-1] } }, `
@{label = 'Destination Port Range'; expression = { $_.DestinationPortRange } }, `
@{label = 'Resource Group Name'; expression = { $azNsg.ResourceGroupName } },
@{label = 'Subscription Name'; expression = { $azSub } }
}
# creating folder to save
# New-Item $output_folder$appfirewall_rules -itemType Directory
create("$output_folder$app")
$Output | Export-Csv -Path $output_folder$app$app-firewall_rules_data$((Get-Date).ToString("yyyy-MM-dd")).csv -Append`
2
Answers
Test whether the
$Output
variable contains anything – if not, create a "dummy object" with the same shape as the actual output objects and use that in conjunction withConvertTo-Csv
to generate the header:The problem you’ve got is that if there’s no objects in
$output
thenExport-Csv
isn’t able to determine what headers to use. In that case, you’re going to need to generate the header text file yourself…This is slightly more convoluted than @MathiasRJessen’s answer, but it has the advantage that you only need to declare your headers once in your code, rather than keep then in sync in the
Select-Object
parameters and the$dummyObject
path…First, we’ll move the property definitions out of
Select-Object
into a variable…and your
Select-Object
then becomes this:Once we’ve got that working we can re-use the
$csvColumns
variable to generate the headers with this function:Example usage:
which you can then write to your file if
$output
is$null
: