PowerShell script used in the Windows Server 2016 TP2 Storage QoS demo at MSIgnite
This is the Windows PowerShell script I used in the Microsoft Ignite 2015 session on Storage QoS: Hyper-V Storage Performance with Storage Quality of Service. You can also find that demo video by itself at Windows Server 2016 TP2 Storage QoS: Managing with a PowerShell script.
The script is fairly straightforward, but there a few interesting points to make about what it does:
- The script is designed to run from a separate management computer, so all Storage QoS cmdlets use the –CimSession option to point to the Scale-Out File Server.
- There is a handy function called “Get-PolicyName” that translates a PolicyID into a PolicyName by using Get-StorageQosPolicy.
- It shows how to filter output of Get-StorageQosFlow. It remove the default policy entries from the list and and sorts the list by VM name (InitiatorName).
- It offers a good example of how to use Expressions to format the output of Get-StorageQosFlow.
- It uses the $LastChange variable to later show the time passed since the QoS policies were changed with Set-StorageQosPolicy, since the Get-StorageQosFlow is an average for the last 5 minutes.
Here’s the script:
# QosDemo.ps1 – Storage QoS demo script for Microsoft Ignite 2015
Function Get-PolicyName([string] $PolicyID)
{
$Policy = Get-StorageQosPolicy -CimSession JOSEBDA-FS -PolicyID $PolicyID
Return $Policy.Name
}
$LastChange = Get-Date
$Option = "R"
While ($Option -ne "Q") {
Clear-Host
Write-Host -ForegroundColor Yellow "C:> Get-StorageQosFlow |”
Write-Host -ForegroundColor Yellow “FT InitiatorNodeName, InitiatorName, FilePath, MinimumIOPS, MaximumIOPS, InitiatorIOPS, InitiatorLatency, PolicyID"
Get-StorageQosFlow -CimSession JOSEBDA-FS | ? InitiatorName -ne "" | Sort InitiatorName |
FT @{Expression={$_.InitiatorNodeName.Split(".")[0]}; Label="Node"},
@{Expression={$_.InitiatorName}; Label="VM"},
@{Expression={$_.FilePath.Split("")[4]}; Label="File"},
@{Expression={$_.MinimumIOPS}; Label="MinIOPS"},
@{Expression={$_.MaximumIOPS}; Label="MaxIOPS"},
@{Expression={$_.InitiatorIOPS}; Label="VM IOPS"},
@{Expression={[int] $_.InitiatorLatency}; Label="Latency"},
@{Expression={(Get-PolicyName $_.PolicyID)}; Label="Policy"},
PolicyID -AutoSize
$TimeDiff = (Get-Date) - $LastChange
$Minutes = [System.Math]::Round($TimeDiff.TotalMinutes, 2)
$Seconds = [System.Math]::Round($TimeDiff.TotalSeconds, 2)
Write-Host "IOPS and Latency are 5-minute averages. Last policy change $Seconds seconds ago ($Minutes minutes ago)."
Write-Host
Write-Host -ForegroundColor Yellow "C:> Get-StorageQosPolicy | FT Name, PolicyType, MinimumIOPS, MaximumIOPS, PolicyID"
Get-StorageQosPolicy -CimSession JOSEBDA-FS | FT Name, PolicyType, MinimumIOPS, MaximumIOPS, PolicyID -AutoSize
Write-Host -NoNewline "Command: Quit, Refresh, Zero, Low, High: "
$Option = Read-Host
$Option = $Option.ToUpper()[0]
Switch ($Option) {
"Z" {
Set-StorageQosPolicy -CimSession JOSEBDA-FS -Name SilverVM -MinimumIops 0 -MaximumIops 0
Set-StorageQosPolicy -CimSession JOSEBDA-FS -Name GoldVM -MinimumIops 0 -MaximumIops 0
$LastChange = Get-Date
}
"L" {
Set-StorageQosPolicy -CimSession JOSEBDA-FS -Name SilverVM -MinimumIops 200 -MaximumIops 500
Set-StorageQosPolicy -CimSession JOSEBDA-FS -Name GoldVM -MinimumIops 500 -MaximumIops 1000
$LastChange = Get-Date
}
"H" {
Set-StorageQosPolicy -CimSession JOSEBDA-FS -Name SilverVM -MinimumIops 500 -MaximumIops 1000
Set-StorageQosPolicy -CimSession JOSEBDA-FS -Name GoldVM -MinimumIops 1000 -MaximumIops 5000
$LastChange = Get-Date
}
} #end switch
} #end while