Maxim_Kazmin - Fotolia

Tip

How to use PowerShell to track VDI resources

It's never ideal to have underutilized servers in a VDI environment. Here's how IT pros can create a PowerShell script to track VDI resource utilization.

PowerShell is deeply integrated into the Windows operating system, so you can use PowerShell to look for underutilized areas of VDI.

Here are a few basic methods that you can adapt to your own environment to use PowerShell to track VDI resources.

Scan your servers

If your goal is to build a PowerShell script to track VDI resource utilization, then you should first create a loop that can view your servers one at a time. To do so, create a list of all the servers.

For the purposes of this article, I will hardcode the server names, but you could design the script to query the names or pull the names from a text file instead. Either method would make the script more dynamic.

Here is a line of code that creates an array containing a list of servers:

$Servers = @("Hyper-V-1", "Hyper-V-2", "Hyper-V-3", "Hyper-V-4")

This line creates a variable called $Servers, which contains a list of Hyper-V servers named Hyper-V-1, Hyper-V-2, etc. You can adjust this command if you use a VDI platform that isn't based on Hyper-V.

Now that you have a list of servers mapped to a variable, the next step is to create a loop:

ForEach ($Server in $Servers) {
}

This loop progresses through the list of servers one by one. The code ends with a set of brackets. Any code that you add between the two brackets will apply to each server in the list.

Write the script

The next step is to write some code that can check to see if a VDI host is underutilized. First, you should determine what it means for a host to be underutilized.

For the sake of this article, I am going to define an underutilized server as a server that has more than 20% of its memory available. However, you should use a definition that makes sense for your own environment.

Here is what my script looks like:

$Servers = @("Hyper-V-1", "Hyper-V-2", "Hyper-V-3", "Hyper-V-4")
ForEach ($Server in $Servers) {

$ServerName = $Server
$MySession = New-PSSession -ComputerName $ServerName
Invoke-Command -Session $MySession -ScriptBlock {

Write-Host $ServerName
$TotalMemory = (Get-CimInstance Win32_OperatingSystem).TotalVisibleMemorySize
$FreeMemory = (Get-CimInstance Win32_OperatingSystem).FreePhysicalMemory
$TargetMemorySize = $TotalMemory * .2
Write-Host "Total Memory: " $TotalMemory
Write-Host "Free Memory: " $FreeMemory
If ($FreeMemory -GT $TargetMemorySize) { Write-Host "This host is underutilized"}
If ($FreeMemory -LT $TargetMemorySize) {Write-Host "This host is not underutilized"}
}
}

This script assumes that all of the hosts are domain-joined and that Kerberos is the authenticator.

The first section of the script defines the list of hosts it will query and then sets up a loop. I will create a variable called $ServerName that holds the name of the server the script is currently querying.

The next two lines of code establish a remote session with the server the command is querying. The Invoke-Command cmdlet defines a script block. All of the code within the script block runs against a remote machine.

$MySession = New-PSSession -ComputerName $ServerName
Invoke-Command -Session $MySession -ScriptBlock {

The contents of the script block compare the server's total memory against the memory in use to determine whether or not the server is underutilized. The $TotalMemory variable holds the total amount of installed memory in the server, while the $FreeMemory variable stores the remaining amount of memory.

In this example, underutilized servers use less than 80% of the available memory. I have created a variable called $TargetMemorySize that contains a value that is equal to 20% of the total memory --$TotalMemory * .2. This allows me to compare the server's free memory amount -- $FreeMemory -- against my target value -- $TargetMemorySize -- in order to determine whether or not the machine is being underutilized.

For the sake of simplicity, I created a modified version of the script. I removed the loop and the code to create a remote session. This simplified script only examines the local machine instead of querying remote hosts. I also added a line of code to display the target memory size. Here is the simplified script:

$TotalMemory = (Get-CimInstance Win32_OperatingSystem).TotalVisibleMemorySize
$FreeMemory = (Get-CimInstance Win32_OperatingSystem).FreePhysicalMemory
$TargetMemorySize = $TotalMemory * .2
Write-Host "Total Memory: " $TotalMemory
Write-Host "Free Memory: " $FreeMemory
Write-Host "Target Memory Size: " $TargetMemorySize
If ($FreeMemory -GT $TargetMemorySize) { Write-Host "This host is underutilized"}
If ($FreeMemory -LT $TargetMemorySize) {Write-Host "This host is not underutilized"}

Dig Deeper on Virtual and remote desktop strategies

Enterprise Desktop
Cloud Computing
SearchVMware
Close