You may have a requirement from time-to-time to provide a copy of the current Network Security Group(s) rulset within your Azure subscription, in this blog I will show you how this can be be done via PowerShell
Lets have a look at a sample NSG created below

I am looking this ruleset to be in a .csv file.
Looking at the relevant PowerShell command below and output directly to .csv has some formatting issues. Shown below:-
$nsg = Get-AzNetworkSecurityGroup -Name "tamops-nsg" | Get-AzureRmNetworkSecurityRuleConfig
Example output of $nsg – shows rules in an array
PS C:UsersThomasDesktopscripts> $nsg
Name : Rule1
Id : /subscriptions/<subscription_id>/resourceGroups/tamopsnsg/providers/Microsoft.Network/networkSecurityGroup
s/tamops-nsg/securityRules/Rule1
Etag : W/"aad44fcb-7e51-4e43-8b49-cd07613302d2"
ProvisioningState : Succeeded
Description :
Protocol : *
SourcePortRange : {*}
DestinationPortRange : {3389}
SourceAddressPrefix : {}
DestinationAddressPrefix : {VirtualNetwork}
SourceApplicationSecurityGroups : [
{
"Id": "/subscriptions/<subscription_id>/resourceGroups/tamopsnsg/providers/Microsoft.Network/applicati
onSecurityGroups/tamopsasg1"
}
]
DestinationApplicationSecurityGroups : []
Access : Allow
Priority : 100
Direction : Inbound
Name : Rule2
Id : /subscriptions/<subscription_id>/resourceGroups/tamopsnsg/providers/Microsoft.Network/networkSecurityGroup
s/tamops-nsg/securityRules/Rule2
Etag : W/"aad44fcb-7e51-4e43-8b49-cd07613302d2"
ProvisioningState : Succeeded
Description :
Protocol : *
SourcePortRange : {*}
DestinationPortRange : {80}
SourceAddressPrefix : {192.168.0.1}
DestinationAddressPrefix : {}
SourceApplicationSecurityGroups : []
DestinationApplicationSecurityGroups : [
{
"Id": "/subscriptions/<subscription_id>/resourceGroups/tamopsnsg/providers/Microsoft.Network/applicati
onSecurityGroups/tamopsasg2"
}
]
Access : Allow
Priority : 110
Direction : Inbound
Output this directly to .csv has a formatting issue
Get-AzNetworkSecurityGroup -Name "tamops-nsg" | Get-AzNetworkSecurityRuleConfig | export-csv -Path "nsg-output.csv"

You will see several outputs showing:-
System.Collections.Generic.List`1[System.String] |
To resolve this issue, I created a new [pscustomobject] and added the columns I wanted to display, full script is below:-
Notice -join has been used to split ports, addresses etc if there is >1 entry within each rule.
Additional rows can be added to [pscustomobject] if required as found in output from:-
$nsg = Get-AzNetworkSecurityGroup -Name "tamops-nsg" | Get-AzureRmNetworkSecurityRuleConfig
PowerShell script:-
param(
[Parameter(Mandatory=$true)][string]$NsgName,
[Parameter(Mandatory=$true)][string]$CsvPathToSave
)
$nsg = Get-AzNetworkSecurityGroup -Name $NsgName | Get-AzNetworkSecurityRuleConfig
$NsgRuleSet = @()
foreach ($rule in $nsg) {
$ASGGroupNameSource = $rule.SourceApplicationSecurityGroups.id -replace '.*/'
$ASGGroupNameDestination = $rule.DestinationApplicationSecurityGroups.id -replace '.*/'
$NsgRuleSet += (
[pscustomobject]@{
RuleName = $rule.Name;
Priority = $rule.Priority;
DestinationPortRange = "$($rule.DestinationPortRange -join ",")";
Protocol = $rule.Protocol;
SourceAddressPrefix = "$($rule.SourceAddressPrefix -join ", ")";
SourceApplicationSecurityGroups = $ASGGroupNameSource;
DestinationAddressPrefix = "$($rule.DestinationAddressPrefix -join ",")";
DestinationApplicationSecurityGroups = $ASGGroupNameDestination;
Direction = $rule.Direction;
Access = $rule.Access;
}
)
}
$NsgRuleSet | export-csv -Path "$($CsvPathToSave).csv"
Example run of script below:-
PS C:UsersThomasDesktopscripts> .nsg-to-xml.ps1
cmdlet nsg-to-xml.ps1 at command pipeline position 1
Supply values for the following parameters:
NsgName: tamops-nsg
CsvPathToSave: nsgscript-output.csv

As you can see from the above snippet, a readable format with no Systems.collection.xxx output
Yes, finally someone who solved this problem. There’s so many dead ends on fixing the list issue.
Hi David,
Thanks for the feedback – glad it helped you!
Thanks
Thomas
Bigup for this David. I’ve been trying to fix the formatting issue for the longest time.
Cheers,
Pablito
Hi Pablito,
Thanks for the feedback – glad it helped!
Thanka
Thomas
Hi Thomas, this is really useful. I’m currently working on something similar but trying to export Azure Firewall network collection rules and application rules instead. I’m having some difficulty as the rules are nested so not sure how to approach it in powershell.
If you ever write something for exporting Az fw rules, please let me know.
Many thanks
Hi Mus,
Thank you for the feedback, great to hear! I will add that to my future blog posts. Feel free to subscribe to my blog and I will work on it in coming week or so
Thanks
Thomas