Edit

Application installation using RemoteApp Virtual Machine

Install an application via Virtual Machine service catalog template.

The application installation scripting supports the following scenarios:

  • The most common use case for the RemoteApp app installation is to deploy remote applications that can be accessed from an Azure Virtual Destop.
  • Install your prerequisites such as cyber security and monitoring agents.
  • Script configuration changes for compliance or application setup.

Note

This sample deployment is just for demo purposes and doesn't represent all the best practices for network, systems, or applications administration.

Prerequisites

The RemoteApp template supports scripting to automate the process of installing applications and configuring the Virtual Machine. Before you can start using the RemoteApp app installation, you need to make sure you have:

  • A community, enclave, workload, and at least one workload resource group and permissions to create resources inside the workload resource group.
  • Enable Advanced maintenance mode for your enclave so you can add the Private Link resources to your enclave managed resource group.
  • A container (artifacts) within the storage account.
  • A community endpoint to the storage account and optionally to an existing copy of AzCopy.exe.
  • A copy of AzCopy.exe
    • Download AzCopy.
    • Upload the AzCopy installer to the storage account at the same level as your app folder.
    • File Structure:
          - storage account
              - artifacts container
                  - app folder
                  - azcopy.exe 
      
      Screenshot showing storage container organization structure with multiple app folders in the same container and using the same copy of AzCopy.exe.
  • Enclave connections between the previously made community endpoints and the enclave subnet.

Note

If the storage account is in a different enclave, create an enclave endpoint in the enclave with the storage account. Then create an enclave connection between that storage account enclave and the enclave where you're installing the application.

Azure Resources Deployed

  • RemoteApp example Virtual Machine
    • Disk
    • Windows Virtual Machine
    • Windows Virtual Machine Extension

Software Deployed

  • Windows
  • Application of your choice

Installation

Set up Storage Account to install Visual Studio Code

  1. Add app folder to container within storage account. Diagram showing method of installation within the same enclave. Diagram showing method of installation outside enclave that contains the storage account.
    • File Structure:
          - artifacts container
              - app folder
                  - app installer
                  - main script to install app
                  - (optional) additional scripts
                  - (optional) azcopy.exe
      
  2. Download the application installer you need. In this example download Vscode.exe and upload the installer into the storage account app folder.
  3. Upload the main.ps1 application installer script compatible with the version of Visual Studio Code you added to the storage account app folder:
        # Main powershell script that installs the application
    
        Start-Process 'C:/vscode/VSCodeSetup-x64-{version}.exe' -Argument "/VERYSILENT /MERGETASKS=!runcode"
    

Setup Template

  1. On the workload overview page, select +Add an Azure Service.

Screenshot showing workload overview page.

  1. For Service, select Virtual Machine.

Screenshot showing Virtual Machine selected from the service catalog list.

  1. Confirm the resource group selection and select Next

  2. Basics Tab:

    • For Virtual Machine name, input the name of the Virtual Machine.
    • For Admin username and Admin password, input the username and password you use to log into your Virtual Machine.
  3. App Tab:

    • For App folder URI, input the URI to the container. Select an artifact within the container, copy its URI, remove everything after the folder name in the URI. Screenshot showing the application folder URI for use in this deployment.

      Original URI Fixed URI
      https://<storage-account>.blob.core.windows.net/<container-name>/<folder-name>/<script>.ps1 https://<storage-account>.blob.core.windows.net/<container-name>/<folder-name>
    • Example:

      • storageaccountexample.blob.core.windows.net/artifacts/vscode
    • For Main Script input the name (ex: main.ps1) of the script that installs the application.

    Screenshow showing the App tab during a Virtual Machine deployment.

Private Container:

  1. For App folder in private container select true to allow reader role access to the storage account via the Virtual Machine.

  2. For Storage container resource id get the following three parts: <storage-account-resource-id> + '/blobServices/default/containers/' + <container-name>.

    • To get Storage container resource id, from the storage account, select "Overview," select "JSON View" in the far right corner, copy the storage account resource ID.

    Screenshot of account resource id for use in this deployment.

    • For the container name, copy the name of the private container that holds the artifacts.
    • Example storage container resource ID: subscriptions/000000a0-a0a0-000a-00a0-0000aaa0a000/resourceGroups/providers/Microsoft.Storage/storageAccounts/storage-account-example/blobServices/default/containers/container-name
  3. If the parameter AzCopy File URI is displayed, add the URI to the azcopy.exe from the container

    • Select the file, and copy its URL:

    Screenshot showing storage container organization structure with azcopy.exe file.

    Screenshot showing the URI for the azcopy.exe file.

Example Private Container Parameters:

Screenshot showing the App tab parameters completed.

  1. Select Review and Create, if validations pass, select Create.
  2. Once resources are deployed, check to see if app is installed on application Virtual Machine by connecting to the Application Virtual Machine. Connect to the Application Virtual Machine

WinGet Installation

Folder Structure:

- artifacts container
    - WinGet app folder ('winget')
        - WinGet installer ('Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle')
        - Windows UI Library ('Microsoft.UI.Xaml.2.8.x64.appx')
        - main script to schedule install ('main.ps1')
        - script to install and schedule reboot('install_winget.ps1')
        - ('restart.ps1')

Screenshot showing the artifacts needed to install winget onto the RemoteApp to then install and manage other applications using winget.

  1. Download installers and upload them to the winget folder in storage container
  2. Create and upload scripts
    1. main.ps1
      # This script creates and runs a scheduled task to install the appx package and msix bundle with elevated privileges
      
      $installScriptPath = "C:\winget\install_winget.ps1"
      
      # Create a scheduled task action to run the installation script with elevated permissions
      $taskAction = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-ExecutionPolicy Bypass -File $installScriptPath"
      
      # Set the task to start 30 seconds from now
      $taskTrigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddSeconds(30)
      $taskPrincipal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
      
      # Register the scheduled task
      Register-ScheduledTask -TaskName "InstallWinget" -Action $taskAction -Trigger $taskTrigger -Principal $taskPrincipal
      
    2. install_winget.ps1
      Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force
      
      Start-Process -FilePath "DISM.exe" -ArgumentList "/Online /Add-ProvisionedAppxPackage /PackagePath:C:\winget\Microsoft.UI.Xaml.2.8.x64.appx /SkipLicense" -NoNewWindow -Wait
      Start-Process -FilePath "DISM.exe" -ArgumentList "/Online /Add-ProvisionedAppxPackage /PackagePath:C:\winget\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle /SkipLicense" -NoNewWindow -Wait
      
      $wingetDir = 'C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_1.23.1791.0_x64__8wekyb3d8bbwe'
      $currentPath = [System.Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::Machine)
      [System.Environment]::SetEnvironmentVariable("Path", "$currentPath;$wingetDir", [System.EnvironmentVariableTarget]::Machine)
      
      # Schedule the reboot script
      $rebootScriptPath = "C:\winget\reboot.ps1"
      $taskAction = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-ExecutionPolicy Bypass -File $rebootScriptPath"
      
      # Set the task to start 30 seconds from now
      $taskTrigger = New-ScheduledTaskTrigger -Once -At ((Get-Date).AddSeconds(30))
      $taskPrincipal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
      
      # Register the scheduled task
      Register-ScheduledTask -TaskName "Reboot" -Action $taskAction -Trigger $taskTrigger -Principal $taskPrincipal
      
    3. restart.ps1
      Restart-Computer -Force
      
  3. Proceed to Deploy Template