Skip to main content
Unlisted page
This page is unlisted. Search engines will not index it, and only users having a direct link can access it.

Microsoft Azure AutoScale (Windows)

Azure

warning

The following instructions utilize the Azure CLI. You can open the CLI in the Azure web portal and run these commands directly. See Microsoft's instructions for basic usage of the Azure Cloud Shell environment.

The next step in the AutoScale Configuration is the VM Provider Details page.

  1. Select Azure from the Provider Drop Down.

  2. Provide a name for your configuration.

  3. Enter a Subscription ID, Resource Group, and Tenant ID.

  4. Enter the Client ID and Client Secret created by following the Azure App Registration instructions.

  5. Select the Azure Authority from the drop down. Most users will select Azure Public Cloud.

  6. Enter the region name, you can use the following Azure CLI command to list available regions, use the Name column.

    az account list-locations -o table
  7. Enter the Maximum Instances. This puts an upper limit on the number of VMs this auto scale configuration can create.

  8. Enter a VM Size by name. Use the following Azure CLI command to list all VM sizes available in the desired region.

    az vm list-sizes --location "westus"
  9. Enter the OS Disk Type, using the Azure Disk Type SKU. The following is the current list of available type names. Not all disk SKUs are compatible with all VM size types.

    Disk Type Name
    Standard_LRS
    Standard_GRS
    Standard_RAGRS
    Standard_ZRS
    Premium_LRS
    Premium_ZRS
    Standard_GZRS
    Standard_RAGZRS
  10. Enter the OS Disk Size, in gigabytes. The size need to be at least the size of the target OS Image Reference, defined in the next field.

  11. Enter the OS Image Reference JSON. Use the following Azure CLI command to list images in the JSON format expected by Kasm. Note that these are default Azure provided images, however, you will most likely need to create a Custom Image.

    # List Windows Server Editions using the offline list (faster)
    az vm image list --architecture x64 --location westus --offer WindowsServer
    # Search the full Marketplace for Desktop versions of Windows
    az vm image list --architecture x64 --location westus --all --publisher MicrosoftWindowsDesktop

Here is an example of an OS Image Reference JSON value returned by one of the above queries that can be used.

{
"architecture": "x64",
"offer": "windows-ent-cpc",
"publisher": "MicrosoftWindowsDesktop",
"sku": "win11-22h2-ent-cpc-os",
"urn": "MicrosoftWindowsDesktop:windows-ent-cpc:win11-22h2-ent-cpc-os:22621.963.221213",
"version": "22621.963.221213"
}
  1. Check the Image is Windows checkbox.

  2. Enter the target Network Security Group. In the Azure portal, find your Network Security Group, go to Properties, and find the Resource ID field.

  3. Enter the target Subnet. In the Azure portal, find your subnet, go to Properties, and find the Resource ID field.

  4. Check the Assign Public IP box if you desire your VMs to have public IP addresses. It is more secure to not have public IP addresses assigned. Kasm will provide a secure way to provide access to private systems and therefore, it is not strictly necessary to have a public IP.

  5. Optionally provide additional tags for the VM, use empty {} brackets if no additional tags are needed.

  6. Enter a public SSH Key, this is required even for Windows systems.

  7. Enter a PowerShell startup script. Azure does not automatically run this script on startup like other cloud providers. You will need to create Custom Image in order for the startup script to execute on boot. The following example will create a local user account using the Connection Username and Connection Password fields specified on the previous screen. This is only relevant if you are using static credentials and will not work Active Directory integration.

    $pass = ConvertTo-SecureString -String "{connection_password}" -AsPlainText -Force

    New-LocalUser -Name {connection_username} -Description 'Programatically generated Kasm user account' -Password $pass -PasswordNeverExpires -AccountNeverExpires | Add-LocalGroupMember -Group administrators | Add-LocalGroupMember -Group "Remote Desktop Users"

    Start-Service -Name "Audiosrv"
  8. Enter a Config Override as JSON. This the Image Reference (VERSION_ID from Custom Image Step 13 below) be provided. Additionally, in the example we used Windows 11, which requires SecureBoot to be enabled and the securityType to be set to TrustedLaunch. This is not required for older versions of Windows such as Windows 10 and therefore it is not required to provide override settings for those cases. Finally, some plans in Azure require that the Plan object be included as well. Below are examples for a Windows 10 image, without securityType, and for a Windows 11 image with securityType. Both include the Plan object, but that object may be left out for some plans.

    {
    "virtual_machine": {
    "plan": {
    "name": SKU,
    "product": OFFER,
    "publisher": PUBLISHER
    },
    "properties": {
    "storageProfile": {
    "imageReference": {
    "id": VERSION_ID
    }
    }
    }
    }
    }
    {
    "virtual_machine": {
    "plan": {
    "name": SKU,
    "product": OFFER,
    "publisher": PUBLISHER
    },
    "properties": {
    "securityProfile": {
    "securityType": "TrustedLaunch",
    "uefiSettings": {
    "secureBootEnabled": true,
    "vTpmEnabled": true
    }
    },
    "storageProfile": {
    "imageReference": {
    "id": VERSION_ID
    }
    }
    }
    }
    }

Custom Image

Unlike most other cloud providers, Azure does not automatically execute the startup script on boot. You need to create a custom image and implement your own method of executing that script on boot. The following method has been tested by Kasm, but is by no means the only method that can be used. These procedures are only necessary if you want to utilize Kasm's startup script injection and perform custom actions on boot of the VMs.

  1. Manually create a VM using the appropriate base image, such as Windows 11 Enterprise

  2. Install the required software and configure the OS as appropriate for your environment

  3. Create a file with the following contents at C:\AzureData\startup.cmd

    schtasks /Delete /TN "DomainJoin" /F
    cd C:\AzureData

    setlocal EnableExtensions EnableDelayedExpansion
    set tries=0

    :CheckForFile
    IF EXIST CustomData.bin GOTO FoundIt
    set /a tries+=1
    IF !tries! GEQ 40 GOTO Timeout
    TIMEOUT /T 15 >nul
    GOTO CheckForFile

    :FoundIt
    ren CustomData.bin CustomData.ps1
    PowerShell -Command "Set-ExecutionPolicy Unrestricted"
    PowerShell -file C:\AzureData\CustomData.ps1
    GOTO End

    :Timeout
    REM Timed out waiting for CustomData.bin (40 x 15s)
    echo ERROR: Timed out waiting for CustomData.bin after %tries% attempts (about 10 minutes).

    :End
  4. Open a Windows Command Prompt as an Administrator and execute the following command.

    schtasks /create /tn "DomainJoin" /sc onstart /rl highest /ru system /tr "cmd /c C:\AzureData\startup.cmd > C:\AzureData\startup.log 2>&1"
  5. Run sysprep on the VM and shut it down. Run the following in an elevated command prompt.

    cd %windir%\system32\sysprep
    sysprep.exe /oobe /generalize /mode:vm /shutdown
    warning

    You may get an error message when running the above command on a Windows 11 system using the default Azure provided image. Look at the log file indicated by the error message. If you see an error message near the bottom of the logs indicating OneDriveSync was installed for the user but not provisioned for all users, remove the software from an elevated PowerShell session with the following command. Try sysprep again after running this command.

    get-appxpackage -allusers -name "microsoft.Onedrivesync" | Remove-appxpackage
  6. Open a Cloud Shell in Azure and run the following command to get a list of VMs and find the VM that you just ran sysprep on.

    az vm list -otable
  7. The table provided by the above command will contain the VM name and its resource group name. Plug in your VM name and resource group name into the below command in order to generalize the VM.

    az vm generalize -g RESOURCE_GROUP_NAME -n VM_NAME
  8. Create a Gallery, if one is not already available for the location of the Custom Image VM, which is how images are shared and organized in Azure. Plug in your resource group name and your desired Gallery name.

    az sig create --resource-group RESOURCE_GROUP_NAME --gallery-name GALLERY_NAME
  9. Obtain the full ID of the VM you want to create an image from. Plug in your resource group name and VM name into the below command.

    az vm get-instance-view -g RESOURCE_GROUP_NAME -n VM_NAME --query id

    The output should look similar to the following and will be used in step 11.

    "/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP_NAME>/providers/Microsoft.Compute/virtualMachines/<VM_NAME>"
  10. From the Azure portal search bar, search for 'Azure compute galleries' and find the Gallery you created on step 8. Click into that gallery. Click the drop down on the Add button and select 'VM Image Definition'. Provide a VM image definition name and select Windows as the OS Type. The Security Type and VM generation may differ based on what base image you started from. For Windows 11, select Trusted Launch for the Security Type, which will lock you into VM generation 2. The Publisher, Offer, and SKU can all be found in the Azure Portal on the VM page, under Source Image Details. After creating the image definition, take note of the name for the subsequent steps.

  11. Create a Managed Image using the below command for your desired MANAGED_IMAGE_NAME and appropriate os-type and hyper-v-generation depending on what was selected in Step 10 (using Windows and V2 for the example below).

    az image create --resource-group RESOURCE_GROUP_NAME --name MANAGED_IMAGE_NAME --source "VM_ID" --os-type Windows --hyper-v-generation V2 --location "eastus"
  12. Create an Image version. Plug in your resource group name, gallery name, image definition, desired version number, location, and target regions into the following Azure CLI command. For the managed-image field, use the managed image name you created in step 11. Target regions must include both the region your image is in and the region your resource group is in, if different.

    az sig image-version create \
    --resource-group RESOURCE_GROUP_NAME \
    --gallery-name GALLERY_NAME \
    --gallery-image-definition IMAGE_DEFINITION_NAME \
    --gallery-image-version 1.0.0 \
    --location "eastus"
    --target-regions "eastus" \
    --replica-count 2 \
    --managed-image MANAGED_IMAGE_NAME

    Make note of the ID returned from the above command for the next step.

  13. In the VM Provider configuration, Step 11 and Step 19, put the ID returned by the previous step into the OS Image Reference and Config Override fields. The following is an example.

    {
    "id": "/subscriptions/<Subscription_ID>/resourceGroups/<RESOURCE_GROUP_NAME>/providers/Microsoft.Compute/galleries/<GALLERY_NAME>/img/IMAGE_DEFINITION_NAME/versions/1.0.0"
    }