You dont have javascript enabled! Please enable it! Export All NSG Rules From All Azure Subscriptions With PowerShell - CHARBEL NEMNOM - MVP | MCT | CCSP | CISM - Cloud & CyberSecurity

Export All NSG Rules from All Azure Subscriptions with PowerShell

5 Min. Read

Updated – 27/09/2023 – The tool is updated to include the list of Protocols that are part of your NSG rules (Any, TCP, UDP, or ICMP).

Updated – 18/07/2023 – The tool now will export Network Security Groups (NSG) assignments for network interfaces and subnets. Please feel free to leave a comment below for additional improvement.

Updated – 25/05/2023 – If you are using Application Security Groups (ASG), the script was updated to support multiple ASGs in one NSG rule. Please feel free to leave a comment below for additional improvement.

Updated – 28/04/2021 – If you are using Application Security Groups (ASG), the script was updated to include the source and destination name of the Application Security Group (ASG) used with Network Security Groups (NSG). Please feel free to leave a comment below for additional improvement.

Updated – 12/03/2021 – The script now includes the source and destination addresses. Please feel free to leave a comment below for additional improvement.

In this article, we will share with you how to export all Network Security Groups (NSG) rules from all Azure subscriptions with Azure PowerShell.

Introduction

Azure Network Security Group (NSG) can help you limit network traffic to resources in a virtual network, you can think of it as your traditional layer 4 Firewall. NSG allows you to create rules (ACLs) at the desired level of granularity: network interfaces, individual VMs, or virtual subnets. You can control access by permitting or denying communication between the workloads within a virtual network, from systems on your network(s) via cross-premises connectivity, or direct Internet communication. Each network interface has zero, or one, associated network security group. Each network interface exists in a virtual network subnet. A subnet can also have zero, or one, associated network security group.

In this article, we will share with you a PowerShell script that will help you to get the list of all Network Security Groups (NSGs) in all Azure subscriptions, and then export it to a comma-separated value (CSV) format. This comes in handy when working with many VMs in Azure, and you want to audit all Network Security Group (NSG) rules you have.

Prerequisites

To follow this guide, you need to have the following:

1) Azure subscription – If you don’t have an Azure subscription, you can create a free one here.

2) You need one or more Network Security Group (NSG) rules.

3) If you want to run this tool locally, then make sure the Azure PowerShell (Az module) is installed locally on your machine.

You can use the following PowerShell command to install and update the “Az module”. You need the Az PowerShell module version 9.2.0 or later.

# Make sure you have the latest version of PowerShellGet installed
Install-Module -Name PowerShellGet -Force

# Install and update to the latest Az PowerShell module
Install-Module -Name Az -AllowClobber -Force

Assuming you have all the prerequisites in place, run the following PowerShell tool.

Export All NSG Rules using PowerShell

Here is the script that will do the job for you:

<#
.Synopsis
A script used to export all NSGs rules in all your Azure Subscriptions

.DESCRIPTION
A script is used to get the list of all Network Security Groups (NSGs) in all your Azure Subscriptions.
Finally, it will export the report into a CSV file in your Azure Cloud Shell storage or locally on your machine.

.Notes
Created   : 04-January-2021
Updated   : 27-September-2023
Version   : 3.6
Author    : Charbel Nemnom (MVP/MCT)
Twitter   : @CharbelNemnom
Blog      : https://charbelnemnom.com
Disclaimer: This script is provided "AS IS" with no warranties.
#>

#! Install Az Module If Needed
function Install-Module-If-Needed {
    param([string]$ModuleName) 
    if (Get-Module -ListAvailable -Name $ModuleName -Verbose:$false) {
        Write-Host "Module '$($ModuleName)' already exists, continue..." -ForegroundColor Green
    } 
    else {
        Write-Host "Module '$($ModuleName)' does not exist, installing..." -ForegroundColor Yellow
        Install-Module $ModuleName -Force  -AllowClobber -ErrorAction Stop
        Write-Host "Module '$($ModuleName)' installed." -ForegroundColor Green
    }
}

#! Install Az Accounts Module If Needed
Install-Module-If-Needed Az.Accounts

#! Install Az Network Module If Needed
Install-Module-If-Needed Az.Network

#! Check Azure Connection
Try { 
    Write-Verbose "Connecting to Azure Cloud..." 
    Connect-AzAccount -ErrorAction Stop -WarningAction SilentlyContinue | Out-Null 
}
Catch { 
    Write-Warning "Cannot connect to Azure Cloud. Please check your credentials. Exiting!" 
    Break 
}

#! Get all Azure Subscriptions
$azSubs = Get-AzSubscription

#! Use the following if you want to select a specific Azure Subscription
$azSubs = Get-AzSubscription | Out-Gridview -PassThru -Title 'Select Azure Subscription'

foreach ( $azSub in $azSubs ) {
    Set-AzContext -Subscription $azSub | Out-Null
    $azSubName = $azSub.Name

    $azNsgs = Get-AzNetworkSecurityGroup | Where-Object {$_.Id -ne $NULL}
    
    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 = { foreach ($Asg in $_.SourceApplicationSecurityGroups) {$Asg.id.Split('/')[-1]} } }, `
            @{label = 'Source Port Range'; expression = { $_.SourcePortRange } }, Access, Priority, Direction, Protocol, `
            @{label = 'Destination'; expression = { $_.DestinationAddressPrefix } }, `
            @{label = 'Destination Application Security Group'; expression = { foreach ($Asg in $_.DestinationApplicationSecurityGroups) {$Asg.id.Split('/')[-1]} } }, `
            @{label = 'Destination Port Range'; expression = { $_.DestinationPortRange } }, `
            @{label = 'Resource Group Name'; expression = { $azNsg.ResourceGroupName } }, `
            @{label = 'NIC Assignment Name'; expression = { $azNsg.NetworkInterfaces.Id.split('/')[-1] } }, `
            @{label = 'Subnet Assignment Name'; expression = { $azNsg.Subnets.Id.split('/')[-1] } } | `
            # Export to Azure Cloud Shell drive
            # Export-Csv -Path "$($home)\clouddrive\$azSubName-nsg-rules.csv" -NoTypeInformation -Append -force
            # Or you can use the following syntax to export to a single CSV file and to a local folder on your machine
            Export-Csv -Path ".\Azure-nsg-rules.csv" -NoTypeInformation -Append -force
        
        # Export default rules
        Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $azNsg -Defaultrules | `
            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 Port Range'; expression = { $_.SourcePortRange } }, Access, Priority, Direction, Protocol, `
            @{label = 'Destination'; expression = { $_.DestinationAddressPrefix } }, `
            @{label = 'Destination Port Range'; expression = { $_.DestinationPortRange } }, `
            @{label = 'Resource Group Name'; expression = { $azNsg.ResourceGroupName } }, `
            @{label = 'NIC Assignment Name'; expression = { $azNsg.NetworkInterfaces.Id.split('/')[-1] } }, `
            @{label = 'Subnet Assignment Name'; expression = { $azNsg.Subnets.Id.split('/')[-1] } } | `
            # Export to Azure Cloud Shell drive
            # Export-Csv -Path "$($home)\clouddrive\$azSubName-nsg-rules.csv" -NoTypeInformation -Append -force
            # Or you can use the following syntax to export to a single CSV file and to a local folder on your machine
            Export-Csv -Path ".\Azure-nsg-rules.csv" -NoTypeInformation -Append -force
      
    }    
}

From the example above, we are exporting the following information:

  • Network Security Group (NSG) Name
  • Network Security Group (NSG) Location
  • For each Network Security Group, we will export the custom rule, as well as the default rule:
    • Rule Name
    • Source address
    • Port Range
    • Access
    • Priority
    • Direction
      • Inbound
      • Outbound
    • Destination address
  • Resource Group Name

Run the script

To run the script, you can either install the latest Azure PowerShell version on your machine, you can jump over the Cloud Shell (https://shell.azure.com), or use the Azure Cloud Shell Connector in Windows Terminal.

Export All NSG Rules from All Azure Subscriptions with PowerShell 1

The report will be saved in the clouddrive path following the Azure Subscription name (-nsg-rules.csv).

Export All NSG Rules from All Azure Subscriptions with PowerShell 2

Switch to the cloud shell storage account and download the CSV files as shown in the figure below.

Export All NSG Rules from All Azure Subscriptions with PowerShell 3

And here is the final report is shown in CSV format:

Export All NSG Rules from All Azure Subscriptions with PowerShell 4

Please note that you can accomplish the same thing using Azure CLI, however, I prefer to use Azure PowerShell.

Summary

In this article, we showed you how to export all Network Security Groups (NSG) rules from all your Azure Subscriptions with Azure PowerShell.

Azure Cloud Shell is so powerful, that you don’t need to install Azure CLI or PowerShell modules locally on your machine to automate your tasks.

Learn more on how to get the list of Network Security Group with RDP port open.

This is version 3.6 of this tool, do you want additional features? Please feel free to leave a comment below.

Hope this helps!

__
Thank you for reading my blog.

If you have any questions or feedback, please leave a comment.

-Charbel Nemnom-

Photo of author
About the Author:
Charbel Nemnom
Charbel Nemnom is a Senior Cloud Architect with 21+ years of IT experience. As a Swiss Certified Information Security Manager (ISM), CCSP, CISM, Microsoft MVP, and MCT, he excels in optimizing mission-critical enterprise systems. His extensive practical knowledge spans complex system design, network architecture, business continuity, and cloud security, establishing him as an authoritative and trustworthy expert in the field. Charbel frequently writes about Cloud, Cybersecurity, and IT Certifications.
Previous

Reflecting on 2020… Goodbye 2020 and Welcome 2021! #HappyNewYear

How To Export and Backup Azure Policy Definitions

Next

37 thoughts on “Export All NSG Rules from All Azure Subscriptions with PowerShell”

Leave a comment...

  1. Great script, thank you very much. Pulled out all the info I needed.
    I have no clue about PowerShell and I wanted to ask is there a way to add a specific subscription instead of pulling all subscriptions NSG’s?

  2. Hello Jack, thanks for the comment and feedback!
    Yes of course you can do that, please add the desired specific subscription to the following variable ($azSubs) at the beginning of the script and it should work.

    $azSubs = "Add-Your-Subscription-Id-Here"

    Hope this helps!

  3. Hello Lovish, thanks for the comment!
    Please note that I have just run this PowerShell tool, and I can see all custom (ad-hoc) and default NSG rules in one CSV file.
    From where are you running this tool?
    If you are running this tool locally, then make sure to use the Az PowerShell module version 9.2.0 or later.

    Install-Module -Name Az -RequiredVersion 9.2.0

    Hope it helps!

  4. Hi Charbel,

    Thanks for this script! I use it a lot.
    I’ve updated it a bit to support multiple ASGs in one NSG rule with the following 2 code lines:

    @{label = ‘Source Application Security Group’; expression = { foreach ($Asg in $_.SourceApplicationSecurityGroups) {$Asg.id.Split(‘/’)[-1]} } }, `

    @{label = ‘Destination Application Security Group’; expression = { foreach ($Asg in $_.DestinationApplicationSecurityGroups) {$Asg.id.Split(‘/’)[-1]} } }, `

    Use it if you like for the next version.

  5. Hello Robert, thanks for the comment and sharing your experience.
    I have adopted the changes to version 3.3.
    Many Thanks!

  6. Hi Charbel,

    I don’t want to see NSG output of ‘all’ subscriptions in my tenant.
    How can I select the subscription(s) I only want to see?

  7. Hello Jerrol, thanks for the comment!
    If you want to select a specific Azure subscription, then update the variable $azSubs line with the following code instead:

    $azSubs = Get-AzSubscription | Out-Gridview -PassThru -Title 'Select Azure Subscription'

    Hope it helps!

  8. Hello Charbel, this is very helpful.
    Any chance this can be enhanced with each NSG assignments?

  9. Hello Horia, thanks for the comment and the great suggestion.
    Please note that the tool will export now Network Security Groups (NSG) assignments for network interfaces and subnets.
    Give it a try and let me know how it works for you.
    Thanks!

  10. Hi, thank you, Charbel. Yes, it worked beautifully!
    I just realized over the weekend that similar /same info can be obtained querying Azure Resource Graph Explorer. I’m trying now to write a query to get the same data. Proves to be quite easy (and fast!) to get it from one table, but it seems that I need to join multiple tables for all details. I need to get the join right.

  11. Hello Horia, thanks for confirming it’s working for you now!
    Yes, the same can be obtained using KQL from Azure Resource Graph Explorer.
    For small to medium deployment, you could use the Azure PowerShell as described in this article.
    However, it is not a good idea to do it on a large scale, Azure Resource Graph is the way to go and faster.
    Cheers,

Let us know what you think, or ask a question...