Eric Monjoin
Staff Consulting Architect but also pilot, spending time in front of my computer or flying in the air...

Horizon Cloud from Zero to Hero – Set your Azure AD subscription ready for Horizon Cloud

In order to deploy Horizon Cloud on Azure, you first need to perform many task on Azure side like creating Virtual Network and so on. This can be done from the Azure portal or you can also use PowerShell to accomplish all tasks…

Before, let me tell you that all the merit for the following script must go to my colleague Roch Norwa and you can find the initial version on his blog here : https://digitalworkspace.blog/2020/04/19/horizon-cloud-on-azure-introduction-and-deployment-automation-script/

I made some slight changes to Roch scripts :

  • Added registration of Microsoft.SQL to the management subnet
  • Use only one Virtual Networ instead of 2
  • Use 3 of subnets instead of 2 : Management, VDI (and RDS host) and UAG
  • Changed Register-AzureRmResourceProvider for Register-AzResourceProvider
#SCRIPT CREATED TO REFLECT STEPS FROM THIS GUIDE: https://techzone.vmware.com/quick-start-tutorial-vmware-horizon-cloud-service-microsoft-azure
#FOR MANUAL STEPS REFERENCE USE SHANE FOWLER VIDEO: https://www.youtube.com/watch?v=qIWum9JtLHk&t=2019s
#IN SCRIPT WORKING DIRECTORY A FILE WILL BE CREATED NAMED .\AzureIDs-For-HZCloud.txt THAT CONTAINS NECESSARY IDS TO CONFIGURE AZURE CAPACITY IN HORIZON CLOUD
#STILL YOU NEED TO MANUALLY INCREASE QUOTA LIMITS FOR YOUR SUBSCRIPTION IN AZURE PORTAL - THERE IS NO PROGRAMATIC WAY TO DO IT
 
#SCRIPT REQUIRES INSTALLED AND IMPORTED MODULES AZ, AZUREAD- LOGIN TO EACH MODULE WITH YOUR ADMIN ACCOUNT
#IGNORE WARNING 
#TESTED ON POWERSHELL 5.1 ON WINDOWS 10 64bit 20H2

# Initial version by Rosh Norwa at https://digitalworkspace.blog/2020/04/19/horizon-cloud-on-azure-introduction-and-deployment-automation-script/
# Modified by Eric Monjoin :
# Added registration of Microsoft.SQL to Admin subnet
# Use only one VNet (initaly 2 with Pearing)
# Changed Register-AzureRmResourceProvider to Register-AzResourceProvider
# Deploy UAG, VDI and Admin on separate subnets
 
#Variables descriptions to be created. CHANGE indicated you need to adjust to your environment specifics. Rest can be left with current values.
#Sub1 - display name of your Azure Subcription CHANGE
#RG1 - display name of a Resource Group that will be created for Horizon Cloud resources
#Location1 - Azure region name where resources should be created CHANGE
#VNetName1 - display name of the network that will be used for all traffics
#VSubNetName1 name of the subnet /24 used for Horizon Management VM 
#VSubNetName2 subnet name /24 used for virtual desktop and RDS hosts
#VSubNetName3 subnet name /24 used for infrastructure UAG
#GWSubName1 subnet name /24 used for Point to Point VPN using Microsoft RRAS
# *Prefix CIDR network addresses for the above subnets CHANGE
#GWName1 Virtual Network Gateway name to be created
#DNS1 your first local AD DNS server address at the DC/LAB CHANGE
#DNS2 your second local AD DNS server address at the DC/LAB CHANGE
#GWIPName1 name of the public IP object in Azure 
#GWIPConfName1 - name of the gateway config
#ConnectionName - VPN Connection Name
#LNGName Local Network Gateway display name in Azure
#LNGPrefix1 and LNGPrefix2 - networks in your datacenter/lab
#LNGIP - your VPN Gateway public IP 
 
# Declare your variables

#Install required PowerShell MODULE

if ($PSVersionTable.PSEdition -eq 'Desktop' -and (Get-Module -Name AzureRM -ListAvailable)) {
    Write-Warning -Message ('Az module not installed. Having both the AzureRM and ' +
      'Az modules installed at the same time is not supported.')
} else {
    Install-Module -Name Az -AllowClobber -Scope AllUsers
	Install-Module -Name AzureAD -AllowClobber -Scope AllUsers
}
 
$Sub1           = "Visual Studio Enterprise"
$RG1            = "HCoA_RG_WestEurope"
$Location1      = "West Europe"
$VNetName1      = "HSoA-VNET-01"
$VSubNetName1   = "HSoA-Subnet-Adm"
$VSubNetName2   = "HSoA-Subnet-VDI"
$VSubNetName3   = "HSoA-Subnet-UAG"
$ServiceEndPoint1 = "Microsoft.Sql"
$GWSubName1     = "GatewaySubnet"
$VNet1Prefix    = "192.168.128.0/22"
$VSubNetAdmPrefix = "192.168.128.0/24"
$VSubNetVDIPrefix = "192.168.129.0/24"
$VSubNetUAGPrefix = "192.168.130.0/24"
$GWName1        = "HSoA-VNetGW-01"
$GWSubPrefix1   = "192.168.131.0/24"
$DNS1           = "192.168.0.10"
$DNS2           = "192.168.0.11"
$GWIPName1     = "HSoA-VNetGW-01-IP"
$GWIPconfName1 = "gwipconf1"
$ConnectionName  = "Site2Site-VPN"
$LNGName       = "Site2SiteVPN-LocalNetGateway"
$LNGPrefix1   = "192.168.35.0/24"
$LNGPrefix2   = "192.168.0.0/24"
$LNGIP         = "78.241.118.24"
 
# Connect to your subscription and create a new resource group

Connect-AzAccount
$azsubscription = Select-AzSubscription -SubscriptionName $Sub1
New-AzResourceGroup -Name $RG1 -Location $Location1
 
# Create virtual networks / spoke vnet for Horizon Service
 
$VSubNetADM1 = New-AzVirtualNetworkSubnetConfig -Name $VSubNetName1 -AddressPrefix $VSubNetAdmPrefix -ServiceEndpoint $ServiceEndPoint1
$VSubNetVDI1 = New-AzVirtualNetworkSubnetConfig -Name $VSubNetName2 -AddressPrefix $VSubNetVDIPrefix
$VSubNetUAG1 = New-AzVirtualNetworkSubnetConfig -Name $VSubNetName3 -AddressPrefix $VSubNetUAGPrefix
$GWSubNet1 = New-AzVirtualNetworkSubnetConfig -Name $GWSubName1 -AddressPrefix $GWSubPrefix1

$vnetHSoA = New-AzVirtualNetwork -Name $VNetName1 -ResourceGroupName $RG1 -Location $Location1 -AddressPrefix $VNet1Prefix -Subnet $VSubNetADM1,$VSubNetVDI1,$VSubNetUAG1,$GWSubNet1 -DnsServer $DNS1,$DNS2
 

# Create VPN gateway
 
$gwpip1    = New-AzPublicIpAddress -Name $GWIPName1 -ResourceGroupName $RG1 -Location $Location1 -AllocationMethod Dynamic
$vnet1     = Get-AzVirtualNetwork -Name $VNetName1 -ResourceGroupName $RG1
$subnet1   = Get-AzVirtualNetworkSubnetConfig -Name "$GWSubName1" -VirtualNetwork $vnet1
$gwipconf1 = New-AzVirtualNetworkGatewayIpConfig -Name $GWIPconfName1 -Subnet $subnet1 -PublicIpAddress $gwpip1
 
New-AzVirtualNetworkGateway -Name $GWName1 -ResourceGroupName $RG1 -Location $Location1 -IpConfigurations $gwipconf1 -GatewayType Vpn -VpnType RouteBased -GatewaySku VpnGw1
New-AzLocalNetworkGateway -Name $LNGName -ResourceGroupName $RG1 -Location $Location1 -GatewayIpAddress $LNGIP -AddressPrefix $LNGPrefix1

# Create the S2S VPN connection
 
$vnet1gw = Get-AzVirtualNetworkGateway -Name $GWName1  -ResourceGroupName $RG1
$lng5gw  = Get-AzLocalNetworkGateway -Name $LNGName -ResourceGroupName $RG1
 
New-AzVirtualNetworkGatewayConnection -Name $ConnectionName -ResourceGroupName $RG1 -VirtualNetworkGateway1 $vnet1gw -LocalNetworkGateway2 $lng5gw -Location $Location1 -ConnectionType IPsec -SharedKey 'VMware1!VMware1!' -EnableBGP $False

# Create App Registration in Azure AD
 
Connect-AzureAD

$appName = "HCoAzure"
$startDate = Get-Date
$endDate = (Get-Date).AddYears(10)
$HorizonServiceApp = New-AzureADApplication -DisplayName $appName
$KeyValue = New-AzureADApplicationPasswordCredential -ObjectId $HorizonServiceApp.ObjectId -CustomKeyIdentifier "HSoA-Key-1" -StartDate $startDate -EndDate $endDate
 
#Create text file with details for Horizon Cloud setup
 
$KeyValueDescription = "App Client Secret Key Value:" | Out-File -FilePath .\AzureIDs-For-HZCloud.txt -Append
$KeyValue.Value | Out-File -FilePath .\AzureIDs-For-HZCloud.txt -Append
$AppIDDescription = "Application (Client) ID:" | Out-File -FilePath .\AzureIDs-For-HZCloud.txt -Append
$HorizonServiceApp.AppId | Out-File -FilePath .\AzureIDs-For-HZCloud.txt -Append
$AppIDDescription = "Object ID:" | Out-File -FilePath .\AzureIDs-For-HZCloud.txt -Append
$HorizonServiceApp.ObjectId | Out-File -FilePath .\AzureIDs-For-HZCloud.txt -Append
$AzTenantValueDescription = "TenantID:" | Out-File -FilePath .\AzureIDs-For-HZCloud.txt -Append
Get-AzTenant| Out-File -FilePath .\AzureIDs-For-HZCloud.txt -Append
 
#add permissions for service principal of the application
 
Start-Sleep -Seconds 5
$azsubscription = Select-AzSubscription -SubscriptionName $Sub1
$subid = $azsubscription.Subscription.Id
New-AzADServicePrincipal -ApplicationId $HorizonServiceApp.AppId
$ServicePrincipalId = Get-AzureADServicePrincipal -All $true | Where-Object {$_.DisplayName -eq $appName}
Start-Sleep -Seconds 5
New-AzRoleAssignment -ObjectId $ServicePrincipalId.ObjectId -RoleDefinitionName Contributor -Scope "/subscriptions/$subid"
 
#Register necessary Resource  Providers
Register-AzResourceProvider -ProviderNamespace "Microsoft.Compute"
Register-AzResourceProvider -ProviderNamespace "Microsoft.insights"
Register-AzResourceProvider -ProviderNamespace "Microsoft.Network"
Register-AzResourceProvider -ProviderNamespace "Microsoft.Storage"
Register-AzResourceProvider -ProviderNamespace "Microsoft.KeyVault"
Register-AzResourceProvider -ProviderNamespace "Microsoft.Authorization"
Register-AzResourceProvider -ProviderNamespace "Microsoft.Resources"
Register-AzResourceProvider -ProviderNamespace "Microsoft.ResourceHealth"
Register-AzResourceProvider -ProviderNamespace "Microsoft.DBforPostgreSQL"
Register-AzResourceProvider -ProviderNamespace "Microsoft.sql"

You may also like...

Leave a Reply

Your email address will not be published.