A few months ago, I started in a new company. After an audit of their VMware infrastructure, I was very surprised to discover that DRS was disabled.
The reason was that they were afraid of too much VMs moving, or doing ping-pong between hosts. Moreover, they never investigated the possibility of DRS rules.
So in order to improve the inventory, I had to convince them to activate DRS.
The first thing I suggested was to introduce DRS rules. Indeed, there was clustered VMs, so it is better to split them on different hosts.
Moreover, as we had a double room datacenter, it was even better to have one node in each room.
We had also some VMs that must run together.
Secondly, I had to convince them that VMs will not move so much. So I suggested to monitor all the VMotions, and generate some alerts in the Nagios console:
- a warning for more than 10 vmotions in the last 24 hours
- a critcal for more than 20 vmotions in the last 24 hours
I also proposed to keep a trace of all the vMotions in a database, so we could do reporting in our SQLReporting Dashboard.
But I needed a script to collect the vMotions data. I found one on Alan Remouf's blog: http://www.virtu-al.net/2012/09/20/vmotion-and-svmotion-details-with-powercli/
But it was not perfect for my needs. So I improved its function. The code is here below. Let me know if you have any comment.
function Get-VMotionDuration {
<#
.SYNOPSIS
This function returns the list of VMotions and Storage VMotions that occured during a specified period.
.DESCRIPTION
This function returns the list of VMotions and Storage VMotions that occured during a specified period.
You can specify if you want DRS triggered VMotions, manual VMotions or both.
.NOTES
File Name : Get-VMotionDuration.ps1
Author : David Vekemans - based on an original script from Alan Renouf
Date : 17/05/2013
Version : 1.00
History : 1.00 - 17/05/2013 - Initial release
.LINK
http://geekdav.blogspot.be/2013/05/powercli-list-vmotion-storage-vmotion.html
http://www.virtu-al.net/2012/09/20/vmotion-and-svmotion-details-with-powercli/
.PARAMETER Start
This parameter specify the start date and time of the period to analyze.
It must be a DATETIME type.
.PARAMETER Finish
This parameter specify the end date and time of the period to analyze.
It must be a DATETIME type.
.PARAMETER DaysOfHistory
This is another way to give the start and end time of the period to analyze.
This parameter specify the number of days from now to define the start time.
The default value is 1 day.
It must be a INTEGER type.
.PARAMETER Type
This parameter specify the types pf VMotion that you want to display.
Possible values are :
DRS - for DRS triggered VMotions
MANUAL - for any user triggered VMotions
BOTH - for all VMotions
Default value is BOTH.
.OUTPUTS
The output is a special PSobject (or a table of PSobjects) with the following properties:
VMName : name of the VM that was moved
StartTime : start time of the vMotion
EndTime : end time of the vMotion
Duration : duration of the vMotion
SourceHost : original host of the VM
DestinationHost : new host of the VM
Type : type of move vMotion or svMotion
Trigger : trigger of move : DRS or MANUAL
User : admin who triggered the move (only in case of MANUAL)
.INPUTS
See the paramater list.
.EXAMPLE
Get-VMotionDuration -DaysOfHistory 3 -Type DRS
Name : VM1
StartTime : 16/05/2013 11:32:38
EndTime : 16/05/2013 11:36:02
Duration : 00:03:23.9130000
SourceHost : host06.local
DestinationHost : host07.local
Type : vMotion
Trigger : DRS
User :
Name : VM2
StartTime : 16/05/2013 11:32:39
EndTime : 16/05/2013 11:35:54
Duration : 00:03:15.8170000
SourceHost : host08.local
DestinationHost : host09.local
Type : vMotion
Trigger : DRS
User :
This command will list all the VMotions done by DRS during the last 3 days.
.EXAMPLE
Get-VMotionDuration -Start (get-date).addhours(-4) -Finish (get-date) -Type Manual
VMName : VM3
StartTime : 17/05/2013 09:35:56
EndTime : 17/05/2013 09:36:53
Duration : 00:00:56.8360000
SourceHost : host08.local
DestinationHost : host09.local
Type : vMotion
Trigger : MANUAL
User : DOMAIN\admin_user
This command will list all the VMotions done by any admin during the last 4 hours.
.EXAMPLE
Get-VMotionDuration 1
VMName : VM4
StartTime : 16/05/2013 11:41:02
EndTime : 16/05/2013 11:42:10
Duration : 00:01:08.1000010
SourceHost : host07.local
DestinationHost : host09.local
Type : vMotion
Trigger : DRS
User :
VMName : VM5
StartTime : 17/05/2013 09:35:56
EndTime : 17/05/2013 09:36:53
Duration : 00:00:56.8360000
SourceHost : host08.local
DestinationHost : host09.local
Type : vMotion
Trigger : MANUAL
User : DOMAIN\admin_user
VMName : VM6
StartTime : 17/05/2013 11:25:57
EndTime : 17/05/2013 11:27:06
Duration : 00:01:09.0300010
SourceHost : host09.local
DestinationHost : host09.local
Type : svMotion
Trigger : MANUAL
User : DOMAIN\admin_user
This command will list all the VMotions during the last day.
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory=$True,
ParameterSetName="1",
Position=0)]
[datetime]$Start,
[Parameter(Mandatory=$True,
ParameterSetName="1",
Position=1)]
[datetime]$Finish,
[Parameter(Mandatory=$True,
ParameterSetName="2",
Position=0)]
[int]$DaysOfHistory = 1,
[Parameter(Mandatory=$False)]
[ValidateSet("DRS","Manual","Both")]
[String]$Type="Both"
)
begin {
write-verbose "Starting function"
$Type = $Type.toupper()
if ($DaysOfHistory){
$Now = Get-Date
$Start = $Now.AddDays(-$DaysOfHistory)
$Finish = $Now
}
else {
$DaysOfHistory = ($Finish - $Start).Days
}
Write-verbose "Number of days of history is : $DaysOfHistory"
Write-verbose "Start time is : $Start"
Write-verbose "Finish time is : $Finish"
$Maxsamples = ($DaysOfHistory+1)*50000
Write-verbose "Max samples : $Maxsamples"
Write-Verbose "Type is : $type"
$ResultDRS = @()
$ResultManual = @()
}
process {
write-verbose "Beginning process loop"
$events = get-vievent -start $Start -finish $Finish -maxsamples $Maxsamples
if (($Type -eq "DRS") -or ($Type -eq "BOTH")) {
$relocates = $events | where {($_.GetType().Name -eq "TaskEvent") -and ($_.Info.DescriptionId -eq "Drm.ExecuteVMotionLRO")}
foreach($task in $relocates){
$tEvents = $events | where {$_.ChainId -eq $task.ChainId} | Sort-Object -Property CreatedTime
if($tEvents.Count){
$obj = New-Object PSObject -Property @{
VMName = $tEvents[0].Vm.Name
Type = &{if($tEvents[0].Host.Name -eq $tEvents[-1].Host.Name){"svMotion"}else{"vMotion"}}
Trigger = "DRS"
StartTime = $tEvents[0].CreatedTime
EndTime = $tEvents[-1].CreatedTime
Duration = New-TimeSpan -Start $tEvents[0].CreatedTime -End $tEvents[-1].CreatedTime
SourceHost = $tEvents[0].Host.Name
DestinationHost = $tEvents[-1].Host.Name
User = $tEvents[0].UserName
}
$ResultDRS+=$obj
}
}
}
if (($Type -eq "MANUAL") -or ($Type -eq "BOTH")) {
$relocates = $events |
where {($_.GetType().Name -eq "TaskEvent") -and (($_.Info.DescriptionId -eq "VirtualMachine.migrate") -or ($_.Info.DescriptionId -eq "VirtualMachine.relocate"))}
foreach($task in $relocates){
$tEvents = $events | where {$_.ChainId -eq $task.ChainId} | Sort-Object -Property CreatedTime
if($tEvents.Count){
$obj = New-Object PSObject -Property @{
VMName = $tEvents[0].Vm.Name
Type = &{if($tEvents[0].Host.Name -eq $tEvents[-1].Host.Name){"svMotion"}else{"vMotion"}}
Trigger = "MANUAL"
StartTime = $tEvents[0].CreatedTime
EndTime = $tEvents[-1].CreatedTime
Duration = New-TimeSpan -Start $tEvents[0].CreatedTime -End $tEvents[-1].CreatedTime
SourceHost = $tEvents[0].Host.Name
DestinationHost = $tEvents[-1].Host.Name
User = $tEvents[0].UserName
}
$ResultMANUAL+=$obj
}
}
}
}
end {
write-verbose "Ending function"
if ($Type -eq "DRS") {$Result = $ResultDRS}
if ($Type -eq "MANUAL") {$Result = $ResultMANUAL}
if ($Type -eq "BOTH") {$Result = $ResultDRS + $ResultMANUAL}
$Result | Select-Object VMName,StartTime,EndTime,Duration,SourceHost,DestinationHost,Type,Trigger,User | Sort-Object -Property StartTime
}
}
Read More......