Q. How can I inject PowerShell into an Azure VM via the Azure VM agent?

A. The Azure VM Agent enables many different types of extensions to be used with the VM. One of the extension types is CustomScriptExtension which enables PowerShell to be executed inside the VM. The PowerShell can be stored as a blob inside an Azure storage account (which can easily be copied up to Azure using Azure Storage Explorer (http://storageexplorer.com/) or via PowerShell) then executed.

Below is example PowerShell that leverages a PowerShell script stored in a blob. In this example the script is called FirstBoot.ps1 and stored in a folder named scripts of the storage account. note you should populate the script with your storage account information and key.

$ScriptBlobAccount = "<name of storage account>"
$ScriptBlobKey = "<key for your storage account>"
$ScriptBlobURL = "https://<name of storage account>.blob.core.windows.net/scripts/"
$ScriptName = "FirstBoot.ps1"
$ExtensionName = 'FirstBootScript'
$ExtensionType = 'CustomScriptExtension'
$Publisher = 'Microsoft.Compute'  
$Version = '1.8'
$timestamp = (Get-Date).Ticks
$ScriptLocation = $ScriptBlobURL + $ScriptName
$ScriptExe = ".\$ScriptName"
$PrivateConfiguration = @{"storageAccountName" = "$ScriptBlobAccount";"storageAccountKey" = "$ScriptBlobKey"}
$PublicConfiguration = @{"fileUris" = [Object[]]"$ScriptLocation";"timestamp" = "$timestamp";"commandToExecute" = "powershell.exe -ExecutionPolicy Unrestricted -Command $ScriptExe"}
Write-Output "Injecting First Boot PowerShell" | timestamp
Set-AzureRmVMExtension -ResourceGroupName $RGName -VMName $VMName -Location $Location `
-Name $ExtensionName -Publisher $Publisher -ExtensionType $ExtensionType -TypeHandlerVersion $Version `
-Settings $PublicConfiguration -ProtectedSettings $PrivateConfiguration

You can check on the state of the extension execution using:

((Get-AzureRmVM -Name $VMName -ResourceGroupName $RGName -Status).Extensions | Where-Object {$_.Name -eq $ExtensionName}).Substatuses

Inside the VM the extension writes to C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\<version>. In the Downloads folder is the actual PowerShell downloaded and Status folder contains the information (that is returned by the above PowerShell). More information on troubleshooting can be found at https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-windows-extensions-troubleshoot/.

If you wish to call another instance for CustomScriptExtension to run another script (although you can pass an array of scripts in one execution that will run in series) you must first remove the existing CustomScriptExtension instance since a VM can have only one.

Remove-AzureRmVMExtension -ResourceGroupName $RGName -VMName $VMName -Name FirstBootScript -Force