Build Your Own Web Launcher for AVD

AVD Azure

URI Schemes with the Remote Desktop Client for AVD let you launch apps from your own web page!

There’s a cool new preview feature for AVD that lets you craft URIs (you know, like URLs on a webpage) to launch AVD session from the Remote Desktop Windows client. You can read all about it here:
https://learn.microsoft.com/en-us/azure/virtual-desktop/uri-scheme

Also, check out this other approach to building an AVD web launcher once you are done here: AVD Web Launcher Using Only “Local Stuff” – Azure Advanced Migration Topics for Government (azurewebsites.us).

Note that as of right now the feature:

  • Is in preview
  • Does not work with Azure Gov (yet)
  • Only works with the Windows Remote Desktop Client 1.2.4065 or later

What it lets you do is craft URIs that you can embed in web pages for users to launch apps.

If you read the “learn” post above, you’ll see an example URI that looks like this:

I want to walk you through an example of how you might form that URI above… nothing near production ready, just enough to build some understanding.
First a shout out to John Wilson and Joel Sisko on the team for working on this!

Now, let me show you a little bit about the AVD environment I have setup – it’s small with a few one application group and one Workspace:

That’s enough to build out some PowerShell to use the URI feature.

The first thing we need to do in our PowerShell is to set some variables for our environment – typical Azure stuff like the RG, subscription, and some of the AVD chunks we are targeting to pull from, as well as setting the UPN suffix (we’ll need that later):

$ResourceGroup = "AVD"
$AppResourceGroup = $ResourceGroup
$SubscriptionID = "11111111-1111-1111-1111-11111111"
$WorkspaceName = "Desktops"
$AppGroupName = "Apps"
$UPN_Suffix = "@gbbcore.com"

Now we’ll get the local (Windows) user ID, to highlight that we need the actual user ID to build the URI (and that we may not have the $UPN for an AD joined workstation/user):

$Shell = New-Object -ComObject ("WScript.Shell")
$ShortCut = $Shell.CreateShortcut($env:USERPROFILE + "\downloads\Comet.url")
$userID = $env:USERNAME+$UPN_Suffix
$webfile = "C:\Users\" + $env:USERNAME + "\downloads\myfile.html"

We also created a “webfile” variable based on that local user where we can create our HTML file.

Next, we’ll log into Azure and get our AVD “stuff”:

Login-AzAccount
Select-AzSubscription -SubscriptionId $SubscriptionID
$Workspace = Get-AzWvdWorkspace -name $WorkspaceName -ResourceGroupName $ResourceGroup
$AppGroup = Get-AzWvdApplicationGroup -name $appGroupName -ResourceGroupName $AppResourceGroup
$apps = Get-AzWvdApplication -ApplicationGroupName $AppGroup.name -ResourceGroupName $AppResourceGroup

What we were after where the object IDs for the Workspace and each Application in the App Group.

Now we’ll do something boring (and non-AVD), and writeout the header to our HTML file:
(had to stick in a code block… since IT’S HTML!):

new-item $webfile -itemtype File -force
# Added some HTML Formating John Wilson
add-content $webfile "<!DOCTYPE html>`n<html>`n<body>`n`n<h1>AVD Applications & Desktops</h1>`n"
add-content $webfile "<style>"
add-content $webfile "a {color: white;}"
add-content $webfile "link {color: white;}"
add-content $webfile "<head>"
Add-content $webfile "body {background-color: powderblue;font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;}"
Add-content $webfile "body {font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;}"
#add-content $webfile "button {font-family: Arial, Helvetica;font-size: 16px;padding: 10px;background: white;color: white;display: inline;border: 0;text-decoration: none;line-height: 17px;}"
Add-Content $webfile "button {  display: inline-block;border-radius: 12px;background-color: blue;padding: 10px;width: 250px;color: #ffffff;text-align: center;  border: 4px double #cccccc;border-radius: 10px;font-size: 18px; }"
Add-Content $webfile "button span {cursor: pointer;display: inline-block;position: relative:transition:0.5s}"
Add-Content $webfile "button span:after {content: '\00bb';position: absolute;opacity: 0;top: 0;right: -20px;transition:0.5:}"
#Add-Content $webfile "button { display: inline-block;background-color: #7b38d8;padding: 20px;width: 200px;color: #ffffff;text-align: center;  border: 4px double #cccccc;border-radius: 10px;font-size: 28px; }"
Add-Content $webfile "h1   {color: blue;}"
add-content $webfile "</style>"

The last bit of magic is where we actually form the URIs, create our “buttons, and launch our new little web page:

Foreach ($App in $Apps) {  
    $URL = -join("ms-avd:connect?workspaceId=", $Workspace.ObjectID, "&resourceid=", $app.ObjectID, "&username=", $UserID, "&version=0")
    $APPNAME = $app.name -split "/"
    $APPNAME = $APPNAME[1]
    add-content $webfile "<p>`n----------------------------------------------------------------------`n</p>"
    add-content $webfile "<p><button><a href=`"$URL`">$APPNAME</a>`n`n</button></p>"
}
add-content $webfile "`n`n</body>`n</html>"
#
###############################################################################################################
#
# open up new custom web page!
#
Invoke-item $webfile

What we get is a not so glamours little web page that let us launch AVD sessions – in this case the apps from our “Apps” group:

When you click on an app (like say Word), the web site reaches back to the PC and fires up the Remote Desktop Client using the URI:

….and your Remote App (or desktop session) starts:

Here’s the full sample code all in one block:

##############################################################################################################
# https://learn.microsoft.com/en-us/azure/virtual-desktop/uri-scheme
# sample code to create a local custom webpage to launch AVD application from a specific AVD Application Group
# in a specific Workspace for the current local user
#
# Thrown together by John Wilson and John Kelbley at Microsoft
#
# set the below variables to reach into Azure (as at least a Reader) to get AVD info
#
#
$ResourceGroup 	= "AVD"
$AppResourceGroup	= $ResourceGroup
$SubscriptionID	= "11111111-1111-1111-1111-11111111"
$WorkspaceName	= "Desktops"
$AppGroupName	= "Apps"
$UPN_Suffix		= "@gbbcore.com"
#
##############################################################################################################
#
# Get local userID
#
$Shell = New-Object -ComObject ("WScript.Shell")
$ShortCut = $Shell.CreateShortcut($env:USERPROFILE + "\downloads\Comet.url")
$userID = $env:USERNAME+$UPN_Suffix
$webfile = "C:\Users\" +  $env:USERNAME + "\downloads\myfile.html"
#
##############################################################################################################
#
#
# Connect to Azure and get AVD info
#
Login-AzAccount
Select-AzSubscription -SubscriptionId $SubscriptionID
$Workspace = Get-AzWvdWorkspace -name $WorkspaceName -ResourceGroupName $ResourceGroup
$AppGroup = Get-AzWvdApplicationGroup -name $appGroupName -ResourceGroupName $AppResourceGroup
$apps = Get-AzWvdApplication -ApplicationGroupName $AppGroup.name -ResourceGroupName $AppResourceGroup 
#
##############################################################################################################
#
# Write out HTML File Header
#
new-item $webfile -itemtype File -force
# Added some HTML Formating John Wilson
add-content $webfile "<!DOCTYPE html>`n<html>`n<body>`n`n<h1>AVD Applications & Desktops</h1>`n"
add-content $webfile "<style>"
add-content $webfile "a {color: white;}"
add-content $webfile "link {color: white;}"
add-content $webfile "<head>"
Add-content $webfile "body {background-color: powderblue;font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;}"
Add-content $webfile "body {font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;}"
#add-content $webfile "button {font-family: Arial, Helvetica;font-size: 16px;padding: 10px;background: white;color: white;display: inline;border: 0;text-decoration: none;line-height: 17px;}"
Add-Content $webfile "button {  display: inline-block;border-radius: 12px;background-color: blue;padding: 10px;width: 250px;color: #ffffff;text-align: center;  border: 4px double #cccccc;border-radius: 10px;font-size: 18px; }"
Add-Content $webfile "button span {cursor: pointer;display: inline-block;position: relative:transition:0.5s}"
Add-Content $webfile "button span:after {content: '\00bb';position: absolute;opacity: 0;top: 0;right: -20px;transition:0.5:}"
#Add-Content $webfile "button { display: inline-block;background-color: #7b38d8;padding: 20px;width: 200px;color: #ffffff;text-align: center;  border: 4px double #cccccc;border-radius: 10px;font-size: 28px; }"
Add-Content $webfile "h1   {color: blue;}"
add-content $webfile "</style>"
#
###############################################################################################################
#
# Write out Application Buttons
#
Foreach ($App in $Apps) {  
    $URL = -join("ms-avd:connect?workspaceId=", $Workspace.ObjectID, "&resourceid=", $app.ObjectID, "&username=", $UserID, "&version=0")
    $APPNAME = $app.name -split "/"
    $APPNAME = $APPNAME[1]
    add-content $webfile "<p>`n----------------------------------------------------------------------`n</p>"
    add-content $webfile "<p><button><a href=`"$URL`">$APPNAME</a>`n`n</button></p>"
}
add-content $webfile "`n`n</body>`n</html>"
#
###############################################################################################################
#
# open up new custom web page!
#
Invoke-item $webfile

Check out my next post on how to create an AVD web launcher from just information on the local PC (with icons!): AVD Web Launcher Using Only “Local Stuff” – Azure Advanced Migration Topics for Government (azurewebsites.us)

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top