Problem scenario
You want to use an ARM template via a PowerShell script to create a storage account in Azure. How do you do this?
Solution
Prerequisites
1. If you are using Windows 7, you have installed Azure PowerShell; if you need assistance with this, see this posting. If you are using Windows 10, you have installed the modules for Azure and the storage resource; if you need assistance with this, see this posting.
2. You know your subscription ID. If you need assistance, see this posting.
Procedures
1. Create a parameters.json file with the following content, but replace foobar with the name you want this storage account to have:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"value": "northcentralus"
},
"storageAccountName": {
"value": "foobar"
},
"accountType": {
"value": "Standard_RAGRS"
},
"kind": {
"value": "StorageV2"
},
"accessTier": {
"value": "Hot"
},
"supportsHttpsTrafficOnly": {
"value": true
}
}
}
2. Create a template.json file with the following content:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string"
},
"storageAccountName": {
"type": "string"
},
"accountType": {
"type": "string"
},
"kind": {
"type": "string"
},
"accessTier": {
"type": "string"
},
"supportsHttpsTrafficOnly": {
"type": "bool"
}
},
"variables": {},
"resources": [
{
"name": "[parameters('storageAccountName')]",
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2018-07-01",
"location": "[parameters('location')]",
"properties": {
"accessTier": "[parameters('accessTier')]",
"supportsHttpsTrafficOnly": "[parameters('supportsHttpsTrafficOnly')]"
},
"dependsOn": [],
"sku": {
"name": "[parameters('accountType')]"
},
"kind": "[parameters('kind')]"
}
],
"outputs": {}
}
3. Use this PowerShell script as a draft: first, modify "path\to" to be the paths of the respective files that are assigned. Secondly change "foobargroup" to a Resource Group name; if you need assistance with finding an existing Resource Group, see this posting or this posting.
<#
.SYNOPSIS
Deploys a template to Azure
.DESCRIPTION
Deploys an Azure Resource Manager template
.PARAMETER subscriptionId
The subscription id where the template will be deployed.
.PARAMETER resourceGroupName
The resource group where the template will be deployed. Can be the name of an existing or a new resource group.
.PARAMETER resourceGroupLocation
Optional, a resource group location. If specified, will try to create a new resource group in this location. If not specified, assumes resource group is existing.
.PARAMETER deploymentName
The deployment name.
.PARAMETER templateFilePath
Optional, path to the template file. Defaults to template.json.
.PARAMETER parametersFilePath
Optional, path to the parameters file. Defaults to parameters.json. If file is not found, will prompt for parameter values based on template.
#>
param(
# [Parameter(Mandatory=$True)]
# [string]
# $subscriptionId,
# [Parameter(Mandatory=$True)]
# [string]
# $resourceGroupName = "foobargroup",
[string]
$resourceGroupLocation,
[Parameter(Mandatory=$True)]
[string]
$deploymentName,
[string]
$templateFilePath = "C:\path\to\template.json",
[string]
$parametersFilePath = "C:\path\to\parameters.json"
)
<#
.SYNOPSIS
Registers RPs
#>
Function RegisterRP {
Param(
[string]$ResourceProviderNamespace
)
Write-Host "Registering resource provider '$ResourceProviderNamespace'";
Register-AzureRmResourceProvider -ProviderNamespace $ResourceProviderNamespace;
}
#******************************************************************************
# Script body
# Execution begins here
#******************************************************************************
$ErrorActionPreference = "Stop"
# sign in
Write-Host "Logging in...";
Login-AzureRmAccount;
$subscriptions= Get-AzureRmSubscription
$subscriptionId = $subscriptions.Id
$resourceGroupName = "contintgroup"
# select subscription
#Write-Host "Selecting subscription '$subscriptionId'";
echo "This PowerShell Program assumes you have only one subscription ID. If you have more than one, you'll need to re-write it around this statement"
echo "and in the parameters section."
Select-AzureRmSubscription -SubscriptionID $subscriptionId;
# Register RPs
$resourceProviders = @("microsoft.storage");
if($resourceProviders.length) {
Write-Host "Registering resource providers"
foreach($resourceProvider in $resourceProviders) {
RegisterRP($resourceProvider);
}
}
#Create or check for existing resource group
$resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue
if(!$resourceGroup)
{
Write-Host "Resource group '$resourceGroupName' does not exist. To create a new resource group, please enter a location.";
if(!$resourceGroupLocation) {
$resourceGroupLocation = Read-Host "resourceGroupLocation";
}
Write-Host "Creating resource group '$resourceGroupName' in location '$resourceGroupLocation'";
New-AzureRmResourceGroup -Name $resourceGroupName -Location $resourceGroupLocation
}
else{
Write-Host "Using existing resource group '$resourceGroupName'";
}
# Start the deployment
Write-Host "Starting deployment...";
if(Test-Path $parametersFilePath) {
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile $templateFilePath -TemplateParameterFile $parametersFilePath;
} else {
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile $templateFilePath;
}
echo "***********************************************"
echo "The deploymentName can be any arbitrary string. (this statement is for when the program initially runs and prompts user for a deploymentname; ignore it later)"
In the future we want to re-write these directions to use write-verbose instead of write-host. We want to warn people that write-verbose is recommended instead of write-host (according to this posting).