I developed a habit when I was working with ACLs on a Cisco ASA firewall. I would keep a master list for each ACL, and when I needed to make a change, I would remove the entire ACL from the device and then recreate it each time I made a modification. For example I would run the following, and keep adding new rules when needed.
clear configure access-list dmz_acl access-list dmz_acl extended permit tcp host 1.1.1.1 object-group DCs eq 389 . . . .
Add one line, look at the logs and if traffic is still being blocked then modify and try again.
I wanted the ability to do the same thing with Azure Network Security Groups. I wrote a PowerShell script that would look at the NSGs, dump the settings, and would display the commands to recreate them. here is the script I wrote. I hope it helps some one.
function JBM-AZURE-GetNetworkSecurityGroupRules{ param( [String]$Name , [Switch]$ShowCommands ) $Groups=$(Get-AzureNetworkSecurityGroup -Detailed) If(!$Name){ Write-Host Write-host "Select the number of the NSG" $NSGNumb = $(Read-Host -prompt "$($(for($i=0;$i-le $Groups.Count-1;$i++){$AllGroups=$AllGroups+"$i $($Groups[$i].Name)`n"});$AllGroups)" ) $Name=$Groups[$NSGNumb].Name } $NSG=$Groups | where {$_.Name -eq $Name} If ($NSG){ $InboundRules=$NSG.Rules | where {$_.Type -eq "Inbound"} $OutBoundRules=$NSG.Rules | where {$_.Type -eq "Outbound"} Write-Output "" Write-Output "Inbound Rules" Write-Output $InboundRules | FT Write-Output "Outbound Rules" Write-Output $OutBoundRules | FT if ($ShowCommands){ Write-Output "New-AzureNetworkSecurityGroup -Name ""$($NSG.Name)"" -Location ""$($NSG.Location)""" Write-Output "" foreach ($Rule in $($InboundRules | where {$_.Priority -lt 65000})){ write-Output "Get-AzureNetworkSecurityGroup -Name ""$($NSG.Name)"" | Set-AzureNetworkSecurityRule -Name ""$($Rule.Name)"" -Type ""$($Rule.Type)"" -Priority ""$($Rule.Priority)"" -Action ""$($Rule.Action)"" -SourceAddressPrefix ""$($Rule.SourceAddressPrefix)"" -SourcePortRange ""$($Rule.SourcePortRange)"" -DestinationAddressPrefix ""$($Rule.DestinationAddressPrefix)"" -DestinationPortRange ""$($Rule.DestinationPortRange)"" -Protocol ""$($Rule.Protocol)""" Write-Output "" } foreach ($Rule in $($OutBoundRules | where {$_.Priority -lt 65000})){ write-Output "Get-AzureNetworkSecurityGroup -Name ""$($NSG.Name)"" | Set-AzureNetworkSecurityRule -Name ""$($Rule.Name)"" -Type ""$($Rule.Type)"" -Priority ""$($Rule.Priority)"" -Action ""$($Rule.Action)"" -SourceAddressPrefix ""$($Rule.SourceAddressPrefix)"" -SourcePortRange ""$($Rule.SourcePortRange)"" -DestinationAddressPrefix ""$($Rule.DestinationAddressPrefix)"" -DestinationPortRange ""$($Rule.DestinationPortRange)"" -Protocol ""$($Rule.Protocol)""" Write-Output "" } } } Else { Write-Host "Can't find a NSG with that name" } }