Adjust Azure Network Security Group

This article is about modifying an Azure Network Security Group (NSG) to give you access to your resources with a simple PowerShell script.

(Dieser Artikel ist auch auf deutsch erschienen).

My test environments are all following the same standard: There is a name schema for all (infrastructure) resources, including VNet and subnet. And there is always a NSG created at deployment that initially blocks all access. I bind the NSG to the subnet, not to individual VMs, so all resources attached to the subnet are protected at once. Everytime I want to access my resources, I run a small PowerShell script (see below) that looks for my current IP address (mobile workers like me have different once) and modifies this standard NSG to grant me access. Have a look:

First of all, here is the part of my standard template that deploys the NSG:

        {   "type": "Microsoft.Network/networkSecurityGroups",
            "name": "[variables('nsgName')]",
            "apiVersion": "2018-08-01",
            "location": "[variables('location')]",
            "properties": {
                "securityRules": [
                        "name": "all-in-from-home",
                        "properties": {
                            "description": "needs modification by script",
                            "protocol": "Tcp",
                            "sourcePortRange": "*",
                            "destinationPortRange": "*",
                            "sourceAddressPrefix": "",
                            "destinationAddressPrefix": "*",
                            "access": "Allow",
                            "priority": 100,
                            "direction": "Inbound"

As you can see, the rule allows only access from, so effectively blocking everything.

The variable „nsgname“ is build following my standard naming schema by using the resource group and „nsg1“. So for the resource group „blogdemo“ the name of the NSG resource is blogdemonsg1. That makes life much easier since I only need to know the name of the resource group (and you would need that anyways). So here is part one of the script:


$ipinfo = Invoke-RestMethod ""

$sourceAddressPrefix = "$($ipinfo.ip)/32"
$description = "modified by script to temp IP"

$nsg=Get-AzNetworkSecurityGroup -Name $nsgname -ResourceGroupName $resourcegroup

$rule = ($nsg | Get-AzNetworkSecurityRuleConfig -Name $configname -ErrorAction SilentlyContinue)

I’m sure there are a lot more ways to determine your current address, I prefer the one shown in line 5 because it gives you (if you want) some more information.

We already talked about „nsgname“, we get the corresponding object in line 12. We search for the rule „all-in-from-home“ in line 14 (it might have been deleted or not deployed in older envirnments). If the rule is missing, we create a new one with Add-AzNetworkSecurityRuleConfig, otherwise we change the existing one with Set-AzNetworkSecurityRuleConfig:

if ($rule -eq $null) {
        $prio = [int]($nsg.SecurityRules[$nsg.SecurityRules.Count-1].Priority)
        $prio += 10
        if ($prio -lt 100){
        Write-Host "Adding $configname rule to allow $sourceAddressPrefix with priority $prio"
        $ret = ($nsg | Add-AzNetworkSecurityRuleConfig `
                        -Name $configname `
                        -SourceAddressPrefix $sourceAddressPrefix `
                        -SourcePortRange "*" `
                        -DestinationAddressPrefix "*" `
                        -DestinationPortRange "*" `
                        -Protocol "Tcp" `
                        -Direction "Inbound" `
                        -Access "Allow" `
                        -Priority $prio `
                        -Description $description
} else {
        Write-Host "Updating $configname rule to allow $sourceAddressPrefix"
        $ret = ($nsg | Set-AzNetworkSecurityRuleConfig `
                        -Name $configname `
                        -SourceAddressPrefix $sourceAddressPrefix `
                        -SourcePortRange $rule.SourcePortRange `
                        -DestinationAddressPrefix $rule.DestinationAddressPrefix `
                        -DestinationPortRange $rule.DestinationPortRange `
                        -Protocol $rule.Protocol `
                        -Direction $rule.Direction `
                        -Access $rule.Access `
                        -Priority $rule.Priority `
                        -Description $description
Write-Host "Apply new rule..."
$ret = ($nsg | Set-AzNetworkSecurityGroup)

We define a priority in line 16-20 (not perfect, I agree, but it suits my needs). Standard is 100 except there is already a rule with this prio, in this case we add 10 to the highest existing. You can see that – if the rule already exists – we only modify „sourceAddressPrefix“ and „description“. If you want to grant access only to specific ports when deploying the NSG, the script won’t change this settings.

At the end, we refresh the NSG, and – here we go!

Calling the script looks like this:

change-nsg.ps1 -resourcegroup blogdemo

Of course there is a great „Just-in-Time“ Access Control Service in Azure (see here), I just wanted something simple from a commandline. And when I’m deploying a new test environment, I deploy the standard NSG and – at the very end of the deployment – I change the NSG rule with this script. And by the way: I had this in place even before JIT access control was available 🙂

Ein Kommentar zu „Adjust Azure Network Security Group

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

Du kommentierst mit Deinem Abmelden /  Ändern )

Google Foto

Du kommentierst mit Deinem Google-Konto. Abmelden /  Ändern )


Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )


Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s