Category: Azure

Reboot all the VM’s in a Windows Virtual Desktop Host Pool…safely ;-)

I have found that the session hosts often end up reporting a status of ‘Needs Assistance’. This can be caused by updates having been applied that require a reboot to complete…and other unknown issues. Often a reboot will sort them out. So I developed a simple script to assist.

The following script will allow you to specifiy the only the VM’s in a Host Pool and only those that ‘Need Assistance’ and that have no active sessions on too….or not!

Save the full script to a file called RebootHosts.ps1

<#PSScriptInfo
.VERSION 1.0
.GUID b053571a-b9f4-445d-ac05-45e184cf6f90
.AUTHOR Nicholas Rogoff
.RELEASENOTES

#>
<#
.SYNOPSIS
  Reboots VMs in a HostPool
.DESCRIPTION
  This will iterate through the VMs registered to a host pool and reboot them. 
.NOTES
  Version:        1.0
  Author:         Nicholas Rogoff
  Creation Date:  2020-09-03
  Purpose/Change: Initial script development

.EXAMPLE
  .\RebootHosts.ps1 -HostPoolName "my-host-pool" -HostPoolResourceGroupName "my-host-pool-rg" -OnlyDoIfNeedsAssistance -SkipIfActiveSessions
#>

#---------------------------------------------------------[Script Parameters]------------------------------------------------------
[CmdletBinding()]
Param (
    #Script parameters go here
    [Parameter(mandatory = $true)]
    [string]$HostPoolName,

    [Parameter(mandatory = $true)]
    [string]$HostPoolResourceGroupName,
    
    [Parameter(mandatory = $false)]
    [switch]$SkipIfActiveSessions,

    [Parameter(mandatory = $false)]
    [switch]$OnlyDoIfNeedsAssistance
)

#---------------------------------------------------------[Initialisations]--------------------------------------------------------

#Set Error Action to Silently Continue
$ErrorActionPreference = 'SilentlyContinue'

#----------------------------------------------------------[Declarations]----------------------------------------------------------

#Any Global Declarations go here

#-----------------------------------------------------------[Functions]------------------------------------------------------------


#-----------------------------------------------------------[Execution]------------------------------------------------------------

Write-Output "Starting to Enable Boot Diagnostics for VMs in Host Pool $HostPoolName ..."
if ($OnlyDoIfNeedsAttention) {
    Write-Output "!! Only hosts flagged as 'Needs Assistance' will be rebooted !!"
}
if ($SkipIfActiveSessions) {
    Write-Output "!! Only hosts with zero sessions will be rebooted !!"
}

$rebooted = 0
$skippedSessions = 0
$skippedOK = 0
$shutdown = 0

$sessionHosts = Get-AzWvdSessionHost -ResourceGroupName $HostPoolResourceGroupName -HostPoolName $HostPoolName
foreach ($sh in $sessionHosts) {
    

    # Name is in the format 'host-pool-name/vmname.domainfqdn' so need to split the last part
    $VMName = $sh.Name.Split("/")[1]
    $VMName = $VMName.Split(".")[0]
    
    $Session = $sh.Session
    $Status = $sh.Status
    $UpdateState = $sh.UpdateState
    $UpdateErrorMessage = $sh.UpdateErrorMessage

    Write-output "=== Starting Reboot for VM: $VMName"
    Write-output "Session: $Session"
    Write-output "Status: $Status"
    Write-output "UpdateState: $UpdateState"
    Write-output "UpdateErrorMessage: $UpdateErrorMessage"

    if ($Status -ne "Unavailable") {
        if ($Status -ne "NeedsAssistance" -and $OnlyDoIfNeedsAssistance ) {
            $skippedOK += 1
            Write-output "!! The VM '$VMName' is not in 'Needs Assistance' state, so will NOT be rebooted. !!"       
        }
        elseif ($SkipIfActiveSessions -and $Session -gt 0) {
            $skippeSessions += 1
            Write-output "!! The VM '$VMName' has $Session session(s), so will NOT be rebooted. !!"       
        }
        else {
            $rebooted += 1
            Restart-AzVM -ResourceGroupName $HostPoolResourceGroupName -Name $VMName
            Write-output "=== Reboot initiated for VM: $VMName"       
        }
    }
    else {
        $shutdown += 1
        Write-output "!! The VM '$VMName' must be started in order to reboot it. !!"       
    }

}

Write-Output ""
Write-Output "============== Completed =========================="
Write-Output "Skipped due Not needing attention: $skippedOK"
Write-Output "Skipped due to active sessions: $skippedSessions"
Write-Output "Host not started: $shutdown"
Write-Output "Rebooted: $rebooted"
Write-Output "==================================================="

You will need to log in to Azure and select your subscription in the normal way using:

Login-AzAccount
Select-AzSubscription "my-subscription"

You can then simply run the script as follows:

.\RebootHosts.ps1 -HostPoolName "my-host-pool" -HostPoolResourceGroupName "my-host-pool-rg" -OnlyDoIfNeedsAssistance -SkipIfActiveSessions

Cloud Resource Naming Convention (Azure)

In any organisation it is important to get a standard naming convention in place for most things, but especially with cloud based resources.

As many types of cloud resources require globally unique names (due to platform DNS resolution), it’s important to have a strategy that will give you a good chance of achieving global uniqueness, but also as helpful as possible to human beings, as well as codefiable in DevOps CD pipelines.

Continue reading “Cloud Resource Naming Convention (Azure)”
‘*** Execution Timeout Expired’ with SqlPackage.exe on Azure DevOps Release Pipeline Fix

‘*** Execution Timeout Expired’ with SqlPackage.exe on Azure DevOps Release Pipeline Fix

A while ago I was having an issue deploying a SQL Data Tools project using the Azure DevOps pipelines. It worked fine when there was no data in the database, but once there was some data to preserve in the release the DACPAC deployment started to timeout with the following error when running SqlPackage.

Continue reading “‘*** Execution Timeout Expired’ with SqlPackage.exe on Azure DevOps Release Pipeline Fix”

Resource Tag management in Microsoft Azure

Adding tags to resources in Azure is generally a good idea. This helps administrators manage billing, knowing what things are and when they can be safely decommissioned etc..

I have includes here some guidance and useful scripts for adding tags and managing tags on resources and resource groups.

Continue reading “Resource Tag management in Microsoft Azure”

How to get Azure Data Factory connecting to your data on a VNet (or internal network)

Azure Data Factory (ADF) is a great tool as part of your cloud based ETL tool set. However not all your data is necessarily accessible from the public internet. These instruction go through the steps required to allow ADF access to your internal or VNet data-sets.

Continue reading “How to get Azure Data Factory connecting to your data on a VNet (or internal network)”