Skip to content

Instantly share code, notes, and snippets.

@PlagueHO
Last active October 7, 2022 07:01
Show Gist options
  • Save PlagueHO/3fa7b7048187ec41565df7138e7b35ed to your computer and use it in GitHub Desktop.
Save PlagueHO/3fa7b7048187ec41565df7138e7b35ed to your computer and use it in GitHub Desktop.
PowerShell function to add or update a rule in all Azure Network Security Groups (NSG) across a set of Azure subscriptions
<#
.SYNOPSIS
Function to loop over all Azure Network Security Groups in multiple
subscriptions and add an NSG rule to it if it does not already exist.
If the rule already exists, it will remove it and add it. The NSG will
then be replaced.
This function is not idempotent, it will replace the NSG regardless
of whether it needed to be or not.
.PARAMETER Subscription
An array of SubscriptionIds to loop through. If parameter is not passed
then all subscriptions the user has access to will be used.
.PARAMETER RuleName
The name of the rule to create or update.
.PARAMETER Description
Specifies a description of a network security rule configuration.
.PARAMETER Access
The access to set on the rule.
.PARAMETER Protocol
Specifies the network protocol that a rule configuration applies to. The acceptable values for this parameter are:
Tcp
Udp
Wildcard character (*) to match both
.PARAMETER Direction
Specifies whether a rule is evaluated on incoming or outgoing traffic. The acceptable values for this parameter are: Inbound and Outbound.
.PARAMETER Priority
Specifies the priority of a rule configuration. The acceptable values for this parameter are: An integer between 100 and 4096. The priority number must be unique for each rule in the collection. The lower the priority number, the higher the priority of the rule.
.PARAMETER SourceAddressPrefix
Specifies a destination address prefix. The acceptable values for this parameter are:
A Classless Interdomain Routing (CIDR) address
A destination IP address range
A wildcard character (*) to match any IP address. You can use tags such as VirtualNetwork, AzureLoadBalancer, and Internet.
.PARAMETER SourcePortRange
Specifies a source port or range. This value is expressed as an integer, as a range between 0 and 65535, or as a wildcard character (*) to match any source port.
.PARAMETER DestinationAddressPrefix
Specifies a source address prefix. The acceptable values for this parameter are:
A CIDR
A source IP range
A wildcard character (*) to match any IP address. You can also use tags such as VirtualNetwork, AzureLoadBalancer and Internet.
.PARAMETER DestinationPortRange
Specifies a destination port or range. The acceptable values for this parameter are:
An integer
A range of integers between 0 and 65535
A wildcard character (*) to match any port
.EXAMPLE
Connect-AzAccount
.\Set-AzNetworkSecurityGroupAddRule.ps1 `
-SubscriptionId 7af822f6-1111-1111-1111-cb443919f7c0 `
-RuleName 'test' `
-Description 'test rule' `
-Access Allow `
-Protocol TCP `
-Direction Inbound `
-Priority 999 `
-SourceAddressPrefix * `
-SourcePortRange * `
-DestinationAddressPrefix * `
-DestinationPortRange 1234 `
-WhatIf `
-Verbose
This example will SIMULATE creation of a new test rule (or update it) on all NSGS in the subscription.
Remove the -WhatIf to run for real.
#>
[CmdletBinding(SupportsShouldProcess=$True)]
param (
[System.String[]]
$SubscriptionId,
[ValidateNotNullOrEmpty()]
[System.String]
$RuleName,
[ValidateNotNullOrEmpty()]
[System.String]
$Description,
[ValidateSet('Allow','Deny')]
[System.String]
$Access,
[ValidateSet('*','Ah','Esp','ICMP','Tcp','Udp')]
[System.String]
$Protocol,
[ValidateSet('Inbound','Outbound')]
[System.String]
$Direction,
[ValidateRange(100,4096)]
[System.Int32]
$Priority,
[ValidateNotNullOrEmpty()]
[System.String]
$SourceAddressPrefix,
[ValidateNotNullOrEmpty()]
[System.String[]]
$SourcePortRange,
[ValidateNotNullOrEmpty()]
[System.String]
$DestinationAddressPrefix,
[ValidateNotNullOrEmpty()]
[System.String[]]
$DestinationPortRange
)
# Loop through all the subscriptions and process NSGs in each
$subscriptions = Get-AzSubscription
:subscriptionLoop foreach ($subscription in $subscriptions) {
if ($PSBoundParameters.ContainsKey('SubscriptionId') -and $Subscription.SubscriptionId -notin $SubscriptionId) {
# This subscription is not in the list provided in the SubscriptionId parameter - so skip
continue subscriptionLoop
}
Write-Verbose -Message "Selecting subscription '$($subscription.Name)' to being processing NSG rules."
$null = $subscription | Set-AzContext -WhatIf:$False
# Loop throught the NSGs in the subscription and check the rules
$nsgs = Get-AzNetworkSecurityGroup
:nsgLoop foreach ($nsg in $nsgs) {
Write-Verbose -Message "Begin processing NSG '$($nsg.Name) in subscription '$($subscription.Name)'."
# Does the rule already exist in the NSG?
if ($RuleName -in $nsg.SecurityRules.Name) {
# It does, so first remove it so we can add it back in
Write-Verbose -Message "Rule '$RuleName' already exists in NSG '$($nsg.Name) in subscription '$($subscription.Name)', so will update by removing."
$null = $nsg | Remove-AzNetworkSecurityRuleConfig -Name $RuleName
}
Write-Verbose -Message "Adding rule '$RuleName' to NSG '$($nsg.Name)' in subscription '$($subscription.Name)'."
$null = $nsg | Add-AzNetworkSecurityRuleConfig -Name $RuleName -Description $Description -Access $Access `
-Protocol $Protocol -Direction $Direction -Priority $Priority `
-SourceAddressPrefix $SourceAddressPrefix -SourcePortRange $SourcePortRange `
-DestinationAddressPrefix $DestinationAddressPrefix -DestinationPortRange $DestinationPortRange
Write-Verbose -Message "Writing the NSG '$($nsg.Name)' back to Azure subscription '$($subscription.Name)'."
# Write the updated NSG back to Azure with the new/updated rule
$null = $nsg | Set-AzNetworkSecurityGroup
}
Write-Verbose -Message "Finished processing NSGs in subscription '$($subscription.Name)'."
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment