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
Add Git Bash (or other) to Windows Terminal

Add Git Bash (or other) to Windows Terminal

This is my quick, 1 minute, method to add ‘Git for Windows’ bashto Windows Terminal. But you can use the same process for any other command line.

  1. Either use the shortcut CTRL+, or the menu to open the settings.json
  1. This will open the settings.json file in you default editor.
  2. Now generate a new GUID by either
    1. go to https://www.guidgenerator.com/online-guid-generator.aspx or
    2. Enter [guid]::NewGuid() into the PowerShell terminal window
  1. Add the following json to the bottom of the “Profile”:”List” section
,
{
  "guid": "{REPLACE THE GUID HERE WITH YOUR ONE}",
  "hidden": false,
  "name": "Git bash",
  "icon": "C:\\Program Files\\Git\\mingw64\\share\\git\\git-for-windows.ico",
  "commandline": "C:\\Program Files\\Git\\bin\\bash.exe",
  "colorScheme": "One Half Dark",
  "startingDirectory": "%USERPROFILE%"
}
  1. Remember to replace the GUID with the one you created earlier.
  2. Save the file and you should now see the option in the drop down.

If you want this to be your default terminal, then just add the GUID to the “defaultProfile” setting in the json file and save.

I used a simple colour scheme to distinguish this terminal from the other. I also changed the PowerShell one by adding

"colorScheme": "Campbell Powershell"

to that profile to bring back the good ol’ blue background 😉

This is just the tip of the iceberg. You can customise Windows Terminal to your hearts delight.

For more details see the full Windows Terminal docs here https://docs.microsoft.com/en-gb/windows/terminal/

Power Off and On a Heatmiser neoStat v2…that actually works!

Power Off and On a Heatmiser neoStat v2…that actually works!

If, like me, you have been driving yourself crazy trying to follow the instructions in the Heatmiser neoStat V2 manual page 21 and wondering why you can Power the thing off (which is required for a number of actions)…then it’s because it’s wrong. After contacting support, I found the right way 🙂

Page 21 of the manual, with the wrong instructions!

Here’s how you do it

  1. Use the < > buttons to move to the Power Icon
  2. Press and hold the tick ? for approx. 3 seconds
  3. You will then see a new set of three options. ‘SETUP’, ‘CLOCK’ and Power Icon.
The Power Icon menu
  1. Now use the < > buttons to move to the Power button…again
  2. And now just wait. Do NOT press any buttons.
    After about 10 secs the light will go off…but continue to wait another 10 or so secs till the ‘SETUP’ and ‘CLOCK’ menu items disappear too.
  3. Congratulations…now it’s off and you can perform the configuration steps that now start from this position.

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 codifiable in DevOps CD pipelines.

Continue reading “Cloud Resource Naming Convention (Azure)”
How to get the Ratings from SharePoint into your PowerApp

How to get the Ratings from SharePoint into your PowerApp

The seems to be a disconnect between how ratings work in SharePoint, the actual data values in the underlying table and how to use them in a PowerApp.

I’ll explain what and how I got the ratings to show in my PowerApp.

Continue reading “How to get the Ratings from SharePoint into your PowerApp”

Keeping your managed PC from locking all the time

I know you shouldn’t try and subvert your companies internal security policies, but sometimes the security department just don’t seem to understand the consequences of what they do…especially when using multiple computers simultaneously!

The following script essentially presses the inaccessible F15 key at regular time intervals to ensure the screen timeout is reset and you avoid locking out.

Continue reading “Keeping your managed PC from locking all the time”