0

I want to change the host pool load-balancing methods from Breadth-first to Depth-first at 19 PM ~ 11 AM every day to reduce the cost of VMs.

For example: Host pool load-balancing methods: Breath-first, 11:00 AM ~ 17:00 PM Host pool load-balancing methods: Depth-first, 17:00 PM ~ 11:00 AM

Is there someone who knows something about this? Reference: SET-Hostpool

Joy Wang
  • 39,905
  • 3
  • 30
  • 54
Arthur
  • 103
  • 11

1 Answers1

2

You could use the azure automation runbook to do that, follow the steps as below.

1.Navigate to the azure portal, create an automation account, then create a powershell runbook.

2.Navigate to the automation account -> Modules -> Browse Gallery -> search for the powershell module Microsoft.RDInfra.RDPowerShell and import it, after import, it appears like below.

enter image description here

3.When you create the automation account with the setting Create Azure Run As account as Yes, it will create an AD App along with a service principal in your Azure AD tenant, its name will be like automationaccountname_fc2Wgay6EkHrpgrpMSbF1V8uc6LVDkz9tgb8T6YUhaQ=. In azure runbook, you could not use the interactive way to login to Virtual Desktop, so the option is to use the service principal(Run as account) to login.

Before login, you need to create a role assignment so the service principal can sign in to Virtual Desktop, just follow this link.

Add-RdsAccount -DeploymentUrl "https://rdbroker.wvd.microsoft.com"
Get-RdsTenant

$myTenantName = "<Windows Virtual Desktop Tenant Name>"
New-RdsRoleAssignment -RoleDefinitionName "RDS Owner" -ApplicationId <service-principal-appid> -TenantName $myTenantName

To find the ApplicationId in script above, navigate to the Azure Active Directory in the portal -> App registrations -> All applications -> find the AD App of your Run as account -> get the ApplicationId like below.

enter image description here

4.Navigate to the powershell runbook created in step 1, use the script like below, it sets the host pool to use breadth-first load balancing.

$connectionName = "AzureRunAsConnection"
try
{
    # Get the connection "AzureRunAsConnection "
    $servicePrincipalConnection=Get-AutomationConnection -Name $connectionName         

    "Logging in to Windows Virtual Desktop..."
    Add-RdsAccount `
        -DeploymentUrl "https://rdbroker.wvd.microsoft.com" `
        -AadTenantId $servicePrincipalConnection.TenantId `
        -ApplicationId $servicePrincipalConnection.ApplicationId `
        -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint 
}
catch {
    if (!$servicePrincipalConnection)
    {
        $ErrorMessage = "Connection $connectionName not found."
        throw $ErrorMessage
    } else{
        Write-Error -Message $_.Exception
        throw $_.Exception
    }
}

Set-RdsHostPool -TenantName "<contoso>" -Name "<contosoHostPool>" -BreadthFirstLoadBalancer

Then save the runbook1, and create another runbook2, use the script below, it sets the host pool to use depth-first load balancing.

$connectionName = "AzureRunAsConnection"
try
{
    # Get the connection "AzureRunAsConnection "
    $servicePrincipalConnection=Get-AutomationConnection -Name $connectionName         

    "Logging in to Windows Virtual Desktop..."
    Add-RdsAccount `
        -DeploymentUrl "https://rdbroker.wvd.microsoft.com" `
        -AadTenantId $servicePrincipalConnection.TenantId `
        -ApplicationId $servicePrincipalConnection.ApplicationId `
        -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint 
}
catch {
    if (!$servicePrincipalConnection)
    {
        $ErrorMessage = "Connection $connectionName not found."
        throw $ErrorMessage
    } else{
        Write-Error -Message $_.Exception
        throw $_.Exception
    }
}

Set-RdsHostPool -TenantName "<contoso>" -Name "<contosoHostPool>" -DepthFirstLoadBalancer -MaxSessionLimit 10

5.Navigate to the Schedule in the runbook1, for more details about how to use it, see this doc. For example in your case, just set it like below. Then runbook1 will run at 11:00 AM every day. In runbook2, it is the same logic, then runbook2 will run at 17:00 PM every day. After configuring the schedules, strat the two runbooks.

enter image description here

Joy Wang
  • 39,905
  • 3
  • 30
  • 54
  • thanks so much for your comments. Can you please check my another post [link](https://stackoverflow.com/questions/59476551/how-to-give-an-announce-message-before-forcing-users-to-logoff-on-remote-desktop?noredirect=1#comment105158908_59476551) . It is similar to this one, may i use the Azure Automation runbook to sent the message to the users who is using the special vm session hosts? Thanks. – Arthur Jan 06 '20 at 02:25
  • @Arthur Glad it helps.:-) – Joy Wang Jan 06 '20 at 02:26
  • by the way, I run the scripts and found an error. Can you please explain it more clearly. I don't know what it means like: $connectionName ="AzureRunAsConnection" @Joy Wang – Arthur Jan 06 '20 at 04:56
  • @Arthur This is used to get your `RunAsConnection` which stored your Run As Account credentials. What's the error? – Joy Wang Jan 06 '20 at 05:13
  • And I found another way to achieve the goal, log in WVD with service principals as below: '$creds = New-Object System.Management.Automation.PSCredential("your service PrincipalID", (ConvertTo-SecureString "Your Service Pricipal Password" -AsPlainText -Force)) Add-RdsAccount -DeploymentUrl "https://rdbroker.wvd.microsoft.com" -Credential $creds -ServicePrincipal -AadTenantId "your AADTenantId" ' – Arthur Jan 06 '20 at 05:20
  • @Arthur Of course you can, this way uses your own service principal instead of the service principal created by the automation account, it is the same logic. Both will work. But I recommend you to use the Run As account. – Joy Wang Jan 06 '20 at 05:22
  • The error is 'Failed Cannot bind argument to parameter 'AadTenantId' because it is null.' – Arthur Jan 06 '20 at 05:23
  • can you tell me the reason that Run As account? For security or something esle? – Arthur Jan 06 '20 at 05:24
  • @Arthur I think it is more convenient to manage the service principal, e.g. renew the certificate, you just need to do that in the automation account page. If you use own service principal, you need to expose its password in the script, it is not safe. And if you store them manually in the Variables or Connections in the automation account, it is complicated. – Joy Wang Jan 06 '20 at 05:31
  • @Arthur For the error, did you choose `Create Azure Run As account` as `Yes` in step 3? – Joy Wang Jan 06 '20 at 05:32
  • yes, I choose **Create Azure Run as account** as **Yes**. I changed the content as below, is it right? { $servicePrincipalConnection=Get-AutomationConnection -Name $connectionName "Logging in to Windows Virtual Desktop..." Add-RdsAccount ` -DeploymentUrl "https://rdbroker.wvd.microsoft.com" -AADTenantId $servicePrincipalConnection."my aadID" -ApplicationId $servicePrincipalConnection."my service principal ID" -CertificateThumbprint $servicePrincipalConnection."my service principal password" – Arthur Jan 06 '20 at 05:46
  • @Arthur Could you find the values in this page https://i.stack.imgur.com/FN1gB.png ? – Joy Wang Jan 06 '20 at 05:51
  • so I have no need to change the content, right? I tested the runbook again and I found the error content changed. I will assign the RDS OwnerRole to the AzureRunAsConnection Application ID. Thanks. – Arthur Jan 06 '20 at 05:58
  • @Arthur Yes, you are right. In step 3, I mentioned that we need to assign a role to the service principal. – Joy Wang Jan 06 '20 at 06:01
  • I assigned the RDS Owner Role to AzureRunAsConnection Application ID and run again. There have an error of **Set-RdsHostPool : User is not authorized to query the management service.**. I tried another account to did that and the result was same, is there a time limit of Host pool load balancer method change. By the way, do you know the mean of **Make sure to sign in with an account that has permissions to create role assignments** at this [link](https://learn.microsoft.com/en-us/azure/virtual-desktop/create-service-principal-role-powershell). Thanks – Arthur Jan 06 '20 at 06:31
  • @Arthur Your user account also needs to be `RDS Owner` to assign the role. By default, just use the account used to [create the Windows Virtual Desktop tenant](https://learn.microsoft.com/en-us/azure/virtual-desktop/tenant-setup-azure-active-directory#create-a-windows-virtual-desktop-tenant). – Joy Wang Jan 06 '20 at 06:34