Overview
Custom script extensions download and execute scripts on Azure Stack Hub virtual machines. Custom script extensions are useful for post deployment configuration, software installation, or any other configuration or management tasks.
This article explains how to add custom script extensions to new and existing VMs on Azure Stack Hub.
There are two options for deploying custom script extensions:
Prerequisites
To complete the steps in this article, you must have appropriate access to a subscription in the Azure Stack Hub portal.
Declare variables
Enter details below to provide values for the variables in the following scripts in this article:
Variable name |
Variable description |
Input |
$ArmEndpoint |
The Azure Resource Manager endpoint for Azure Stack Hub |
|
$RGName |
Name of the resource group |
|
$VMName |
Name of the virtual machine |
|
$CustomScriptFileName |
The name of the custom script file |
|
$ScriptArguments |
The command to execute |
|
Variable name |
Variable description |
Input |
$ContainerName |
The name of the container created in the storage blob |
|
$CustomScriptStorageAccountName |
The name of the new storage account |
|
$FilePath |
Path to the script on disk |
|
Variable name |
Variable description |
Input |
$FileUri |
URL to the custom script |
|
Select the desired deployment option:
See documentation here on how to create a new VM on Azure Stack Hub, then continue with the guide below.
Depending on whether you deploy a Windows or Linux VM, you will need to append the appropriate code to the end of the VM creation script.
Use the following code to authenticate to Azure Stack Hub, then continue with the guide below.
# Initialise environment and variables
# Declare endpoint
$ArmEndpoint = ""
# Add environment
Add-AzEnvironment -Name "AzureStackUser" -ArmEndpoint $ArmEndpoint
# Login
Connect-AzAccount -EnvironmentName "AzureStackUser"
# Get location of Azure Stack Hub
$Location = (Get-AzLocation).Location
In your PowerShell window:
Local disk
# Input variables
$RGName = ""
$VMName = ""
$CustomScriptFileName = ""
$ContainerName = ""
$CustomScriptStorageAccountName = "".ToLower()
$FilePath = ""
$ScriptArguments = ""
$CommandToExecute = "sh $CustomScriptFileName $ScriptArguments"
# Create a new storage account
Write-Output -InputObject "Creating storage account and container"
$StorageAccount = New-AzStorageAccount -Location $Location -ResourceGroupName $RGName -Type "Standard_LRS" -Name $CustomScriptStorageAccountName
# Get storage account context
$Context = $StorageAccount.Context
$Container = New-AzStorageContainer -Name $ContainerName -Context $Context
# Retrieve storage account key
$StorageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $RGName -Name $CustomScriptStorageAccountName).Value[0]
# Retrieve storage blob endpoint
$ScriptBlobUrl = $Container.Context.BlobEndPoint
# Upload script extension to the storage account
Write-Output -InputObject "Uploading custom script extension to storage account"
Set-AzStorageBlobContent -File $FilePath -Container $ContainerName -Blob $CustomScriptFileName -Context $Context
# Creating script location string
$ScriptLocation = $ScriptBlobUrl + "$ContainerName/" + $CustomScriptFileName
# Add custom script extension to Linux VM
Write-Output -InputObject "Adding custom script extension to VM"
$Extensions = Get-AzVMExtensionImage -Location $Location -PublisherName "Microsoft.Azure.Extensions" -Type "CustomScript"
$Extension = $Extensions | Sort-Object -Property Version -Descending | Select-Object -First 1
$ExtensionVersion = $Extension.Version[0..2] -join ""
$ScriptSettings = @{"fileUris" = @("$ScriptLocation")};
$ProtectedSettings = @{"storageAccountName" = $CustomScriptStorageAccountName; "storageAccountKey" = $StorageAccountKey; "commandToExecute" = $CommandToExecute};
Set-AzVMExtension -ResourceGroupName $RGName -Location $Location -VMName $VMName -Name $Extension.Type -Publisher $Extension.PublisherName -ExtensionType $Extension.Type -TypeHandlerVersion $ExtensionVersion -Settings $ScriptSettings -ProtectedSettings $ProtectedSettings
In your PowerShell window:
File URI
# Input variables
$RGName = ""
$VMName = ""
$CustomScriptFileName = ""
$FileUri = ""
$ScriptArguments = ""
$CommandToExecute = "sh $CustomScriptFileName $ScriptArguments"
# Add custom script extension to existing Linux VM
Write-Output -InputObject "Adding custom script extension to existing virtual machine"
$Extensions = Get-AzVMExtensionImage -Location $Location -PublisherName Microsoft.Azure.Extensions -Type "CustomScript"
$Extension = $Extensions | Sort-Object -Property Version -Descending | Select-Object -First 1
$ExtensionVersion = $Extension.Version[0..2] -join ""
$ScriptSettings = @{"fileUris" = @($FileUri); "commandToExecute" = $CommandToExecute};
Set-AzVMExtension -ResourceGroupName $RGName -Location $Location -VMName $VMName -Name $Extension.Type -Publisher $Extension.PublisherName -ExtensionType $Extension.Type -TypeHandlerVersion $ExtensionVersion -Settings $ScriptSettings
In your PowerShell window:
Local disk
# Input variables
$RGName = ""
$VMName = ""
$CustomScriptFileName = ""
$ContainerName = ""
$CustomScriptStorageAccountName = "".ToLower()
$FilePath = ""
$ScriptArguments = ""
$CommandToExecute = "powershell -ExecutionPolicy Unrestricted -file $CustomScriptFileName $ScriptArguments"
# Create a new storage account
Write-Output -InputObject "Creating storage account and container"
$StorageAccount = New-AzStorageAccount -Location $Location -ResourceGroupName $RGName -Type "Standard_LRS" -Name $CustomScriptStorageAccountName
# Get storage account context
$Context = $StorageAccount.Context
$Container = New-AzStorageContainer -Name $ContainerName -Context $Context
# Retrieve storage blob endpoint
$ScriptBlobUrl = $Container.Context.BlobEndPoint
# Upload script extension to the storage account
Write-Output -InputObject "Uploading custom script extension to storage account"
Set-AzStorageBlobContent -File $FilePath -Container $ContainerName -Blob $CustomScriptFileName -Context $Context
# Generate temporary SAS token for accessing the blob
$EndTime = (Get-Date).AddHours(2)
$BlobSasToken = $Container | New-AzStorageBlobSASToken -Container $ContainerName -Blob $CustomScriptFileName -Permission rw -ExpiryTime $EndTime
# Creating script location string
$ScriptLocation = $ScriptBlobUrl + "$ContainerName/" + $CustomScriptFileName + $BlobSasToken
# Add custom script extension to existing Windows VM
Write-Output -InputObject "Adding custom script extension to VM"
$Extensions = Get-AzVMExtensionImage -Location $Location -PublisherName "Microsoft.Compute" -Type "CustomScriptExtension"
$Extension = $Extensions | Sort-Object -Property Version -Descending | Select-Object -First 1
$ExtensionVersion = $Extension.Version[0..2] -join ""
$ScriptSettings = @{"fileUris" = @("$ScriptLocation") };
$ProtectedSettings = @{"commandToExecute" = $CommandToExecute };
Set-AzVMExtension -ResourceGroupName $RGName -Location $Location -VMName $VMName -Name $Extension.Type -Publisher $Extension.PublisherName -ExtensionType $Extension.Type -TypeHandlerVersion $ExtensionVersion -Settings $ScriptSettings -ProtectedSettings $ProtectedSettings
In your PowerShell window:
File URI
# Input variables
$RGName = ""
$VMName = ""
$CustomScriptFileName = ""
$FileUri = ""
$ScriptArguments = ""
$CommandToExecute = "powershell -ExecutionPolicy Unrestricted -file $CustomScriptFileName $ScriptArguments"
# Add custom script extension to Windows VM
Write-Output -InputObject "Adding custom script extension to VM"
$Extensions = Get-AzVMExtensionImage -Location $Location -PublisherName "Microsoft.Compute" -Type "CustomScriptExtension"
$Extension = $Extensions | Sort-Object -Property Version -Descending | Select-Object -First 1
$ExtensionVersion = $Extension.Version[0..2] -join ""
$ScriptSettings = @{"fileUris" = @("$FileUri") };
$ProtectedSettings = @{"commandToExecute" = $CommandToExecute };
Set-AzVMExtension -ResourceGroupName $RGName -Location $Location -VMName $VMName -Name $Extension.Type -Publisher $Extension.PublisherName -ExtensionType $Extension.Type -TypeHandlerVersion $ExtensionVersion -Settings $ScriptSettings -ProtectedSettings $ProtectedSettings
Feedback
If you find a problem with this article, click Improve this Doc to make the change yourself or raise an issue in GitHub. If you have an idea for how we could improve any of our services, send an email to feedback@ukcloud.com.