Get Azure virtual machines without NSG and ASG assigned

Hi Scripters! Today I’ve got for you awesome script which will generate report with information about Azure virtual machines without NSG and ASG assigned.

For non-Azure related people – Network Security Groups and Application Secuirty Groups are Azure network security concepts, which allows to filter/block virtual machines network traffic and easily group them according to ports which should be used by specific type of application.

Both NSG and ASG are very important security aspect if we are talking about Infrastructure as a Service (IaaS) configuration in public cloud. That is why I’ve prepared this script, so also you will be able if fo sure your all azure VMs are safe.

Script is working in following way, it’s gathering all subscription base on tenant ID porvided as input parameter. In next step it’s iterate accross all subscriptions and gathering information about virtual machines. For each of vm it’s checking if NSG and ASG assigned on subnet level of virtual network. If it’s not script is checking if it’s is done at least on network interface level. If not it’s adding them to proper array $vmsMissingNSG or $vmsMissingASG. Once script is completed it’s displaying them in the output. Script is also quite clearly described in comments, so hope you will understand each line.


    [Parameter(Mandatory = $true)]$TenantID

$ErrorActionPreference = "Stop"
Login-AzureRmAccount -TenantId $TenantID

#Get list of all subscriptions in specific tenant id
$subscriptionsArray = Get-AzureRmSubscription -tenantID $TenantID | Select-Object Name, ID

#Create arrays for missing NSG and ASG
$vmsMissingNSG = @()
$vmsMissingASG = @()

#Iterate across all subscriptions found for specific tenant ID
foreach ($subscription in $subscriptionsArray) {
    Write-Output "Working on subscription $($subscription.Name)"
    Select-AzureRmSubscription -SubscriptionId $subscription.Id | Out-Null
    # Gather information about all virtual machines in specific subscription
    $vmsArray = Get-AzureRmVM | Select-Object ResourceGroupName, Name, NetworkProfile
    # Proceed with furhter part of the script in case that there is at least one vm created
    if ($vmsArray) {
        foreach ($vm in $vmsArray) {
            # Gather information about network interfaces configuration like ID, resource group, subnet etc.
            $vmNetworkInterfacesIdArray = $
            # Iterate across all nics attached to VM
            foreach ($vmNetworkInterfaceId in $vmNetworkInterfacesIdArray) {
                $vmNetworkInterfaceObject = Get-AzureRmResource -id $vmNetworkInterfaceId | Get-AzureRmNetworkInterface
                $vmNetworkInterfaceSubnet = $vmNetworkInterfaceObject.IpConfigurations.subnet.Id
                # Check which NSGs and ASGs are assigned to network interface
                $vmNsgAssigned = $vmNetworkInterfaceObject.NetworkSecurityGroupText
                $vmAsgAssigned = $vmNetworkInterfaceObject.IpConfigurations.ApplicationSecurityGroupsText
                # Check network name and subnet name for which nic is connected
                $vmNetworkInterfaceVnetName = $vmNetworkInterfaceSubnet.Split("/")[8] 
                $vmNetworkInterfaceSubnetName = $vmNetworkInterfaceSubnet.Split("/")[-1] 
                $vmVnetResourceGroup = $vmNetworkInterfaceSubnet.Split("/")[4]
                $vnetObject = Get-AzureRmVirtualNetwork -Name $vmNetworkInterfaceVnetName -ResourceGroupName $vmVnetResourceGroup
                $subnetObject = Get-AzureRmVirtualNetworkSubnetConfig -Name $vmNetworkInterfaceSubnetName -VirtualNetwork $vnetObject
                # If there is no NSG assigned to NIC and subnet attached to the nic doesn't have NSG assigned as well add virtual machine to array with missing NSGs
                if ($vmNsgAssigned -eq "null" -and !$subnetObject.NetworkSecurityGroup.Id) {

                    $vmObject = New-Object PSObject -Property ([ordered]@{ 
                            "Virtual Machine Name" = $vm.Name
                            "Resource Group Name"  = $vm.ResourceGroupName
                            "Subscription"         = $subscription.Name
                            "Subnet"               = $vmNetworkInterfaceSubnetName
                            "Virtual Network"      = $vmNetworkInterfaceVnetName
                    $vmsMissingNSG += $vmObject
                # If there is nsg assgined to virtual machine either on nic or subnet level 
                else {
                    # But there is no ASGs assigned add virtual machine to missing ASGs array
                    if ($null -eq $vmAsgAssigned) {
                        $vmObject = New-Object PSObject -Property ([ordered]@{ 
                                "Virtual Machine Name" = $vm.Name
                                "Resource Group Name"  = $vm.ResourceGroupName
                                "Subscription"         = $subscription.Name
                                "Subnet"               = $vmNetworkInterfaceSubnetName
                                "Virtual Network"      = $vmNetworkInterfaceVnetName
                        $vmsMissingASG += $vmObject
    else {
        Write-Output "No virtual machines found in subscription $($subscription.Name)"
    Write-Output "----------------------------"

Write-Output "Virtual machines with missing NSG: $($vmsMissingNSG.Count)"

Write-Output "Virtual machines with missing ASG: $($vmsMissingASG.Count)"

Remember that’s checking periodcially Azure virtual machines without NSG and ASG assigned it’s very important from secuirty perspective and do not ignore this aspect, even if you don’t want to use my script 🙂

Hope that it will be usefull for some of you 😉


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.