Run Scripts on Azure VMs with Custom Script Extension

Published:21 July 2019 - 3 min. read

Azure Cloud Labs: these FREE, on‑demand Azure Cloud Labs will get you into a real‑world environment and account, walking you through step‑by‑step how to best protect, secure, and recover Azure data.

As your team begins to provision and configure more Windows Azure virtual machines (VMs), at some point, you’ll get tired of reinventing the wheel. You need automation! In this article, come with me as I walk you through step-by-step to begin using Azure custom script extensions to use Azure to run scripts on your VMs.

If your team is in a Windows environment, one of the best tools to automate server configuration is PowerShell. By using the Azure PowerShell module, your organization can leverage the power of PowerShell not only to automate on-prem tasks but also to run commands on Azure VMs in bulk rather than one at a time.

One feature Microsoft has provided us is called the Azure custom script extension. The custom script extension is an Azure virtual machine extension that the VM agent runs to execute arbitrary PowerShell code against your VMs by using the Azure API rather than consoling into the VM or using PowerShell remoting.

Running commands this way provides several benefits. Running commands using the Azure custom extension in Windows:

  • provides increased security by not needing to open network ports for PowerShell remoting
  • allows for easy executing PowerShell code at VM startup
  • automatically transferring resources from Azure storage to your VM as part of the provisioning process
  • an easy way of running PowerShell scripts stored in various Azure storage accounts

Enabling an Azure custom script extension for Windows can be done in a few ways. In this article, we’ll be focusing on enabling the custom script extension via PowerShell, but you may also enable the extension via an Azure Resource Manager(ARM) template.

As a simple example, let’s say you’d like to ensure PowerShell remoting is enabled on an Azure VM in your subscription. To do this, you’d need to run the following command locally on each VM:

Enable-PSRemoting -Force

Let’s build a custom script extension to do this.

Using Azure to Run a Script on a VM

First, create a PowerShell script called Enable-PSRemoting.ps1 on your local computer with the command above inside. This script needs to run on an Azure VM. To do this, we’ll build another small PowerShell script called New-CustomScriptExtension.ps1 to get it uploaded into Azure and a custom script extension created to execute it. Before we get too far, you’ll need a couple items:

  • The Azure resource group and storage account name that will store the script
  • The Azure storage container name
  • The VM name
  • The Azure resource group name that the VM is in

This script can be broken down into two sections; getting the small PowerShell script uploaded to Azure and creating the custom script extension. Everything else is required to glue these two processes together.

Uploading a PowerShell Script to Azure

First, we’ll upload the Enable-PSRemoting.ps1 script to the Azure storage account ($StorageAccountName) inside of the container ($ContainerName) in the resource group ($ResourceGroupName).

$saParams = @{
    'ResourceGroupName' = $ResourceGroupName
    'Name' = $StorageAccountName
}
$storageContainer = Get-AzureRmStorageAccount @saParams |Get-AzureStorageContainer -Container $ContainerName
$bcParams = @{
    'File' = 'C:\Enable-PSRemoting.ps1'
    'BlobType' = 'Block'
    'Blob' = ' Enable-PSRemoting.ps1'
}
$storageContainer | Set-AzureStorageBlobContent @bcParams

Running the Custom Script Extension

When you run New-CustomScriptExtension.ps1, this script will upload the Enable-PSRemoting.ps1 script to the Azure storage account specified.

Now that the script is stored in Azure, you can execute it via the custom script extension for the VM:

  • Name: $VMName
  • Resource Group: $rgName
  • Storage Account: $saName
  • Storage Container: $scName

Open up a text editor for New-CustomScriptExtension.ps1 and paste in the below example. When you run this, it will execute the Azure custom script extension for Windows which will execute the Enable-PSRemoting.ps1 PowerShell script you uploaded earlier.

# Get the VM we need to configure
$vm = Get-AzureRmVM -ResourceGroupName $rgName -Name $VMName
# Get storage account key
$key = (Get-AzureRmStorageAccountKey -Name $saName -ResourceGroupName$rgname).Key1
## Enable the custom script extension and run the script
$scriptParams = @{
    'ResourceGroupName' = $rgName
    'VMName' = $VMName
    'Name' = 'Enable-PSRemoting.ps1'
    'Location' = $vm.Location
    'StorageAccountName' = $saName
    'StorageAccountKey' = $key
    'FileName' = 'Enable-PSRemoting.ps1'
    'ContainerName' = $scName
    'Run' = 'Enable-PSRemoting.ps1'
}
Set-AzureRmVMCustomScriptExtension @scriptParams

Summary

Once this script completes, you can verify that Enable-PSRemoting.ps1 has executed on the VM and PowerShell remoting has been successfully enabled. You should now be able to use Invoke-Command against your Azure VM.

By leveraging the Azure custom script extension in Windows, you now have the ability to remotely run any kind of PowerShell scripts on your Azure VMs.

Hate ads? Want to support the writer? Get many of our tutorials packaged as an ATA Guidebook.

Explore ATA Guidebooks

Looks like you're offline!