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"
}
}