I am trying to automate my NSG creation, as well as NSG remediation for Azure via DevOps pipelines. Therefore, I wrote a PowerShell script that creates an ARM Template, which is deployable in Azure, from a CSV with the specified NSG ruleset. The script runs smoothly, but only when I am leaving out some quotes.
I am able to create this template:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"NSG_Name": {
"defaultValue": "XXXXXX0000-nsg",
"type": "String"
},
"Tag_SystemOwner": {
"defaultValue": "systemowner",
"type": "String"
},
"Tag_BusinessProcess": {
"defaultValue": "Network",
"type": "String"
},
"Tag_CostCenter": {
"defaultValue": "Group-IT",
"type": "String"
},
"Tag_MHP-ID": {
"defaultValue": "EUWAZP-XXXXX0000",
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2020-11-01",
"name": "[parameters(NSG_Name)]",
"location": "westeurope",
"tags": {
"SystemOwner": "[parameters(Tag_SystemOwner)]",
"CostCenter": "[parameters(Tag_CostCenter)]",
"MHP-ID": "[parameters(Tag_MHP-ID)]",
"BusinessProcess": "[parameters(Tag_BusinessProcess)]",
"NSG-Template-Build": "WillBeReplacedToBuildNumber"
},
"properties": {
"securityRules": [
{
...
}
]
}
}
]
}
But I need to get this code with the correct quotes, e.g. around the NSG_Name parameter:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"NSG_Name": {
"defaultValue": "XXXXXX0000-nsg",
"type": "String"
},
"Tag_SystemOwner": {
"defaultValue": "systemowner",
"type": "String"
},
"Tag_BusinessProcess": {
"defaultValue": "Network",
"type": "String"
},
"Tag_CostCenter": {
"defaultValue": "Group-IT",
"type": "String"
},
"Tag_MHP-ID": {
"defaultValue": "EUWAZP-XXXXX0000",
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2020-11-01",
"name": "[parameters('NSG_Name')]",
"location": "westeurope",
"tags": {
"SystemOwner": "[parameters('Tag_SystemOwner')]",
"CostCenter": "[parameters('Tag_CostCenter')]",
"MHP-ID": "[parameters('Tag_MHP-ID')]",
"BusinessProcess": "[parameters('Tag_BusinessProcess')]",
"NSG-Template-Build": "WillBeReplacedToBuildNumber"
},
"properties": {
"securityRules": [
{
...
}
]
}
}
]
}
However, when adding the single quote around the 'NSG_Name' the PowerShell script outputs the following error:
param(
[Parameter(Mandatory=$true)]
[String]$filename
)
$arm = '{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"NSG_Name": {
"defaultValue": "XXXXXX0000-nsg",
"type": "String"
},
"Tag_SystemOwner": {
"defaultValue": "systemowner",
"type": "String"
},
"Tag_BusinessProcess": {
"defaultValue": "Network",
"type": "String"
},
"Tag_CostCenter": {
"defaultValue": "Group-IT",
"type": "String"
},
"Tag_MHP-ID": {
"defaultValue": "EUWAZP-XXXXX0000",
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2020-11-01",
"name": "[parameters('NSG_Name')]",
"location": "westeurope",
"tags": {
"SystemOwner": "[parameters(Tag_SystemOwner)]",
"CostCenter": "[parameters(Tag_CostCenter)]",
"MHP-ID": "[parameters(Tag_MHP-ID)]",
"BusinessProcess": "[parameters(Tag_BusinessProcess)]",
"NSG-Template-Build": "WillBeReplacedToBuildNumber"
},
"properties": {
"securityRules": [
'
Import-Csv -Path $env:SYSTEM_DEFAULTWORKINGDIRECTORY\$filename -Delimiter ";" | ForEach {
if($_.SourcePortRange -Match "," ) {
$SPRS = $_.SourcePortRange
$SPR = """*"""
} else {
$SPRS = $NULL
$SPR = $_.SourcePortRange
}
if($_.DestinationPortRange -Match "," ) {
$DPRS = $_.DestinationPortRange
$DPR = """*"""
} else {
$DPRS = $NULL
$DPR = $_.DestinationPortRange
}
if($_.SourceAddressPrefix -Match "," ) {
$SAPS = $_.SourceAddressPrefix
$SAP = """*"""
} else {
$SAPS = $NULL
$SAP = $_.SourceAddressPrefix
}
if($_.DestinationAddressPrefix -Match "," ) {
$DAPS = $_.DestinationAddressPrefix
$DAP = """*"""
} else {
$DAPS = $NULL
$DAP = $_.DestinationAddressPrefix
}
Write-Host "RuleName:" $_.RuleName
Write-Host "SourcePortRanges:" $SPRS
Write-Host "SourcePortRange:" $SPR
Write-Host "DestinationPortRanges:" $DPRS
Write-Host "DestinationPortRange:" $DPR
Write-Host "SourceAddressPrefixes:" $SAPS
Write-Host "SourceAddressPrefix:" $SAP
Write-Host "DestinationAddressPrefixes:" $DAPS
Write-Host "DestinationAddressPrefix:" $DAP
$jsonrule = "{
""name"": ""$($_.RuleName)"",
""properties"": {
""description"": ""$($_.Description)"",
""protocol"": ""$($_.Protocol)"",
""sourcePortRange"": $SPR,
""destinationPortRange"": $DPR,
""sourceAddressPrefix"": $SAP,
""destinationAddressPrefix"": $DAP,
""access"": ""Allow"",
""priority"": ""$($_.Priority)"",
""direction"": ""$($_.Direction)"",
""sourcePortRanges"": [$SPRS],
""destinationPortRanges"": [$DPRS],
""sourceAddressPrefixes"": [$SAPS],
""destinationAddressPrefixes"": [$DAPS]
}
},"
$arm+=$jsonrule
}
$arm = $arm.Substring(0,$arm.Length-1)
$arm+='
]
}
}
]
}'
$filename = "$env:SYSTEM_DEFAULTWORKINGDIRECTORY" + "\ARM-Templates\NSG-Governance\template.json"
$arm | out-file $filename
+ "name": "[parameters('NSG_Name')]",
+ ~~~~~~~~~~~~~
Unexpected token 'NSG_Name')]",
"location": "westeurope",
"tags": {
"SystemOwner": "[parameters(Tag_SystemOwner)]",
"CostCenter": "[parameters(Tag_CostCenter)]",
"MHP-ID": "[parameters(Tag_MHP-ID)]",
"BusinessProcess": "[parameters(Tag_BusinessProcess)]",
"NSG-Template-Build": "WillBeReplacedToBuildNumber"
},
"properties": {
"securityRules": [
'' in expression or statement.
##[error]PowerShell exited with code '1'.
Has someone any solution for this problem? Any help would be much appreciated! Unfortunately, Microsoft Doc about quoting rules does not help me.
Thank you!
Kind regards, Moritz.
You can add both single and double quotes to a variable using ` along with double quotes. Below is an example, hope it helps.
$ex
will have the value as:Let me know if this is not what you are looking for.