lundi 20 mai 2013

POWERCLI: list vMotion, Storage vMotion, and who triggered it

· 2 commentaires

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......

A propos de moi

Je suis David Vekemans. Ingénieur en informatique de 32 ans, je vais à travers ce blog essayer de vous faire partager mon expérience en résolution de problèmes. Cela va couvrir mes différents centres d'intérêts : l'informatique et Windows, la photographie numérique, la réception satellite.

Visites