Network Security Group Ruleset to CSV

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

8 comments

  1. Bigup for this David. I’ve been trying to fix the formatting issue for the longest time.

    Cheers,

    Pablito

  2. 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

    1. 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

  3. Hi

    Script works fine when you have default subscription set originally. However, when you change subscription and run this script lots of information source and destination addresses goes something… Any particular reason pls?

    1. Hi,

      Can you provide more context?
      – Script you are attempting?
      – Errors from the script?

      Thanks

      Thomas

Leave a Reply