MaxIOPS and SCSI-UNMAP
Two new Functions: - Report VM Disk IOPS of VMs - Process SCSI UNMAP on VMware Datastores
This commit is contained in:
85
Modules/Get-VMmaxIOPS.psm1
Normal file
85
Modules/Get-VMmaxIOPS.psm1
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
function Get-VMmaxIOPS {
|
||||||
|
<#
|
||||||
|
|
||||||
|
.SYNOPSIS
|
||||||
|
Report VM Disk IOPS of VMs
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
This Function will Create a VM Disk IOPS Report
|
||||||
|
|
||||||
|
.Example
|
||||||
|
Get-VM TST* | Get-VMmaxIOPS -Minutes 60 | FT -Autosize
|
||||||
|
|
||||||
|
.Example
|
||||||
|
$SampleVMs = Get-VM "TST*"
|
||||||
|
Get-VMmaxIOPS -VMs $SampleVMs -Minutes 60
|
||||||
|
|
||||||
|
.PARAMETER VMs
|
||||||
|
Specify the VMs
|
||||||
|
|
||||||
|
.PARAMETER Minutes
|
||||||
|
Specify the Minutes to report (10080 is one Week)
|
||||||
|
|
||||||
|
.Notes
|
||||||
|
NAME: Get-VMmaxIOPS.ps1
|
||||||
|
LASTEDIT: 08/23/2016
|
||||||
|
VERSION: 1.1
|
||||||
|
KEYWORDS: VMware, vSphere, ESXi, IOPS
|
||||||
|
|
||||||
|
.Link
|
||||||
|
http://mycloudrevolution.com/
|
||||||
|
|
||||||
|
#Requires PS -Version 4.0
|
||||||
|
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
|
||||||
|
#>
|
||||||
|
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true, ValueFromPipeline=$True, Position=0)]
|
||||||
|
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]
|
||||||
|
$VMs,
|
||||||
|
[Parameter(Mandatory=$false, Position=1)]
|
||||||
|
[int] $Minutes = 30
|
||||||
|
)
|
||||||
|
|
||||||
|
Process {
|
||||||
|
|
||||||
|
#region: Global Definitions
|
||||||
|
[int]$TimeRange = "-" + $Minutes
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region: Creating Metrics
|
||||||
|
Write-Debug "Starting to Create Metrics..."
|
||||||
|
$metrics = "virtualDisk.numberReadAveraged.average","virtualDisk.numberWriteAveraged.average"
|
||||||
|
$start = (Get-Date).AddMinutes($TimeRange)
|
||||||
|
$stats = Get-Stat -Stat $metrics -Entity $VMs -Start $start
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region: Creating HD-Tab
|
||||||
|
Write-Debug "Starting to Create HD-Tab..."
|
||||||
|
$hdTab = @{}
|
||||||
|
foreach($hd in (Get-Harddisk -VM $VMs)){
|
||||||
|
$controllerKey = $hd.Extensiondata.ControllerKey
|
||||||
|
$controller = $hd.Parent.Extensiondata.Config.Hardware.Device | where{$_.Key -eq $controllerKey}
|
||||||
|
$hdTab[$hd.Parent.Name + "/scsi" + $controller.BusNumber + ":" + $hd.Extensiondata.UnitNumber] = $hd.FileName.Split(']')[0].TrimStart('[')
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region: Creating Reports
|
||||||
|
Write-Debug "Starting to Process IOPS Report..."
|
||||||
|
$reportPerf = @()
|
||||||
|
$reportPerf = $stats | Group-Object -Property {$_.Entity.Name},Instance | %{
|
||||||
|
New-Object PSObject -Property @{
|
||||||
|
VM = $_.Values[0]
|
||||||
|
Disk = $_.Values[1]
|
||||||
|
IOPSMax = ($_.Group | `
|
||||||
|
Group-Object -Property Timestamp | `
|
||||||
|
%{$_.Group[0].Value + $_.Group[1].Value} | `
|
||||||
|
Measure-Object -Maximum).Maximum
|
||||||
|
Datastore = $hdTab[$_.Values[0] + "/"+ $_.Values[1]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$reportPerf | Select-Object VM, Disk, Datastore, IOPSMax
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
99
Modules/Start-UNMAP.psm1
Normal file
99
Modules/Start-UNMAP.psm1
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
function Start-UNMAP {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Process SCSI UNMAP on VMware Datastores
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
This Function will process SCSI UNMAP on VMware Datastores via ESXCLI -V2
|
||||||
|
|
||||||
|
.Example
|
||||||
|
Start-UNMAP -ClusterName myCluster -DSWildcard *RAID5*
|
||||||
|
|
||||||
|
.Example
|
||||||
|
Start-UNMAP -ClusterName myCluster -DSWildcard *RAID5* -Verbose -WhatIf
|
||||||
|
|
||||||
|
.Notes
|
||||||
|
NAME: Start-UNMAP.psm1
|
||||||
|
AUTHOR: Markus Kraus
|
||||||
|
LASTEDIT: 23.09.2016
|
||||||
|
VERSION: 1.0
|
||||||
|
KEYWORDS: VMware, vSphere, ESXi, SCSI, VAAI, UNMAP
|
||||||
|
|
||||||
|
.Link
|
||||||
|
http://mycloudrevolution.com/
|
||||||
|
|
||||||
|
#Requires PS -Version 4.0
|
||||||
|
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
|
||||||
|
#>
|
||||||
|
|
||||||
|
[CmdletBinding(SupportsShouldProcess = $true,ConfirmImpact='High')]
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true, Position=0)]
|
||||||
|
[String]$ClusterName,
|
||||||
|
[Parameter(Mandatory=$true, Position=1)]
|
||||||
|
[String]$DSWildcard
|
||||||
|
)
|
||||||
|
Process {
|
||||||
|
$Validate = $true
|
||||||
|
#region: PowerCLI Session Timeout
|
||||||
|
Write-Verbose "Set Session Timeout ..."
|
||||||
|
$initialTimeout = (Get-PowerCLIConfiguration -Scope Session).WebOperationTimeoutSeconds
|
||||||
|
Set-PowerCLIConfiguration -Scope Session -WebOperationTimeoutSeconds -1 -Confirm:$False | Out-Null
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region: Get Cluster
|
||||||
|
$Cluster = Get-Cluster -Name $ClusterName -ErrorAction SilentlyContinue
|
||||||
|
Write-Verbose "vSphere Cluster: $Cluster"
|
||||||
|
if (!$Cluster){Write-Error "No Cluster found!"; $Validate = $false}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region: Get Hosts
|
||||||
|
$ClusterHosts = $Cluster | Get-VMHost -ErrorAction SilentlyContinue | where {$_.ConnectionState -eq "Connected" -and $_.PowerState -eq "PoweredOn"}
|
||||||
|
Write-Verbose "vSphere Cluster Hosts: $ClusterHosts"
|
||||||
|
if (!$ClusterHosts){Write-Error "No Hosts found!"; $Validate = $false}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region: Get Datastores
|
||||||
|
$ClusterDataStores = $Cluster | Get-Datastore -ErrorAction SilentlyContinue | where {$_.Name -like $DSWildcard -and $_.State -eq "Available" -and $_.Accessible -eq "True"}
|
||||||
|
Write-Verbose "vSphere Cluster Datastores: $ClusterDataStores"
|
||||||
|
if (!$ClusterDataStores){Write-Error "No Datastores found!"; $Validate = $false}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region: Process Datastores
|
||||||
|
if ($Validate -eq $true) {
|
||||||
|
Write-Verbose "Starting Loop..."
|
||||||
|
foreach ($ClusterDataStore in $ClusterDataStores) {
|
||||||
|
Write-Verbose "vSphere Datastore to Process: $ClusterDataStore"
|
||||||
|
$myHost = $ClusterHosts[(Get-Random -Maximum ($ClusterHosts).count)]
|
||||||
|
Write-Verbose "vSphere Host to Process: $myHost"
|
||||||
|
$esxcli2 = $myHost | Get-ESXCLI -V2
|
||||||
|
$arguments = $esxcli2.storage.vmfs.unmap.CreateArgs()
|
||||||
|
$arguments.volumelabel = $ClusterDataStore
|
||||||
|
$arguments.reclaimunit = "256"
|
||||||
|
if ($PSCmdlet.ShouldProcess( $ClusterDataStore,"Starting UNMAP on $myHost")) {
|
||||||
|
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
|
||||||
|
try {
|
||||||
|
Write-Output "Starting UNMAP for $ClusterDataStore on $myHost..."
|
||||||
|
$esxcli2.storage.vmfs.unmap.Invoke($arguments)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Output "A Error occured: " "" $error[0] ""
|
||||||
|
}
|
||||||
|
$stopwatch.Stop()
|
||||||
|
Write-Output "UNMAP duration: $($stopwatch.Elapsed.Minutes)"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Error "Validation Failed. Processing Loop Skipped!"
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region: Revert PowerCLI Session Timeout
|
||||||
|
Write-Verbose "Revert Session Timeout ..."
|
||||||
|
Set-PowerCLIConfiguration -Scope Session -WebOperationTimeoutSeconds $initialTimeout -Confirm:$False | Out-Null
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user