Get the vMotion/svMotion history

The availability of vMotion and svMotion, provided you have a license that allows it, in vSphere are some of its key features.

The DRS and SDRS functionality will use vMotion and svMotion to better use the available resources.

And you as a vSphere administrator can use it to facilitate your work. Just think of how easy patching or datastorecluster maintenance becomes with the help of these two features.
But as an administrator you want to be able to report on what vMotion and svMotion have been doing over a specific time interval in your vSphere environment.

In the past I already provided a vMotion reporting tool in Events – Part 8 – vMotion history, but now it was time to provide a universal (s)vMotion reporting feature.

motion-reports

Update October 29th 2013: added additional parameters to the Get-VIEventPlus function

  • User: one or more users for which to return the events
  • System: a switch to return all system user events
  • ScheduledTask: return all events for a specific Scheduled Task

Update February 10th 2014: it’s always nice to see another implementation based on one of your scripts. The Opvizor solution will soon contain this function, see Dennis Zimmer‘s post called Storage vMotion Activities Report !

The Script

Annotations

Line 1-101: The Get-VIEventPlus function. This function adds some improvements, at least for me, to the current Get-VIEvent cmdlet. It allows you to specify which specific events to return and it allows you to use a ‘recursive’ search for events starting from the ‘Entity’.

Line 52: The function uses the EventHistoryCollector. Access to the found events is through a ‘sliding‘ window. This variable defines the size of that sliding window. From my average use, I came to the conclusion that 100 events is a workable size for this window. But your mileage may vary.

Line 55-85: These lines are the hearth of the function. In here the ‘filter‘ is specified for the events to search for. See the EventFilterSpec objects for the details.

Line 89: The EventFilterSpec can hold only one MoRef. So if multiple entities are passed, they will have be handled one by one. This makes a big difference in execution time when you do not select the value for the Entity parameter correctly. See later.

Line 93-96: This While construction reads all the found events.

Line 103-187: The Get-MotionHistory function. This function uses the Get-VIEventPlus function to retrieve specific events. The returned events are used to report on all the vMotions and svMotions.

Line 140-145: The function has 3 parametersets, each indicating a specific type of interval (Days/Hours/Minutes). The default is 1 day back in time.

Line 151: Since the function supports pipeline input, the history records it creates must be stored in an array until all pipeline objects have been handled.

Line 152-162: The 3 parametersets are handled with a Switch statement, and the Start parameter for the Get-VIEvent cmdlet is calculated accordingly.

Line 163: For the (s)vMotion history the function only needs these 2 types of events.

Line 171: The vMotion and or svMotion actions can be user invoked or system invoked (DRS/SDRS)

Line 173-176: Depending on the type of ‘motion‘, the functions will include a target host or target datastore.

Sample Usage

The Get-MotionHistory function is quite simple to use as the following example will show.

The content of the produced CSV looks like this.

motion-report1

When you use the Get-MotionHistory take care of what you pass on the Entity parameter !

The following calls will produce the same result.

as this one

But the difference between these two calls of the function is the execution time. The second method was 80 times slower compared to the first method in my test environment, where there are about 100 VMs in that cluster.

The reason is that the Get-VIEventPlus function has to call the EventHistoryCollector for each VM in the 2nd method, while it is only called once in the 1st method !

That is also the main reason I introduced the Recurse parameter on the Get-VIEventPlus function. A feature that is sadly missing on the Get-VIEvent cmdlet 😥

If you want to have a report for a specific set of VMs in a cluster, it is most probably better to call the Get-MotionHistory function for the complete cluster with the Recurse switch set to $true, and filter out the required VMs from the produced result. Something like this for example

Enjoy !

43 Comments

    Ryan Patigayon

    I got blank output in any parameter, so i modified script from practical admin and working with this output.

    Name Created UserName Type SourceHost TargetHost Datacenter

      LucD

      Hi Ryan,
      Not sure what could be causing this.
      Would you mind sharing the code you used to call the function?

    VMware vSphere HA isolation Events - my cloud-(r)evolution

    […] der VMware PowerCLI und dem Get-VIEventPlus Modul von Luc Dekens hat man die Möglichkeit sehr schnell, viele vCenter Events nach dem Event […]

    Surendra Mannepalli

    Dear Luc,

    I have zero knowledge in scripting ,I am sending the script which i am unable execute, please correct that. please mail me and help me.
    My emailid: surendra.windows@gmail.com

    function Get-MotionHistory {
    param(
    [CmdletBinding(DefaultParameterSetName=”Days”)]
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
    [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]$prvm-vcsrv.mcgm.gov.in,
    [Parameter(ParameterSetName=’Days’)]
    [int]$Days = 1,
    [Parameter(ParameterSetName=’Hours’)]
    [int]$Hours,
    [Parameter(ParameterSetName=’Minutes’)]
    [int]$Minutes,
    [switch]$Recurse = $false,
    [switch]$Sort = $true
    )

    param(
    [CmdletBinding(DefaultParameterSetName=”Days”)]
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
    [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]$prvm-vcsrv.mcgm.gov.in,
    [Parameter(ParameterSetName=’Days’)]
    [int]$Days,
    [Parameter(ParameterSetName=’Hours’)]
    [int]$Hours,
    [Parameter(ParameterSetName=’Minutes’)]
    [int]$Minutes,
    [switch]$Recurse = $false,
    [switch]$Sort = $true
    )

    begin{
    $history = @()
    switch($psCmdlet.ParameterSetName){
    ‘Days’ {
    $start = (Get-Date).AddDays(- $Days)
    }
    ‘Hours’ {
    $start = (Get-Date).AddHours(- $Hours)
    }
    ‘Minutes’ {
    $start = (Get-Date).AddMinutes(- $Minutes)
    }
    }
    $eventTypes = “DrsVmMigratedEvent”,”VmMigratedEvent”
    }

    process{
    $history += Get-VIEventPlus -Entity $entity -Start $start -EventType $eventTypes -Recurse:$Recurse |
    Select CreatedTime,
    @{N=”Type”;E={
    if($_.SourceDatastore.Name -eq $_.Ds.Name){“vMotion”}else{“svMotion”}}},
    @{N=”UserName”;E={if($_.UserName){$_.UserName}else{“System”}}},
    @{N=”VM”;E={$_.VM.Name}},
    @{N=”SrcVMHost”;E={$_.SourceHost.Name.Split(‘.’)[0]}},
    @{N=”TgtVMHost”;E={if($_.Host.Name -ne $_.SourceHost.Name){$_.Host.Name.Split(‘.’)[0]}}},
    @{N=”SrcDatastore”;E={$_.SourceDatastore.Name}},
    @{N=”TgtDatastore”;E={if($_.Ds.Name -ne $_.SourceDatastore.Name){$_.Ds.Name}}}
    }

    end{
    if($Sort){
    $history | Sort-Object -Property CreatedTime
    }
    else{
    $history
    }
    }
    }

    At C:\powershell\Get-MotionHistory.ps1:6 char:77
    + [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]$prvm-vcs …
    + ~
    Missing ‘)’ in function parameter list.
    At C:\powershell\Get-MotionHistory.ps1:2 char:28
    + function Get-MotionHistory {
    + ~
    Missing closing ‘}’ in statement block.
    At C:\powershell\Get-MotionHistory.ps1:15 char:3
    + )
    + ~
    Unexpected token ‘)’ in expression or statement.
    At C:\powershell\Get-MotionHistory.ps1:20 char:77
    + [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]$prvm-vcs …
    + ~~~~
    Unexpected token ‘-vcsrv’ in expression or statement.
    At C:\powershell\Get-MotionHistory.ps1:20 char:83
    + … l[]]$prvm-vcsrv.mcgm.gov.in,
    + ~~~~~~~~~~~~
    Unexpected token ‘.mcgm.gov.in’ in expression or statement.
    At C:\powershell\Get-MotionHistory.ps1:20 char:83

    Nick

    How complex would it be to add the end time of the task?

    chris

    Works great, but the reported time is 2 hours behind.

    My vCenter and ESXi has NTP configured and shows the correct time.

    Any guess?

      LucD

      Hi Chris,
      I suspect this due to the fact the vSphere internally stores all events in UTC. When you retrieve them, they come out with a UTC timestamp.
      You can easily change it to your local TZ with

      $_.CreatedTime.ToLocalTime()

      Hope this helps.
      Luc

    Oliver

    Hi, I’m trying to use this against vCenter 6 (tried PowerCLI 5.1/6) and it just gives me no results like it’s not even trying. No error or anything.

    Any ideas?

      LucD

      Sorry to hear that Oliver.
      Would you mind sharing the script with which you call the function ?
      And are there any error messages ?

    Yvan Comte

    Hi Luc

    Quick question. I am trying to use your script to collect (s)vmotion info from 2 different vcenters (I connect at the beginning of the script, then I pass a system.array populated with a list of VM object I read from a csv list of VMs

    foreach ($MyVM in $OSSvm_List) {
    $OSSVM += ($MyVM.Host) }
    get-MotionHistory -Entity (get-vm $OSSVM) -days $Nbr_days

    the problem I have is that I get VM in the $history that are not at all in the import list nor in the system.array variable I pass to your get-MotionHistory fct?

    Any idea?
    Help very much appreciated and thanks the great contribution to the community

      LucD

      Hi,
      Do these extra VMs you are getting back, have a name that is similar to the ones you did pass to the function ?
      For example, you include the VM name VM123, but you also get back VM1234.

        Yvan Comte

        Hi Luc
        No, the returned VM are not in the system array I am passing. When I breakpoint and look at $entity passed (e.g. line 52) I see the correct VM list. Then it process and the output includes VMs that are not required.
        As said I connect to 2 vcenters, but “should” not be an issue. Actually what I do to produce the report is pipe the output of get-MotionHistory liek this:
        Get-MotionHistory -entity (get-VM $OSSVM) -Days $Nbr_days | convertTo-html -head $a -body $b -Title $myTitle | set-content -Path Microsoft.PowerShell.Core\FileSystem::\\spt.swi.srse.net\davwwwroot\it\se\is\vb\reports\OSS_vmotion_report_test.htm

        /yvan

    Stephane

    Thanks a lot lot Luc for the script. Very useful.

    I’d like to get the date including seconds whereas so far I get 08/07/2015 16:30.

    How can this be done ?

    Manuel Risco-Herrera

    I was struggling with Get-VIEevent cmdlet up to a point that I decided to load Onyx. Suddenly, I remembered LucD (and the chances of having a handy module that will save my day)

    I was not wrong, you saved it.

    Thanks heaps dude,

    Manuel

    Carl Sattler

    Thanks for this. Due to the model of my array and the fw on it, I suffer from SVmotion corruption and now that I have disabled VAAI hdwr acceleration, I wanted to learn where I could identify VMs potentially afflicted. This was a silver bullet but I can’t get it to work. I get prompted for:

    InputObject: df233PowerCLI C:\users\adm-sattler\desktop\Useful PS1 commands> .\SVmotions_Get_CSV_rev1.ps1

    cmdlet Export-Csv at command pipeline position 1
    Supply values for the following parameters:
    InputObject: 4
    PowerCLI C:\users\adm…\desktop\Useful PS1 commands>

    and when I open the resulting CSV file, I get two entries in cells: (A1=Length, A2=1):
    | A | B
    1| Length
    2| 1

    Different inputs result different values in A2 but nothing like I would hope for in terms of column headings and useful timedate stamps indicating when migrations and relocations occurred.

    Thanks much

    Carl

      LucD

      Strange, could you forward me the .ps1 file in which you have the script.
      I suspect there might have been some copy/paste errors.

      Use the mail link on the page top-right

        Carl Sattler

        Hi and thanks for replying. I leveraged an onsite admin who is more familiar with PS than I am (not difficult) and he had me load it as a function . .\script and then run the commands and it output as suggested. Thanks again.

        The usecase is that due to a bug in an older fw rev of the array (which with VAAI hdwr acceleration enabled results in corruption), I wanted to look for potentially affected machines that had been relocated (svmotion). This report covers that. It would also be good if I could identify those VMs that have an uptime (since rebooting seems to exhibit corruption symptoms) so if the uptime was > time since svmotion, we could then focus on those VMs and treat with more care.

    JW

    I found this script and would really like to use it but I cam getting an error on line 91 where the $eventCollector is setup, its aborting. Any chance on an updated version for 5.5?.

    Nathan

    Very cool script. Came in very handy. I typically avoid downloading other people’s scripts in my environment, but it really seemed like there wasn’t a better way to accomplish what you are doing here. I was able to expand this very easily to accomplish the task I was looking to do – which was essentially to determine what host a server was located on for a certain date.

      LucD

      Glad it was useful for you

    Anil

    Hello,
    Great it works like a charm,
    But here in my environment all the hosts connected to vCenter with IP addresses, so when i generate the report in the srcVMhost it is showing only 192 instead of full IP address even in dest also. Any thing need to chenge from the script to get the complete IP address.

    Thanks,
    Anil

    Scott

    Thanks LucD,

    This has been very helpful in the past few days as we have MS Auditors wanting to know how many times our SQL Servers have vMotioned in the past 90 days.

    However, I have just noticed that the script doesn’t include DRS relocation event triggered by the Power On virtual machine task. But they have only asked for vMotions so that is ok 🙂

      admin

      Thanks.
      I’ll check if I can include those vMotions as well in the script.

    Yoav Slama

    Thanks for your script but it doesn’t work for me, no matter which parameters i used i always get a blank CSV file, please help me.

    Thanks.

      LucD

      Do you have some more details on what you did ?
      How did you call the function ? From the prompt, from another script ?
      Any error messages ?

        Yoav Slama

        Before i executed the script i added according to your examples another command in the end of the script, for example:
        Get-MotionHistory -Entity (Get-VM VM*) -Days 1 | Export-Csv C:\motion-report1.csv -NoTypeINformation -UseCulture
        After that i executed your script (./ScriptName).
        I also tried all of your examples, and i tried to change their parameters but nothing helped, the output is blank every single time with no errors.
        PowerCLI version: 5.0.1.4431 and 5.5.0.5836 (tried to execute the script on each one of them)
        vCenter version: 4.1 and 5.1 (tried to execute the script on each one of them)

        Thanks for your help!

        Yoav Slama

        I tried to execute the script by adding according to your examples another command in the end of the script, for example:
        Get-MotionHistory -Entity (Get-VM VM*) -Days 1 | Export-Csv C:\motion-report1.csv -NoTypeINformation -UseCulture
        I tried all of your examples, and i also tried to change their parameters but nothing helped, the output is blank every single time with no errors (i executed the script by writing: ./NameOfTheScript.ps1 in the PowerCLI command line).
        PowerCLI version: 5.0.1.4431 and 5.5.0.5836 (i tried to execute the script on each one of them)
        vCenter version: 4.1 and 5.1 (i tried to execute the script on each one of them)

        Thanks for your help!

    Rocky

    From where and how to run these script???????
    What are the pre-requisites??
    How to understand, what needs to be modified??

    Thanks for quick reply

    ranjit

    when i run the “Get-MotionHistory -Entity (Get-VM VM*) -Days 1 |
    Export-Csv C:\motion-report1.csv -NoTypeINformation -UseCulture” it creates blank file.

    Zach

    I keep getting an Input dialog box pop up running the script with :

    Get-Cluster -Name Cluster1 | Get-MotionHistory -Hours 4 -Recurse:$true
    Export-Csv C:\motion-report1.csv -NoTypeINformation -UseCulture

      admin

      Hi Zach,
      Did you pipe the results of the function call to the Export-Csv cmdlet ?
      The vertical bar at the end of the 1st line ?

      Get-Cluster -Name Cluster1 | Get-MotionHistory -Hours 4 -Recurse:$true |
      Export-Csv C:\motion-report1.csv -NoTypeINformation -UseCulture

      If that doesn’t solve the issue, what is the exact message you are seeing ?

    keith

    Great Script! I am able to get everything functioning except the sourcedatastore.name. Any ideas on why it would not populate?

    akamac

    Hi, Luc.
    How can I find out possible values for event type?

    internetrush

    Method invocation failed because [System.Object[]] doesn’t contain a method named ‘CreateCollectorForEvents’.
    At line:57 char:69
    + $eventCollector = Get-View ($eventMgr.CreateCollectorForEvents <<<< ($eventFilter))
    + CategoryInfo : InvalidOperation: (CreateCollectorForEvents:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

    You cannot call a method on a null-valued expression.
    At line:58 char:53
    + $eventsBuffer = $eventCollector.ReadNextEvents <<<< ($eventnumber)
    + CategoryInfo : InvalidOperation: (ReadNextEvents:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

    You cannot call a method on a null-valued expression.
    At line:63 char:39
    + $eventCollector.DestroyCollector <<<< ()
    + CategoryInfo : InvalidOperation: (DestroyCollector:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

    Code does not work when passing a single vm using the most recent powercli

    Matt Andes

    Luc,

    I was playing around with your Get-VIEventPlus function while working on something else and it appears that the CreatedTime property on the events that the function spits out are in UTC.

    Funny thing is that the start and finish date I gave it were in local time and it pulled all of the correct events but the output it gave me had the UTC time which made it weird and was playing havoc with my script because according to the output the last event was after my finish time parameter.

    Is this intended? As a side note I was able to get around this by adding this before you spit out the events on line 65:

    Foreach ($event in $events) {
    $event.CreatedTime = $event.CreatedTime.ToLocalTime()
    }
    $events

      admin

      That is correct, the Tasks and Events when retrieved with a HistoryCollector are indeed returning UTC timestamps.
      I’ll add a switch to the function that allows you to select LocalTime.

    Prabhurj

    Hello LucD,

    Thanks for the Nice script, Get-MotionHistory does not works on powercli version 5.1 release 1 and 2? any alternate version that you suggest?

    Thanks,
    Prabhu

    Methone

    Hello,

    Is it possible to bring svmotion and vMotion History in vCheck

    I really appreciate that

    Best regards

    michael

    @admin

    works perfectly now, thanks!

    michael

    thanks Luc, this script came in very handy for checking an specific issue we had.

    I received the below error but it still provided the results we needed when running:
    Get-Cluster -Name “*cluster*” | Get-MotionHistory -Hours 4 -Recurse:$true

    Exception setting “endTime”: “Cannot convert null to type “System.DateTime”.”
    At C:\vmware\vmotion.ps1:52 char:7
    + $eventFilter.time.endTime = $Finish
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
    + FullyQualifiedErrorId : ExceptionWhenSetting

      admin

      @Michael, it looks as if that was a “feature” in the Get-VIEventPlus function 😉 Nice catch.
      I changed the function slightly, the Finish parameter now has a default value.
      Can you check if that solves your problem ?

    Robert van den Nieuwendijk

    Cool stuff as always. I specially like the Get-VIEventPlus -Recurse parameter.

      LucD

      Thanks Robert.

Leave a Reply

Your email address will not be published. Required fields are marked *

*
*

Buy the Book