I'm not entirely sure how to use the Start-AzVM cmdlet with an AVD session host.
I first assign my resource group to a variable using Get-AzResourceGroup. Since the cmdlet returns a list, I use a foreach loop to get a list of the host pools within the resource group using Get-AzWvdHostPool and assign the returned value to another variable.
There is only one pool but, again, the cmdlet returns a list so another foreach list is used to iterate on it to get a list of the session hosts. This is done using Get-AzWvdSessionHost and assigning the results to another variable.
I'm specifically looking for sessions hosts that are listed as Unavailable. This is done with an if block to look at the Status of the currently iterated session host object. If it matches Start-AzVM is executed.
I've tried this using both the session host .Id and .Name attributes. With .Name, I've tried two ways. First, by using the full attribute: host-pool/host-name, then by splitting it on the / and only using host-name portion. Regardless, whether I use the .Id attribute or .Name attribute (in any fashion), I get the same error although slightly different in each case.
Start-AzVM: C:\Users\SnyderM\Development\AVD\scripts\AVD\avd-host-status.ps1:39:17
Line |
39 | … Start-AzVM -Name $hostName -ResourceGroupName $resourceGr …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| The Resource 'Microsoft.Compute/virtualMachines/bcst970407.place' under resource group 'Resource-Group' was not found. For more details please go to
| https://aka.ms/ARMResourceNotFoundFix ErrorCode: ResourceNotFound ErrorMessage: The Resource 'Microsoft.Compute/virtualMachines/bcst970407.place' under resource group
| 'Resource-Group' was not found. For more details please go to https://aka.ms/ARMResourceNotFoundFix ErrorTarget: StatusCode: 404 ReasonPhrase: Not Found OperationID :
| b05fd38c-97c2-449a-964e-a9ee5adf9794
The difference is that when I use the full .Name attribute, instead of the hostname at the end of 'Microsoft.Compute/virtualMachines/bcst970407.place', the resource group is listed instead: 'Microsoft.Compute/virtualMachines/Resource-Group'. What I get from this is that splitting it on the /` is the right approach. But again, I'm not sure.
Script:
try {
Get-InstalledModule -Name Az
}
catch {
Write-Host "This script requires the Az module. Install it then re-run the script."
}
$resourceGroups = Get-AzResourceGroup | Where-Object { ($_.ResourceGroupName -like "Resource-Group") }
foreach ($resourceGroup in $resourceGroups.ResourceGroupName) {
#Write-Host $resourceGroup
$hostPoolObjects = Get-AzWvdHostPool -ResourceGroupName $resourceGroup
foreach ($pool in $hostPoolObjects.Name) {
#Write-Host " : $pool"
foreach ($sessionHost in (Get-AzWvdSessionHost -HostPoolName $pool -ResourceGroupName $resourceGroup)) {
$sessionName = $sessionHost.Name
$hostpool,$hostName = $sessionName.split('/')
$hostStatus = $sessionHost.Status
$hostId = $sessionHost.Id
#Write-Host " : $hostName"
if ($sessionHost.Status -eq "Unavailable") {
Start-AzVM -Name $hostName -ResourceGroupName $resourceGroup
#Start-AzVM -Id $hostId
}
}
}
}
UPDATE
@venkat shed some light on where I was misremembering which column I needed to look at when determining if a session host needed to be started. By clearing that up, I need to adjust what to look for to determine if a host needs to be started.
It's true that the Health State column will display if a host is shutdown. What I'm seeing, though, is that they are all listed as Unavailable with a Power State of Deallocated. Upon further thought, I can't reliably search for hosts that need to be started based on being Unavailable because that can be the Health State even for hosts that are running.
UPDATE 2
After further conversation via comments with Venkat V, I'm closer to a solution.
For the moment, I know the specific resource group I'm working with, so I specify it in the script. I also removed the foreach loop that iterates over the $hostPoolObjects variable because I know that each resource group will only ever have one host pool. The variable name has been changed accordingly.
I've been able to reduce the code to just one foreach loop that iterates the session hosts. In the loop, the ResourceId is grabbed and passed to the Split-Path cmdlet to isolate the name of the VM backing the session host. This is then passed to the Get-AzVM cmdlet to get the power state.
I now need to figure out how to isolate the Statuses[1] segment of the Get-AzVM cmdlet because that is where the power state is. I can probably just use Select-String, but I'm curious if there is another way. Whatever I do, once I have the power state, it will be evaluated and if it is "Deallocated", the Start-AzVM cmdlet will be executed.
Incomplete script:
$resourceGroup = Get-AzResourceGroup | Where-Object { ($_.ResourceGroupName -like "ESOC-AVD-GREEN") }
$hostPool = Get-AzWvdHostPool -ResourceGroupName $resourceGroup.ResourceGroupName
$sessionHosts = Get-AzWvdSessionHost -HostPoolName $hostPool.Name -ResourceGroupName $resourceGroup.ResourceGroupName
foreach ($sessionHost in $sessionHosts) {
$vm = Split-Path -Path $sessionHost.ResourceId -Leaf
Get-AzVM -Name $vm -ResourceGroupName $resourceGroup.ResourceGroupName -Status
}

