0
votes

I am new to PS.... trying to get NSGs in a given subscription (and once this works to do this for all subscriptions) to show the following properties (NSG Name, Location, Resource Group, Subnet, NIC).

I am using the below script from Getting list of NSG and corresponding Subnet or NIC but it lists same information for each NSG multiple times equal to the number of NSGs in the subscription so it has to be something wrong in the script

$azNsgs = Get-AzNetworkSecurityGroup
       
 foreach ( $azNsg in $azNsgs ) {

 if ($azNsg.Subnets.Id -ne $null) {

     $NsgSubnets = $azNsg.Subnets.Id.Split('/')[-1]

}
         Get-AzNetworkSecurityGroup | `
            Select-Object `
            @{name = 'NSG Name'; expression = {$azNsg.Name} },  `
            @{name = 'Location'; expression = {$azNsg.Location} }, `
            @{name = 'Resource Group Name'; expression = {$azNsg.ResourceGroupName} },  `
            @{name = 'Subnets'; expression = $NsgSubnets } 
       
}

Also would like the script to ignore null values for NIC/Subnet as some NSGs would be assigned to Subnets whilst others to NICs Finally an NSG could be assigned to multiple subnets/NICs so how do I get the $azNsg.Subnets.Id.Split('/')[-1] part working for multiple entries in Subnets.Id or NetworkInterfaces.Id and not just the last one ?

Thanks

1
You do not need to call Get-AzNetworkSecurityGroup the second time inside of your foreach loop. Just use $azNsg | Select-Object .....AdminOfThings
Many thanks @AdminOfThings.. that seems to have solved that part.. could you help me please with the second part of the query where I want to see subnets and/or NICs associated with each NSG and it should list all subnets/nics not just the last oneByteServe
Index [-1] gets the last element of an array. If you don't want only the last element, then you should remove that index. Since you are using an if statement to set $NsgSubnets, it is not reset for when there are no subnets. The first line of your foreach needs to be something like $NsgSubnets = $null.AdminOfThings
After looking at the linked post, I think I understand more of the issue. The subnet ID is a path and you only want the leaf of that path (the name only). You could try $NsgSubnets = $azNsg.Subnets.foreach({$_.Id.Split('/')[-1]})AdminOfThings

1 Answers

0
votes

You can do the following:

$azNsgs = Get-AzNetworkSecurityGroup
       
    foreach ( $azNsg in $azNsgs ) {

        $NsgSubnets = $null

        if (!$azNsg.Subnets.Id) {
            $NsgSubnets = $azNsg.Subnets.foreach({$_.Id.Split('/')[-1]})
        }

         $azNsg |
            Select-Object @{name = 'NSG Name'; expression = {$_.Name}},
                @{name = 'Location'; expression = {$_.Location}},
                @{name = 'Resource Group Name'; expression = {$_.ResourceGroupName}},  
                @{name = 'Subnets'; expression = {$NsgSubnets -join ','}}
       
    }

Overall improvements include:

  • You only need to run Get-AzNetworkSecurityGroup once since you are storing its output into a variable. You can simply retrieve its contents from the variable. This makes the code execute faster.
  • Since your objects could have multiple subnets, you need to handle the case when $azNsg.Subnets is an array of non-null objects. Using the foreach() method, you can process code against each element of that array. When PowerShell fully enumerates array output (as it does in the case without foreach()), your multiple subnet arrays become one large array on the final output. Then [-1] only returns the very last Id value.
  • Setting $NsgSubnets inside of an if statement without an else statement leads to bad data later in the code execution. If the network has a subnet, $NsgSubnets will be set and returned properly. However, if the next network has no subnet, you are not updating the value of $NsgSubnets. Therefore, it will output the previous network's subnet information in your Select-Object command.
  • You don't always need backticks for continuation. | and , separating elements automatically supports continuation. See Natural Line Continuations.