|
1 | 1 | #Requires -Version 7.4 |
2 | | -#Requires -Modules Az.Resources |
| 2 | +#Requires -Modules Az.Network |
3 | 3 |
|
4 | | -<#`n.SYNOPSIS |
5 | | - New Aznetworksecuritygroup |
| 4 | +<# |
| 5 | +.SYNOPSIS |
| 6 | + Create new Azure Network Security Group |
6 | 7 |
|
7 | 8 | .DESCRIPTION |
8 | | - New Aznetworksecuritygroup operation |
| 9 | + Creates a new Azure Network Security Group with configurable security rules |
| 10 | + Author: Wes Ellis (wes@wesellis.com) |
| 11 | + Version: 2.0 |
9 | 12 |
|
| 13 | +.PARAMETER ResourceGroupName |
| 14 | + Name of the resource group where the NSG will be created |
10 | 15 |
|
11 | | - Author: Wes Ellis (wes@wesellis.com) |
| 16 | +.PARAMETER Name |
| 17 | + Name of the Network Security Group |
| 18 | +
|
| 19 | +.PARAMETER Location |
| 20 | + Azure region where the NSG will be created |
| 21 | +
|
| 22 | +.PARAMETER SecurityRules |
| 23 | + Array of security rule objects created with New-AzNetworkSecurityRuleConfig |
| 24 | +
|
| 25 | +.PARAMETER Tags |
| 26 | + Hashtable of tags to apply to the NSG |
| 27 | +
|
| 28 | +.EXAMPLE |
| 29 | + .\11-New-Aznetworksecuritygroup.ps1 -ResourceGroupName "rg-prod" -Name "nsg-frontend" -Location "eastus" |
| 30 | + Creates an NSG with no initial rules |
| 31 | +
|
| 32 | +.EXAMPLE |
| 33 | + $rule1 = New-AzNetworkSecurityRuleConfig -Name "allow-https" -Access Allow -Protocol Tcp -Direction Inbound -Priority 100 -SourceAddressPrefix Internet -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 443 |
| 34 | + .\11-New-Aznetworksecuritygroup.ps1 -ResourceGroupName "rg-prod" -Name "nsg-frontend" -Location "eastus" -SecurityRules $rule1 |
| 35 | + Creates an NSG with a single HTTPS allow rule |
| 36 | +
|
| 37 | +.EXAMPLE |
| 38 | + $rule1 = New-AzNetworkSecurityRuleConfig -Name "allow-rdp" -Access Allow -Protocol Tcp -Direction Inbound -Priority 100 -SourceAddressPrefix Internet -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 3389 |
| 39 | + $rule2 = New-AzNetworkSecurityRuleConfig -Name "allow-http" -Access Allow -Protocol Tcp -Direction Outbound -Priority 101 -SourceAddressPrefix Internet -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 80 |
| 40 | + .\11-New-Aznetworksecuritygroup.ps1 -ResourceGroupName "rg-prod" -Name "nsg-frontend" -Location "eastus" -SecurityRules $rule1,$rule2 |
| 41 | + Creates an NSG with multiple rules |
| 42 | +
|
| 43 | +.NOTES |
| 44 | + Requires Az.Network module and appropriate permissions |
| 45 | + Security rules can be added later using Add-AzNetworkSecurityRuleConfig |
12 | 46 | #> |
13 | | - Author: Wes Ellis (wes@wesellis.com) |
14 | 47 |
|
15 | | - 1.0 |
16 | | - Requires appropriate permissions and modules |
17 | | -$ErrorActionPreference = "Stop" |
18 | | -$VerbosePreference = if ($PSBoundParameters.ContainsKey('Verbose')) { "Continue" } else { "SilentlyContinue" } |
19 | | -$NewAzNetworkSecurityRuleConfigSplat = @{ |
20 | | - Name = 'rdp-rule' |
21 | | - Description = "Allow RDP" |
22 | | - Access = 'Allow' |
23 | | - Protocol = 'Tcp' |
24 | | - Direction = 'Inbound' |
25 | | - Priority = 100 |
26 | | - SourceAddressPrefix = 'Internet' |
27 | | - SourcePortRange = '*' |
28 | | - DestinationAddressPrefix = '*' |
29 | | - DestinationPortRange = 3389 |
30 | | -} |
31 | | -$rule1 = New-AzNetworkSecurityRuleConfig -ErrorAction Stop @newAzNetworkSecurityRuleConfigSplat |
32 | | -$NewAzNetworkSecurityRuleConfigSplat = @{ |
33 | | - Name = 'web-rule' |
34 | | - Description = "Allow HTTP" |
35 | | - Access = 'Allow' |
36 | | - Protocol = 'Tcp' |
37 | | - Direction = 'Outbound' |
38 | | - Priority = 101 |
39 | | - SourceAddressPrefix = 'Internet' |
40 | | - SourcePortRange = '*' |
41 | | - DestinationAddressPrefix = '*' |
42 | | - DestinationPortRange = 80 |
43 | | -} |
44 | | -$rule2 = New-AzNetworkSecurityRuleConfig -ErrorAction Stop @newAzNetworkSecurityRuleConfigSplat |
45 | | -$NewAzNetworkSecurityGroupSplat = @{ |
46 | | - ResourceGroupName = 'InspireAV_UniFi_RG' |
47 | | - Location = 'CanadaCentral' |
48 | | - Name = "NSG-FrontEnd" |
49 | | - SecurityRules = $rule1, $rule2 |
| 48 | +[CmdletBinding()] |
| 49 | +param( |
| 50 | + [Parameter(Mandatory = $true)] |
| 51 | + [ValidateNotNullOrEmpty()] |
| 52 | + [string]$ResourceGroupName, |
| 53 | + |
| 54 | + [Parameter(Mandatory = $true)] |
| 55 | + [ValidateNotNullOrEmpty()] |
| 56 | + [string]$Name, |
| 57 | + |
| 58 | + [Parameter(Mandatory = $true)] |
| 59 | + [ValidateNotNullOrEmpty()] |
| 60 | + [string]$Location, |
| 61 | + |
| 62 | + [Parameter()] |
| 63 | + [Microsoft.Azure.Commands.Network.Models.PSSecurityRule[]]$SecurityRules = @(), |
| 64 | + |
| 65 | + [Parameter()] |
| 66 | + [hashtable]$Tags = @{} |
| 67 | +) |
| 68 | + |
| 69 | +$ErrorActionPreference = 'Stop' |
| 70 | +$VerbosePreference = if ($PSBoundParameters.ContainsKey('Verbose')) { 'Continue' } else { 'SilentlyContinue' } |
| 71 | + |
| 72 | +function Write-LogMessage { |
| 73 | + param( |
| 74 | + [Parameter(Mandatory = $true)] |
| 75 | + [string]$Message, |
| 76 | + |
| 77 | + [Parameter()] |
| 78 | + [ValidateSet("INFO", "WARN", "ERROR", "SUCCESS")] |
| 79 | + [string]$Level = "INFO" |
| 80 | + ) |
| 81 | + |
| 82 | + $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" |
| 83 | + $colorMap = @{ |
| 84 | + "INFO" = "Cyan" |
| 85 | + "WARN" = "Yellow" |
| 86 | + "ERROR" = "Red" |
| 87 | + "SUCCESS" = "Green" |
| 88 | + } |
| 89 | + |
| 90 | + Write-Host "[$timestamp] [$Level] $Message" -ForegroundColor $colorMap[$Level] |
50 | 91 | } |
51 | | -$nsg = New-AzNetworkSecurityGroup -ErrorAction Stop @newAzNetworkSecurityGroupSplat |
52 | 92 |
|
| 93 | +try { |
| 94 | + Write-LogMessage "Creating Azure Network Security Group" -Level "INFO" |
| 95 | + Write-LogMessage "Resource Group: $ResourceGroupName" -Level "INFO" |
| 96 | + Write-LogMessage "NSG Name: $Name" -Level "INFO" |
| 97 | + Write-LogMessage "Location: $Location" -Level "INFO" |
| 98 | + Write-LogMessage "Security Rules Count: $($SecurityRules.Count)" -Level "INFO" |
| 99 | + |
| 100 | + # Add default tags |
| 101 | + $datetime = Get-Date -Format "yyyy-MM-dd HH:mm:ss" |
| 102 | + $defaultTags = @{ |
| 103 | + "CreatedDate" = $datetime |
| 104 | + "ManagedBy" = "Azure PowerShell Toolkit" |
| 105 | + "Location" = $Location |
| 106 | + "ResourceType" = "Network Security Group" |
| 107 | + } |
| 108 | + |
| 109 | + # Merge default tags with provided tags (provided tags take precedence) |
| 110 | + $finalTags = $defaultTags.Clone() |
| 111 | + foreach ($key in $Tags.Keys) { |
| 112 | + $finalTags[$key] = $Tags[$key] |
| 113 | + } |
| 114 | + |
| 115 | + Write-Verbose "Final tags: $($finalTags | Out-String)" |
53 | 116 |
|
| 117 | + # Build NSG parameters |
| 118 | + $nsgParams = @{ |
| 119 | + ResourceGroupName = $ResourceGroupName |
| 120 | + Location = $Location |
| 121 | + Name = $Name |
| 122 | + Tag = $finalTags |
| 123 | + } |
54 | 124 |
|
| 125 | + # Add security rules if provided |
| 126 | + if ($SecurityRules.Count -gt 0) { |
| 127 | + $nsgParams['SecurityRules'] = $SecurityRules |
| 128 | + Write-LogMessage "Adding $($SecurityRules.Count) security rule(s)" -Level "INFO" |
| 129 | + |
| 130 | + foreach ($rule in $SecurityRules) { |
| 131 | + Write-Verbose "Rule: $($rule.Name) - $($rule.Direction) $($rule.Access) on port(s) $($rule.DestinationPortRange)" |
| 132 | + } |
| 133 | + } else { |
| 134 | + Write-LogMessage "No security rules specified - NSG will be created with default rules only" -Level "WARN" |
| 135 | + } |
| 136 | + |
| 137 | + # Create the NSG |
| 138 | + Write-LogMessage "Creating Network Security Group..." -Level "INFO" |
| 139 | + $nsg = New-AzNetworkSecurityGroup @nsgParams -ErrorAction Stop |
| 140 | + |
| 141 | + Write-LogMessage "Network Security Group created successfully" -Level "SUCCESS" |
| 142 | + Write-LogMessage "NSG ID: $($nsg.Id)" -Level "INFO" |
| 143 | + Write-LogMessage "Provisioning State: $($nsg.ProvisioningState)" -Level "INFO" |
| 144 | + |
| 145 | + if ($nsg.SecurityRules.Count -gt 0) { |
| 146 | + Write-LogMessage "Custom Rules: $($nsg.SecurityRules.Count)" -Level "INFO" |
| 147 | + } |
| 148 | + if ($nsg.DefaultSecurityRules.Count -gt 0) { |
| 149 | + Write-LogMessage "Default Rules: $($nsg.DefaultSecurityRules.Count)" -Level "INFO" |
| 150 | + } |
| 151 | + |
| 152 | + # Return the NSG object |
| 153 | + return $nsg |
| 154 | + |
| 155 | +} catch { |
| 156 | + Write-LogMessage "Failed to create Network Security Group: $($_.Exception.Message)" -Level "ERROR" |
| 157 | + throw |
| 158 | +} |
0 commit comments