{"id":2048,"date":"2021-05-08T15:33:02","date_gmt":"2021-05-08T20:33:02","guid":{"rendered":"https:\/\/www.ciraltos.com\/?p=2048"},"modified":"2023-03-23T06:26:05","modified_gmt":"2023-03-23T11:26:05","slug":"shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool","status":"publish","type":"post","link":"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/","title":{"rendered":"Shut Down Unused Session Hosts in a Windows Virtual Desktop Pooled or Personal Host Pool"},"content":{"rendered":"\n<figure class=\"wp-block-image alignleft size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"101\" height=\"182\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2020\/06\/WVDFunctionApp.png\" alt=\"WVD Function App\" class=\"wp-image-1745\"\/><\/figure>\n\n\n\n<p>(UPDATED 6\/17\/2021 with code for multiple pooled and personal host pools) Azure Virtual Desktop (previously Windows Virtual Desktop (WVD)) has a new option in preview that starts session hosts in a personal or pooled host pool when a user connects. It won\u2019t, however, shut down the session hosts when the user logs out. The script outlined in this video will evaluate all running and available session hosts in a personal or pooled host pool and shut down and deallocate session hosts without an active connection. &nbsp;Deallocating Session hosts while not in use can save money on compute costs. <\/p>\n\n\n\n<!--more-->\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<div class=\"ast-oembed-container\" style=\"height: 100%;\"><iframe loading=\"lazy\" title=\"Shut Down Unused Session Hosts in an Azure Virtual Desktop (WVD, AVD) Personal and Pooled Host Pool\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/0PWO3OaZmeQ?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen><\/iframe><\/div>\n<\/div><\/figure>\n\n\n\n<p>This script is intended to be used with the auto start on connect preview feature.&nbsp; It uses an Azure Function with a system assigned managed identity to query AVD\/WVD and shut down the Session Hosts.&nbsp; It uses an Azure Function because support for a managed identity is GA, and the schedule can run more frequently than every hour.&nbsp; The script could also run in an Azure Automation runbook.<\/p>\n\n\n\n<p>Auto Start WVD Pooled and Personal Host Pool Session Hosts:<br><a href=\"https:\/\/github.com\/tsrob50\/WVD-Public\/blob\/master\/StopSH-MultiHostPools.ps1\">https:\/\/github.com\/tsrob50\/WVD-Public\/blob\/master\/StopSH-MultiHostPools.ps1 <\/a><\/p>\n\n\n\n<p>One important step required for this script is a GPO, or\nsome other method to set a time limit on disconnected sessions in the Host Pool.&nbsp; The script will not shut down Session Hosts\nwith any type of active session, including disconnected sessions.&nbsp; <\/p>\n\n\n\n<p>Also, I recommend not running the script more frequently than every 30 minutes.&nbsp; There is a short window when a user connects, and the Session Host has started, but the login has not fully processed.&nbsp; The script could interpret the Session Host as powered on with no active connects and shut it down.&nbsp; <\/p>\n\n\n\n<h1>Disconnect GPO<\/h1>\n\n\n\n<p>Start by creating a GPO that sets a time limit for\ndisconnected sessions and apply it to the Session Host OU.&nbsp; The settings are located in:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Computer Configuration &gt; Administrative Templets &gt;\nWindows Components &gt; Remote Desktop Services &gt; Remote Desktop Session\nHost &gt; Session Time limits<\/pre>\n\n\n\n<p>At minimum, enable \u201cSet time limit for disconnected sessions\u201d\nto a time limit that works for your organization.&nbsp; Set it too high, and charges will accumulate\nfor resources not in use, set it too low and end users may get frustrated when\nthey step away for a short time and have to wait for their Session Host to start.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"791\" height=\"184\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/GPO-Settings.png\" alt=\"\" class=\"wp-image-2049\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/GPO-Settings.png 791w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/GPO-Settings-300x70.png 300w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/GPO-Settings-768x179.png 768w\" sizes=\"(max-width: 791px) 100vw, 791px\" \/><figcaption class=\"wp-element-caption\"> GPO Settings <\/figcaption><\/figure>\n\n\n\n<p>Also, consider enabling \u201cSet time limit for active but idle Remote Desktop Services session\u201d.&nbsp; Configuring that setting will disconnect a user who may have stepped away and left the remote desktop client open.&nbsp; <\/p>\n\n\n\n<h2>Set the Max Session Limit<\/h2>\n\n\n\n<p>Auto  Start on Connect will only power on a Session Host in a Pooled Host Pool if no Session Host are powered on or, if the powered on Session Hosts have reached the Max Session Limit. A Pooled Host Pool in Breadth-First Load Balancing requires a max session limit when used with the start on connect feature.<\/p>\n\n\n\n<h1>Create Function App<\/h1>\n\n\n\n<p>Let\u2019s start by creating the function app.&nbsp; From the Azure Portal, go to Function Apps\nand add a new function app.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"286\" height=\"282\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Create-a-new-Function-App.png\" alt=\"\" class=\"wp-image-2051\"\/><figcaption class=\"wp-element-caption\"> Create a new Function App <\/figcaption><\/figure>\n\n\n\n<p>In the <em>Create Function App<\/em> page, create a new or use\nan existing resource group and give the Function app a name.&nbsp; Set the runtime stack to PowerShell core and\nset your region.&nbsp; Once finished, it\nshould look similar to the image below.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"935\" height=\"847\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Create-Function-App-Settings-1.png\" alt=\"\" class=\"wp-image-2052\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Create-Function-App-Settings-1.png 935w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Create-Function-App-Settings-1-300x272.png 300w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Create-Function-App-Settings-1-768x696.png 768w\" sizes=\"(max-width: 935px) 100vw, 935px\" \/><figcaption class=\"wp-element-caption\"> Create Function App Settings <\/figcaption><\/figure>\n\n\n\n<p>Hosting, Monitoring, and tags can be left as default.&nbsp; Go to <em>Review and Create<\/em> to deploy the\nFunction App.<\/p>\n\n\n\n<p>Go to the resource when finished.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"575\" height=\"508\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Go-To-Resource.png\" alt=\"\" class=\"wp-image-2053\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Go-To-Resource.png 575w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Go-To-Resource-300x265.png 300w\" sizes=\"(max-width: 575px) 100vw, 575px\" \/><figcaption class=\"wp-element-caption\"> Go to Resource <\/figcaption><\/figure>\n\n\n\n<h1>Configure the Function App<\/h1>\n\n\n\n<p>Next, we will configure the function app to use the PowerShell\nAz. Module and configure a System Assigned Managed Identity.<\/p>\n\n\n\n<h2>Configure Az Module<\/h2>\n\n\n\n<p>From the Function App, go to <em>App files<\/em> under <em>Functions<\/em>.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"246\" height=\"208\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/App-Files.png\" alt=\"\" class=\"wp-image-2054\"\/><figcaption class=\"wp-element-caption\"> App Files <\/figcaption><\/figure>\n\n\n\n<p>From the dropdown, select the <em>requirements.psd1<\/em> file and remove the \u201c#\u201d from the line: \u2018Az\u2019 = \u20185.*\u2019.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"963\" height=\"368\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Requirements.psd1_.png\" alt=\"\" class=\"wp-image-2057\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Requirements.psd1_.png 963w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Requirements.psd1_-300x115.png 300w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Requirements.psd1_-768x293.png 768w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Requirements.psd1_-960x368.png 960w\" sizes=\"(max-width: 963px) 100vw, 963px\" \/><figcaption class=\"wp-element-caption\"> Requirements.psd1<\/figcaption><\/figure>\n\n\n\n<p>Click Save and go back to the Function App Overview.<\/p>\n\n\n\n<p>From the overview page, restart the function app.&nbsp; This will apply configuration changes we just\nmade.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"622\" height=\"227\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Restart-Function-App.png\" alt=\"\" class=\"wp-image-2058\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Restart-Function-App.png 622w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Restart-Function-App-300x109.png 300w\" sizes=\"(max-width: 622px) 100vw, 622px\" \/><figcaption class=\"wp-element-caption\"> Restart Function App <\/figcaption><\/figure>\n\n\n\n<h2>Configure the Managed Identity<\/h2>\n\n\n\n<p>Next, we\u2019ll configure the managed identity used by the Function\nApp to interact with resources in the subscription.<\/p>\n\n\n\n<p>Go to Identity under Settings in the Function App.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"305\" height=\"306\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Settings-Identity.png\" alt=\"\" class=\"wp-image-2059\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Settings-Identity.png 305w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Settings-Identity-300x300.png 300w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Settings-Identity-150x150.png 150w\" sizes=\"(max-width: 305px) 100vw, 305px\" \/><figcaption class=\"wp-element-caption\"> Settings Identity <\/figcaption><\/figure>\n\n\n\n<p>From the <em>System Assigned Identity<\/em> page, change the\nstatus to On and save, that will create a new identity, and the Object ID will\ndisplay similar to below, without the blur.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"598\" height=\"488\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/System-Assigned-Identity.png\" alt=\"\" class=\"wp-image-2060\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/System-Assigned-Identity.png 598w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/System-Assigned-Identity-300x245.png 300w\" sizes=\"(max-width: 598px) 100vw, 598px\" \/><figcaption class=\"wp-element-caption\"> System Assigned Identity <\/figcaption><\/figure>\n\n\n\n<p>Next, we give the identity rights to view properties of the\nWVD environment and manage virtual machines in the subscription.&nbsp; Go to <em>Add Role Assignments.<\/em><\/p>\n\n\n\n<p>From the <em>Add Role Assignments <\/em>page, click <em>Add Role Assignment (preview)<\/em>.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"542\" height=\"444\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Add-Role-Assignments.png\" alt=\"\" class=\"wp-image-2061\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Add-Role-Assignments.png 542w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Add-Role-Assignments-300x246.png 300w\" sizes=\"(max-width: 542px) 100vw, 542px\" \/><figcaption class=\"wp-element-caption\"> Add Role Assignments <\/figcaption><\/figure>\n\n\n\n<p>On the next page, set the <em>Scope<\/em> to <em>Subscription<\/em>,\nVerify the correct subscription is added, and search for and select <em>Desktop\nVirtualization Reader.<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"756\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Add-Roles-1024x756.png\" alt=\"\" class=\"wp-image-2062\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Add-Roles-1024x756.png 1024w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Add-Roles-300x221.png 300w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Add-Roles-768x567.png 768w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Add-Roles.png 1038w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\"> Add Roles <\/figcaption><\/figure>\n\n\n\n<p>Click <em>Save<\/em> to add the Desktop Virtualization Reader\nrole.&nbsp; <\/p>\n\n\n\n<p>Follow the same steps to add the <em>Virtual Machine Contributor<\/em> role.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"375\" height=\"233\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Virtual-Machine-Contributor.png\" alt=\"\" class=\"wp-image-2064\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Virtual-Machine-Contributor.png 375w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Virtual-Machine-Contributor-300x186.png 300w\" sizes=\"(max-width: 375px) 100vw, 375px\" \/><figcaption class=\"wp-element-caption\"> Virtual Machine Contributor <\/figcaption><\/figure>\n\n\n\n<p>Once finished, go back to the Function App.<\/p>\n\n\n\n<h1>Create the Function<\/h1>\n\n\n\n<p>Next, we\u2019ll create the Function.&nbsp; A Function App can have many functions of the\nsame type.&nbsp; For example, we can have multiple\nPowerShell Functions in this Function App.&nbsp;\n<\/p>\n\n\n\n<p>From the Azure Function App, go to <em>Functions<\/em> under <em>Functions<\/em>.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"201\" height=\"210\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Functions.png\" alt=\"\" class=\"wp-image-2065\"\/><figcaption class=\"wp-element-caption\"> Functions <\/figcaption><\/figure>\n\n\n\n<p>Click <em>Add<\/em> to add a Function.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"190\" height=\"253\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Add-a-Function.png\" alt=\"\" class=\"wp-image-2066\"\/><figcaption class=\"wp-element-caption\"> Add a Function <\/figcaption><\/figure>\n\n\n\n<p>From the list of templates, select <em>Timer Trigger. <\/em>&nbsp;&nbsp;This will trigger the Function based on a\nschedule.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"645\" height=\"299\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Timer-Trigger.png\" alt=\"\" class=\"wp-image-2067\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Timer-Trigger.png 645w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Timer-Trigger-300x139.png 300w\" sizes=\"(max-width: 645px) 100vw, 645px\" \/><figcaption class=\"wp-element-caption\"> Timer Trigger <\/figcaption><\/figure>\n\n\n\n<p>Go to Template Details, give it a new name if needed, then\nchange the schedule by replacing the 5 with a 30.&nbsp; This will set the timer to run every 30 minutes\non the hour. &nbsp;You can change this to a different\nfrequency, 45 to run every 45 minutes for example. <\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"629\" height=\"298\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Function-App-Schedule.png\" alt=\"\" class=\"wp-image-2068\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Function-App-Schedule.png 629w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Function-App-Schedule-300x142.png 300w\" sizes=\"(max-width: 629px) 100vw, 629px\" \/><figcaption class=\"wp-element-caption\"> Function App Schedule <\/figcaption><\/figure>\n\n\n\n<p>See the link below for more details on scheduling for a Function App.<br><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/azure-functions\/functions-bindings-timer?tabs=csharp&amp;WT.mc_id=AZ-MVP-5004159#ncrontab-expressions\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"https:\/\/docs.microsoft.com\/en-us\/azure\/azure-functions\/functions-bindings-timer?tabs=csharp&amp;WT.mc_id=AZ-MVP-5004159#ncrontab-expressions (opens in a new tab)\">https:\/\/docs.microsoft.com\/en-us\/azure\/azure-functions\/functions-bindings-timer?tabs=csharp&amp;WT.mc_id=AZ-MVP-5004159#ncrontab-expressions<\/a><\/p>\n\n\n\n<p>Click <em>Add<\/em> to add the function app.<\/p>\n\n\n\n<p>From within the Function, go to Code + Test under Developer.\n<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"244\" height=\"228\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Code-Test.png\" alt=\"\" class=\"wp-image-2069\"\/><figcaption class=\"wp-element-caption\"> Code + Test <\/figcaption><\/figure>\n\n\n\n<p>If you need to change the schedule, go to the <em>Function.json\n<\/em>file in the Function drop-down.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"267\" height=\"145\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Function-json.png\" alt=\"\" class=\"wp-image-2070\"\/><figcaption class=\"wp-element-caption\"> Function json <\/figcaption><\/figure>\n\n\n\n<p>Change the schedule as needed.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"420\" height=\"266\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Change-the-Schedule.png\" alt=\"\" class=\"wp-image-2071\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Change-the-Schedule.png 420w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Change-the-Schedule-300x190.png 300w\" sizes=\"(max-width: 420px) 100vw, 420px\" \/><\/figure>\n\n\n\n<p>Go back to the <em>Run.ps1<\/em> file and replace the existing code with the <strong>StopSH-MultiHostPools.ps1<\/strong> code. The code can be found here:<br><a rel=\"noreferrer noopener\" aria-label=\"https:\/\/github.com\/tsrob50\/WVD-Public\/blob\/master\/StopSH-MultiHostPools.ps1  (opens in a new tab)\" href=\"https:\/\/github.com\/tsrob50\/WVD-Public\/blob\/master\/StopSH-MultiHostPools.ps1\" target=\"_blank\">https:\/\/github.com\/tsrob50\/WVD-Public\/blob\/master\/StopSH-MultiHostPools.ps1 <\/a><\/p>\n\n\n\n<p>Go to the Variables section.&nbsp; Update the Host Pool name and Resource Group for the Personal or Pooled Host Pool.&nbsp; <\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"499\" height=\"225\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/06\/Variables1.png\" alt=\"\" class=\"wp-image-2115\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/06\/Variables1.png 499w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/06\/Variables1-300x135.png 300w\" sizes=\"(max-width: 499px) 100vw, 499px\" \/><\/figure>\n\n\n\n<p>If the function is running againt multple Pooled or Personal Host Pools, copy the block of code from the commends and paste it imediatly after the block updated in the previous step.  <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"473\" height=\"138\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/06\/Host-Pool-Code-Block.png\" alt=\"\" class=\"wp-image-2116\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/06\/Host-Pool-Code-Block.png 473w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/06\/Host-Pool-Code-Block-300x88.png 300w\" sizes=\"(max-width: 473px) 100vw, 473px\" \/><figcaption class=\"wp-element-caption\">Host Pool Code Block<\/figcaption><\/figure>\n\n\n\n<p>Add a new block of code for each host pool targeted by the function.  When finished, the variable section will look similar to the code below.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"392\" height=\"292\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/06\/Two-Host-Pools-Variables.png\" alt=\"\" class=\"wp-image-2117\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/06\/Two-Host-Pools-Variables.png 392w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/06\/Two-Host-Pools-Variables-300x223.png 300w\" sizes=\"(max-width: 392px) 100vw, 392px\" \/><figcaption class=\"wp-element-caption\">Two Host Pools<\/figcaption><\/figure>\n\n\n\n<p>When the Function runs, a while loop is used for each host pool.  It starts by getting all the active sessions in the Host Pool.&nbsp; It then creates a list of all active Session Host names, using a for each loop to remove duplicate values<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"926\" height=\"374\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/06\/Get-Active-Session-Hosts.png\" alt=\"\" class=\"wp-image-2118\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/06\/Get-Active-Session-Hosts.png 926w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/06\/Get-Active-Session-Hosts-300x121.png 300w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/06\/Get-Active-Session-Hosts-768x310.png 768w\" sizes=\"(max-width: 926px) 100vw, 926px\" \/><figcaption class=\"wp-element-caption\">Get Active Session Hosts<\/figcaption><\/figure>\n\n\n\n<p>Next, it creates a list of all Session Hosts that are\npowered on and not in drain mode.&nbsp;\nSetting drain mode will exclude the Session Host from the script. This\nway, if a Session Host has to be on for a few hours for maintenance, such as to\npick up software updates, the script won\u2019t shut it down.<\/p>\n\n\n\n<p>It then compares the Session Hosts that are powered on with\nthe Session Hosts that have active connections.&nbsp;\nIf the Session Host is on but has no active connections, it\u2019s shut down.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"855\" height=\"550\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/06\/Shut-Down-Session-Hosts-with-no-Sessions.png\" alt=\"\" class=\"wp-image-2119\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/06\/Shut-Down-Session-Hosts-with-no-Sessions.png 855w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/06\/Shut-Down-Session-Hosts-with-no-Sessions-300x193.png 300w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/06\/Shut-Down-Session-Hosts-with-no-Sessions-768x494.png 768w\" sizes=\"(max-width: 855px) 100vw, 855px\" \/><figcaption class=\"wp-element-caption\"> Shut Down Session Hosts with no Sessions <\/figcaption><\/figure>\n\n\n\n<p>After that, the script loops through the next instance of a Host Pool until the end.<\/p>\n\n\n\n<p>Once updated with your Host Pool and Resource Group information,\nsave the Function.<\/p>\n\n\n\n<h1>Run the Script<\/h1>\n\n\n\n<p>Test it before you trust it!<\/p>\n\n\n\n<p>My lab had three Session Hosts. All were powered on and\navailable with two users logged in.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"704\" height=\"195\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Test-Pool-Before-Script-Run.png\" alt=\"\" class=\"wp-image-2075\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Test-Pool-Before-Script-Run.png 704w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Test-Pool-Before-Script-Run-300x83.png 300w\" sizes=\"(max-width: 704px) 100vw, 704px\" \/><figcaption class=\"wp-element-caption\"> Test Pool Before Script Run <\/figcaption><\/figure>\n\n\n\n<p>Open logs in the Function so we can see the activity.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"635\" height=\"204\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Open-Logs.png\" alt=\"\" class=\"wp-image-2076\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Open-Logs.png 635w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Open-Logs-300x96.png 300w\" sizes=\"(max-width: 635px) 100vw, 635px\" \/><figcaption class=\"wp-element-caption\"> Open Logs <\/figcaption><\/figure>\n\n\n\n<p>Check the time!&nbsp; As\nconfigured in this example, the script will run every 30 minutes on the hour.&nbsp; Close to run time, you can wait for it to run\non its own.&nbsp; <\/p>\n\n\n\n<p>Otherwise, go to <em>Run\/Test<\/em> and click <em>Run<\/em> to\nstart it manually.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"355\" height=\"68\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Test-Run.png\" alt=\"\" class=\"wp-image-2077\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Test-Run.png 355w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Test-Run-300x57.png 300w\" sizes=\"(max-width: 355px) 100vw, 355px\" \/><figcaption class=\"wp-element-caption\"> Test Run <\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"473\" height=\"745\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Run-the-Function-Manually.png\" alt=\"\" class=\"wp-image-2078\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Run-the-Function-Manually.png 473w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Run-the-Function-Manually-190x300.png 190w\" sizes=\"(max-width: 473px) 100vw, 473px\" \/><figcaption class=\"wp-element-caption\"> Run the Function Manually <\/figcaption><\/figure>\n\n\n\n<p>Close the <em>Run<\/em> window after it starts.<\/p>\n\n\n\n<p>The Function will take a couple of extra minutes to finish\non the first run as it has to download and add the PowerShell Az module.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"134\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Download-PowerShell-Az-Module-1024x134.png\" alt=\"\" class=\"wp-image-2079\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Download-PowerShell-Az-Module-1024x134.png 1024w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Download-PowerShell-Az-Module-300x39.png 300w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Download-PowerShell-Az-Module-768x100.png 768w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Download-PowerShell-Az-Module.png 1484w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\"> Download PowerShell Az Module <\/figcaption><\/figure>\n\n\n\n<p>Once it finishes running, the output will indicate any\nSession Hosts that are shut down in the function output.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"328\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Function-Output-1024x328.png\" alt=\"\" class=\"wp-image-2080\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Function-Output-1024x328.png 1024w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Function-Output-300x96.png 300w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Function-Output-768x246.png 768w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Function-Output.png 1247w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\"> Function Output <\/figcaption><\/figure>\n\n\n\n<p>My example now shows one Session Host is off and unavailable.&nbsp; With <em>Start VM on Connect<\/em> enabled, the Session\nHost will start the next time an assigned user logs in. <\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"689\" height=\"204\" src=\"https:\/\/www.ciraltos.com\/wp-content\/uploads\/2021\/05\/Session-Host-Unavailable.png\" alt=\"\" class=\"wp-image-2081\" srcset=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Session-Host-Unavailable.png 689w, https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2021\/05\/Session-Host-Unavailable-300x89.png 300w\" sizes=\"(max-width: 689px) 100vw, 689px\" \/><figcaption class=\"wp-element-caption\"> Session Host Unavailable <\/figcaption><\/figure>\n\n\n\n<p>That, my friends, is how to shut down Session Hosts in a Personal\nHost Pool with no active sessions.&nbsp; <\/p>\n","protected":false},"excerpt":{"rendered":"<p>(UPDATED 6\/17\/2021 with code for multiple pooled and personal host pools) Azure Virtual Desktop (previously Windows Virtual Desktop (WVD)) has a new option in preview that starts session hosts in a personal or pooled host pool when a user connects. It won\u2019t, however, shut down the session hosts when the user logs out. The script &hellip;<\/p>\n<p class=\"read-more\"> <a class=\"\" href=\"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/\"> <span class=\"screen-reader-text\">Shut Down Unused Session Hosts in a Windows Virtual Desktop Pooled or Personal Host Pool<\/span> Read More &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":3827,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"default","ast-global-header-display":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":""},"categories":[1],"tags":[617,751,230,748,9,614,616,406,585,749,462,988,20,52,394,753,754,613,618,615,750,407,405,400,404,392,393,987],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Shut Down Unused Session Hosts in a Windows Virtual Desktop Pooled or Personal Host Pool - ciraltos<\/title>\n<meta name=\"description\" content=\"The script outlined in this post will evaluate available Session Hosts in a Pooled or Personal Host Pool and shut down Session Hosts without an active connection.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Shut Down Unused Session Hosts in a Windows Virtual Desktop Pooled or Personal Host Pool - ciraltos\" \/>\n<meta property=\"og:description\" content=\"The script outlined in this post will evaluate available Session Hosts in a Pooled or Personal Host Pool and shut down Session Hosts without an active connection.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/\" \/>\n<meta property=\"og:site_name\" content=\"ciraltos\" \/>\n<meta property=\"article:published_time\" content=\"2021-05-08T20:33:02+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-03-23T11:26:05+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2023\/03\/WVDFunctionApp.png\" \/>\n\t<meta property=\"og:image:width\" content=\"101\" \/>\n\t<meta property=\"og:image:height\" content=\"182\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Travis Roberts\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ciraltos\" \/>\n<meta name=\"twitter:site\" content=\"@ciraltos\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Travis Roberts\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/\"},\"author\":{\"name\":\"Travis Roberts\",\"@id\":\"http:\/\/www.ciraltos.com\/staging2\/#\/schema\/person\/25391996d6cddfecd4d257162b7e373a\"},\"headline\":\"Shut Down Unused Session Hosts in a Windows Virtual Desktop Pooled or Personal Host Pool\",\"datePublished\":\"2021-05-08T20:33:02+00:00\",\"dateModified\":\"2023-03-23T11:26:05+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/\"},\"wordCount\":1564,\"commentCount\":33,\"publisher\":{\"@id\":\"http:\/\/www.ciraltos.com\/staging2\/#\/schema\/person\/25391996d6cddfecd4d257162b7e373a\"},\"keywords\":[\"automatically start\",\"automatically stop\",\"Automation\",\"az.DesktopVirtualization\",\"Azure\",\"azure function\",\"cost saving\",\"Desktop\",\"Host Pool\",\"Managed Identity\",\"Microsoft Azure\",\"Personal Host Pool\",\"Powershell\",\"remote desktop\",\"Remote Desktop Services\",\"spring update\",\"spring update 2020\",\"start\",\"start and stop\",\"stop\",\"System Managed Identity\",\"VDI\",\"virtualize\",\"Windows 10\",\"Windows 7\",\"Windows Virtual Desktop\",\"WVD\",\"WVD Automation\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/\",\"url\":\"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/\",\"name\":\"Shut Down Unused Session Hosts in a Windows Virtual Desktop Pooled or Personal Host Pool - ciraltos\",\"isPartOf\":{\"@id\":\"http:\/\/www.ciraltos.com\/staging2\/#website\"},\"datePublished\":\"2021-05-08T20:33:02+00:00\",\"dateModified\":\"2023-03-23T11:26:05+00:00\",\"description\":\"The script outlined in this post will evaluate available Session Hosts in a Pooled or Personal Host Pool and shut down Session Hosts without an active connection.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"http:\/\/www.ciraltos.com\/staging2\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Shut Down Unused Session Hosts in a Windows Virtual Desktop Pooled or Personal Host Pool\"}]},{\"@type\":\"WebSite\",\"@id\":\"http:\/\/www.ciraltos.com\/staging2\/#website\",\"url\":\"http:\/\/www.ciraltos.com\/staging2\/\",\"name\":\"ciraltos\",\"description\":\"cloud, technology and trends\",\"publisher\":{\"@id\":\"http:\/\/www.ciraltos.com\/staging2\/#\/schema\/person\/25391996d6cddfecd4d257162b7e373a\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"http:\/\/www.ciraltos.com\/staging2\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"http:\/\/www.ciraltos.com\/staging2\/#\/schema\/person\/25391996d6cddfecd4d257162b7e373a\",\"name\":\"Travis Roberts\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"http:\/\/www.ciraltos.com\/staging2\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2023\/03\/Logo-1.png\",\"contentUrl\":\"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2023\/03\/Logo-1.png\",\"width\":5657,\"height\":3563,\"caption\":\"Travis Roberts\"},\"logo\":{\"@id\":\"http:\/\/www.ciraltos.com\/staging2\/#\/schema\/person\/image\/\"},\"sameAs\":[\"http:\/\/www.ciraltos.com\",\"https:\/\/twitter.com\/ciraltos\"],\"url\":\"https:\/\/www.ciraltos.com\/staging2\/author\/admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Shut Down Unused Session Hosts in a Windows Virtual Desktop Pooled or Personal Host Pool - ciraltos","description":"The script outlined in this post will evaluate available Session Hosts in a Pooled or Personal Host Pool and shut down Session Hosts without an active connection.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/","og_locale":"en_US","og_type":"article","og_title":"Shut Down Unused Session Hosts in a Windows Virtual Desktop Pooled or Personal Host Pool - ciraltos","og_description":"The script outlined in this post will evaluate available Session Hosts in a Pooled or Personal Host Pool and shut down Session Hosts without an active connection.","og_url":"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/","og_site_name":"ciraltos","article_published_time":"2021-05-08T20:33:02+00:00","article_modified_time":"2023-03-23T11:26:05+00:00","og_image":[{"width":101,"height":182,"url":"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2023\/03\/WVDFunctionApp.png","type":"image\/png"}],"author":"Travis Roberts","twitter_card":"summary_large_image","twitter_creator":"@ciraltos","twitter_site":"@ciraltos","twitter_misc":{"Written by":"Travis Roberts","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/#article","isPartOf":{"@id":"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/"},"author":{"name":"Travis Roberts","@id":"http:\/\/www.ciraltos.com\/staging2\/#\/schema\/person\/25391996d6cddfecd4d257162b7e373a"},"headline":"Shut Down Unused Session Hosts in a Windows Virtual Desktop Pooled or Personal Host Pool","datePublished":"2021-05-08T20:33:02+00:00","dateModified":"2023-03-23T11:26:05+00:00","mainEntityOfPage":{"@id":"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/"},"wordCount":1564,"commentCount":33,"publisher":{"@id":"http:\/\/www.ciraltos.com\/staging2\/#\/schema\/person\/25391996d6cddfecd4d257162b7e373a"},"keywords":["automatically start","automatically stop","Automation","az.DesktopVirtualization","Azure","azure function","cost saving","Desktop","Host Pool","Managed Identity","Microsoft Azure","Personal Host Pool","Powershell","remote desktop","Remote Desktop Services","spring update","spring update 2020","start","start and stop","stop","System Managed Identity","VDI","virtualize","Windows 10","Windows 7","Windows Virtual Desktop","WVD","WVD Automation"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/","url":"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/","name":"Shut Down Unused Session Hosts in a Windows Virtual Desktop Pooled or Personal Host Pool - ciraltos","isPartOf":{"@id":"http:\/\/www.ciraltos.com\/staging2\/#website"},"datePublished":"2021-05-08T20:33:02+00:00","dateModified":"2023-03-23T11:26:05+00:00","description":"The script outlined in this post will evaluate available Session Hosts in a Pooled or Personal Host Pool and shut down Session Hosts without an active connection.","breadcrumb":{"@id":"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.ciraltos.com\/staging2\/shut-down-unused-session-hosts-in-a-windows-virtual-desktop-personal-host-pool\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"http:\/\/www.ciraltos.com\/staging2\/"},{"@type":"ListItem","position":2,"name":"Shut Down Unused Session Hosts in a Windows Virtual Desktop Pooled or Personal Host Pool"}]},{"@type":"WebSite","@id":"http:\/\/www.ciraltos.com\/staging2\/#website","url":"http:\/\/www.ciraltos.com\/staging2\/","name":"ciraltos","description":"cloud, technology and trends","publisher":{"@id":"http:\/\/www.ciraltos.com\/staging2\/#\/schema\/person\/25391996d6cddfecd4d257162b7e373a"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"http:\/\/www.ciraltos.com\/staging2\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"http:\/\/www.ciraltos.com\/staging2\/#\/schema\/person\/25391996d6cddfecd4d257162b7e373a","name":"Travis Roberts","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"http:\/\/www.ciraltos.com\/staging2\/#\/schema\/person\/image\/","url":"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2023\/03\/Logo-1.png","contentUrl":"https:\/\/www.ciraltos.com\/staging2\/wp-content\/uploads\/2023\/03\/Logo-1.png","width":5657,"height":3563,"caption":"Travis Roberts"},"logo":{"@id":"http:\/\/www.ciraltos.com\/staging2\/#\/schema\/person\/image\/"},"sameAs":["http:\/\/www.ciraltos.com","https:\/\/twitter.com\/ciraltos"],"url":"https:\/\/www.ciraltos.com\/staging2\/author\/admin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.ciraltos.com\/staging2\/wp-json\/wp\/v2\/posts\/2048"}],"collection":[{"href":"https:\/\/www.ciraltos.com\/staging2\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ciraltos.com\/staging2\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ciraltos.com\/staging2\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ciraltos.com\/staging2\/wp-json\/wp\/v2\/comments?post=2048"}],"version-history":[{"count":12,"href":"https:\/\/www.ciraltos.com\/staging2\/wp-json\/wp\/v2\/posts\/2048\/revisions"}],"predecessor-version":[{"id":3846,"href":"https:\/\/www.ciraltos.com\/staging2\/wp-json\/wp\/v2\/posts\/2048\/revisions\/3846"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.ciraltos.com\/staging2\/wp-json\/wp\/v2\/media\/3827"}],"wp:attachment":[{"href":"https:\/\/www.ciraltos.com\/staging2\/wp-json\/wp\/v2\/media?parent=2048"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ciraltos.com\/staging2\/wp-json\/wp\/v2\/categories?post=2048"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ciraltos.com\/staging2\/wp-json\/wp\/v2\/tags?post=2048"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}