PowerCLI

 View Only
Expand all | Collapse all

Who created the Snapshot

LucD

LucDDec 20, 2017 06:35 PM

dlgaines

dlgainesDec 20, 2017 06:41 PM

  • 1.  Who created the Snapshot

    Broadcom Employee
    Posted Jun 19, 2009 11:23 AM

    Any idea how I can relatemy Get-Snapshot information to the Get-VIEvent information to work out who created a snapshot ?

    Thanks

    Alan



  • 2.  RE: Who created the Snapshot
    Best Answer

    Posted Jun 21, 2009 06:58 PM

    Short question but a long answer. In the end I got there.

    There were a few quirks in writing this script.

    1) The Created timestamp in the Event object is not always exactly the same as the time stamp in the VirtualMachine Snapshot property.

    The solution is to use the Task Entity property to get the time stamp of the snapshot.

    2) The Get-ViEvent cmdlet returns a VimApi.ManagedObjectReference instead of a VMware.Vim.ManagedObjectReference.

    As such this is not a big problem since I can easily convert the one MoRef to the other (unfortunately not via casting).

    3) The speed of the Get-ViEvent cmdlet is not ideal compered to the Task Collector form the APIs

    From 2) and 3) I decided to go for the Task Collector methods.

    The flow of the script is quite simple.

    First create a hash table from all tasks that created snapshots on the specific guest.

    The key into the hash table is the name of the guest concatenated with the snapshot creation timestamp.

    Then the script use the Get-Snapshot cmdlet to retrieve the snapshots for the guest.

    From this output a key is constructed and then the key is used to look up the user in the hash table.

    The User property is added to the SnapshotImpl object.

    function Get-SnapshotTree{
    	param($tree, $target)
    	
    	$found = $null
    	foreach($elem in $tree){
    		if($elem.Snapshot.Value -eq $target.Value){
    			$found = $elem
    			continue
    		}
    	}
    	if($found -eq $null -and $elem.ChildSnapshotList -ne $null){
    		$found = Get-SnapshotTree $elem.ChildSnapshotList $target
    	}
    	
    	return $found
    }
    
    $daysBack = 3				        # How many days back from now
    $guestName = <VM-name>		                # The name of the guest
    
    $tasknumber = 999			        # Windowsize of the Task collector
    
    #$serviceInstance = get-view ServiceInstance
    $taskMgr = Get-View TaskManager
    
    # Create hash table. Each entry is a create snapshot task
    $report = @{}
    
    $filter = New-Object VMware.Vim.TaskFilterSpec
    $filter.Time = New-Object VMware.Vim.TaskFilterSpecByTime
    $filter.Time.beginTime = (Get-Date).AddDays(-$daysBack)
    $filter.Time.timeType = "startedTime"
    
    $collectionImpl = Get-View ($taskMgr.CreateCollectorForTasks($filter))
    
    $dummy = $collectionImpl.RewindCollector
    $collection = $collectionImpl.ReadNextTasks($tasknumber)
    while($collection -ne $null){
    	$collection | where {$_.DescriptionId -eq "VirtualMachine.createSnapshot" -and $_.State -eq "success" -and $_.EntityName -eq $guestName} | %{
    		$row = New-Object PsObject
    		$row | Add-Member -MemberType NoteProperty -Name User -Value $_.Reason.UserName
    		$vm = Get-View $_.Entity
            $snapshot = Get-SnapshotTree $vm.Snapshot.RootSnapshotList $_.Result
    		$key = $_.EntityName + "&" + ($snapshot.CreateTime.ToString())
    		$report[$key] = $row
    	}
    	$collection = $collectionImpl.ReadNextTasks($tasknumber)
    }
    $collectionImpl.DestroyCollector()
    
    # Get the guest's snapshots and add the user
    $snapshotsExtra = Get-VM $guestName | Get-Snapshot | % {
    	$key = $_.vm.Name + "&" + ($_.Created.ToString())
    	if($report.ContainsKey($key)){
    		$_ | Add-Member -MemberType NoteProperty -Name User -Value $report[$key].User
    	}
    	$_
    }
    
    $snapshotsExtra | Export-Csv "C:\SnapshotsExtra.csv" -NoTypeInformation -UseCulture
    

    Note1: the -UseCulture parameter on the Export-Csv cmdlet is PS v2 CTP3

    Note2: it shouldn't be too difficult to convert the script to handle all guests instead of just one. The name of the guest is already in the key in the hash table.



  • 3.  RE: Who created the Snapshot

    Broadcom Employee
    Posted Jun 22, 2009 09:45 AM

    Luc, is there nothing you can not do ?!

    Thanks very much, I managed to adapt your code to allow me to create a function for this info.

    
    function Get-SnapshotTree{
    	param($tree, $target)
    	
    	$found = $null
    	foreach($elem in $tree){
    		if($elem.Snapshot.Value -eq $target.Value){
    			$found = $elem
    			continue
    		}
    	}
    	if($found -eq $null -and $elem.ChildSnapshotList -ne $null){
    		$found = Get-SnapshotTree $elem.ChildSnapshotList $target
    	}
    	
    	return $found
    }
    
    function Get-SnapshotExtra ($snap){
    	#$daysBack = 5			# How many days back from now
    	$guestName = $snap.VM	# The name of the guest
    	
    
    	$tasknumber = 999		# Windowsize of the Task collector
    	
    	#$serviceInstance = get-view ServiceInstance
    	$taskMgr = Get-View TaskManager
    	
    	# Create hash table. Each entry is a create snapshot task
    	$report = @{}
    	
    	$filter = New-Object VMware.Vim.TaskFilterSpec
    	$filter.Time = New-Object VMware.Vim.TaskFilterSpecByTime
    	$filter.Time.beginTime = (($snap.Created).AddSeconds(-5))
    	$filter.Time.timeType = "startedTime"
    	
    	$collectionImpl = Get-View ($taskMgr.CreateCollectorForTasks($filter))
    	
    	$dummy = $collectionImpl.RewindCollector
    	$collection = $collectionImpl.ReadNextTasks($tasknumber)
    	while($collection -ne $null){
    		$collection | where {$_.DescriptionId -eq "VirtualMachine.createSnapshot" -and $_.State -eq "success" -and $_.EntityName -eq $guestName} | %{
    			$row = New-Object PsObject
    			$row | Add-Member -MemberType NoteProperty -Name User -Value $_.Reason.UserName
    			$vm = Get-View $_.Entity
    			$snapshot = Get-SnapshotTree $vm.Snapshot.RootSnapshotList $_.Result
    			$key = $_.EntityName + "&" + ($snapshot.CreateTime.ToString())
    			$report[$key] = $row
    		}
    		$collection = $collectionImpl.ReadNextTasks($tasknumber)
    	}
    	$collectionImpl.DestroyCollector()
    	
    	# Get the guest's snapshots and add the user
    	$snapshotsExtra = $snap | % {
    		$key = $_.vm.Name + "&" + ($_.Created.ToString())
    		if($report.ContainsKey($key)){
    			$_ | Add-Member -MemberType NoteProperty -Name Creator -Value $report[$key].User
    		}
    		$_
    	}
    	$snapshotsExtra
    }
    
    $Snapshots = Get-VM | Get-Snapshot | Where {$_.Created -lt ((Get-Date).AddDays(-14))} 
    
    $mySnaps = @()
    foreach ($snap in $Snapshots){
    	$SnapshotInfo = Get-SnapshotExtra $snap
    	$mySnaps += $SnapshotInfo
    }
    
    $mySnaps | Select VM, Name, Creator, Description
    
    
    

    If you found this information useful, please consider awarding points for Correct or Helpful.

    Alan Renouf

    http://virtu-al.net



  • 4.  RE: Who created the Snapshot

    Posted Jun 22, 2009 09:52 AM

    It's the combined strength of PowerShell, PowerCLI and the SDK that allows me to do this kind of stuff.

    They are the instruments, I'm just the conductor :smileywink:

    Nice adaption to a general function btw.



  • 5.  RE: Who created the Snapshot

    Posted Feb 02, 2011 07:29 PM

    Ok, so I have a question.  I know that this is a bit of an old topic, but why create a filter for the TaskCollector, and then not specify all the relevant filters.  I.e. you specify start time, but then don't filter on state, entity, or end time.  The only reason I bring it up is that I was running this in the snapreminder.ps1 script, and a couple of very old snapshots brought huge performance problems by bringing up hundreds of records since then. 



  • 6.  RE: Who created the Snapshot

    Posted Feb 02, 2011 07:39 PM

    Basically I did that for performance reasons, the more complex the filter, the longer it will take.

    But you are of course right.

    • We should have used the TaskState -eq "success". No point in retrieving failed snapshot tasks
    • Entity is handy when you want to limit the filter to a specific branch (datacenter, folder, cluster, host...) in your vSphere environment. With the RecursionOption you can easily state for which entities you want to retrieve the tasks

    In the mean time the performance of the Get-VIEvent cmdlet has improved. So you could even consider using the cmdlet instead of the collector. Just filter on TaskEvent.



  • 7.  RE: Who created the Snapshot

    Broadcom Employee
    Posted Feb 02, 2011 07:43 PM

    You can always specify more filter properties to narrow down your search.

    If it fits you, use it as it will return lesser objects to filter out afterwards and improve performance.

    Don't know why there weren't any additional properties in the code though.



  • 8.  RE: Who created the Snapshot

    Posted Feb 02, 2011 08:04 PM

    Thanks for the suggestion, I'll try reworking it with the Get-Event.  However, I'd like to finish out the thought exercise.  I was trying to do this:

        $filter = New-Object VMware.Vim.TaskFilterSpec

        $filter.Time = New-Object VMware.Vim.TaskFilterSpecByTime

        $filter.Time.beginTime = (($snap.Created).AddSeconds(-5))

        $filter.Time.timeType = "startedTime"

        $filter.State = "success"

        $filter.Entity = New-Object VMware.Vim.TaskFilterSpecByEntity

        $filter.Entity.recursion = "self"

        $filter.Entity.entity = Get-Vm -Name $snap.VM.Name | Get-View | Get-VIObjectByVIView

    but get the following error

    Get-VIObjectByVIView : 2/2/2011 1:53:20 PM    Get-VIObjectByVIView        Object reference not set to an instance of an object.   
    At C:\scripts\snapreminder.ps1:59 char:89
    +     $filter.Entity.entity = Get-Vm -Name $snap.VM.Name | Get-View | Get-VIObjectByVIView <<<<
        + CategoryInfo          : NotSpecified: (:) [Get-VIObjectByVIView], VimException
        + FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.DotNetInterop.GetVIObjectByVIViewCommand

    Any ideas on what I am doing wrong?



  • 9.  RE: Who created the Snapshot

    Posted Feb 02, 2011 08:09 PM

    The property Entity needs a MoRef.

    Try replacing this line

    $filter.Entity.entity = Get-Vm -Name $snap.VM.Name | Get-View |  Get-VIObjectByVIView

    by this

    $filter.Entity.entity = (Get-Vm -Name $snap.VM.Name).Extensiondata.MoRef


  • 10.  RE: Who created the Snapshot

    Posted Feb 02, 2011 08:29 PM

    That worked great.  But it looks like I've run into some time based problems....

    when I get to the end of the Get-SnapshotExtra, where it's trying to see if the find the VM+Snapshot creation time in the map,

       # Get the guest's snapshots and add the user

        $snapshotsExtra = $snap | % {

            $key = $_.vm.Name + "&" + ($_.Created.ToString())

            if($report.ContainsKey($key)){

                $_ | Add-Member -MemberType NoteProperty -Name Creator -Value $report[$key].User

            }

            $_

    if I output the value of $key and $report it shows:

    [DBG]: PS C:\Users\admin.ccc>>> $key
    FSBUS&1/8/2011 5:00:44 PM
    ____________________________________________________________________________________________________________________________________________________________________________________________________________________
    [DBG]: PS C:\Users\admin.ccc>>> $report
    Name                           Value                                                                                                                                                                                  
    ----                           -----                                                                                                                                                                                  
    FSBUS&1/8/2011 11:00:44 PM     @{User=ICXT\svc.scripts}

    Now, since we are in Central time zone, the 6 hour difference *kind* of makes sense, but is there away to determine what TZ the data was in, and adjust it before we convert it to the string to put in the tables?

    Thanks for all the help, you've been extremely considerate.



  • 11.  RE: Who created the Snapshot

    Posted Feb 02, 2011 08:34 PM

    Those timestamp are kept in UTC.

    You can easily convert to your localtime like this

    $_.Created.ToLocalTime()


  • 12.  RE: Who created the Snapshot

    Posted Feb 03, 2011 08:46 PM

    Ok, I took all the changes, added in some of the parts from list_snapshots_v6.ps1, and have the one below.

    Creates a list of snapshots, identifies who created them, and emails the owners about them, as well as emailing you a summary.

    Next step is to add a custom field to VMs allowing them to be excluded from this reporting.



  • 13.  RE: Who created the Snapshot

    Posted Feb 24, 2011 10:17 AM

    Hi.

    This script is very helpful for me but i have a little problem with the creator information. We have VMs who have 2 days old snapshots and the script shows under "Created by" Unknown Creator. Has someone an idea why this information isn't shown there?

    Thanks for help

    ron999



  • 14.  RE: Who created the Snapshot

    Posted Aug 11, 2011 11:50 PM

    Very cool.  I've spent most of the day searching/trying scripts to do this, and yours is the best, and *almost* perfect for what I'm looking for:

    - would it be easy enough to add the snapshot size to the email and summary?

    - if the snapshot owner is not determined (returns "unknown owner"), do I understand correctly that you attempt to find that  information in the VC task list?

    - if the owner is determined, how is the email address determined from DOMAIN\Owner?  Would it be possible to extract Owner and append the email domain name, e.g.  from DOMAIN\Owner  => Owner@mydomain.com?

    Did you ever complete the "next step" you mention for exclude VMs from the report?



  • 15.  RE: Who created the Snapshot

    Posted Sep 07, 2011 08:44 PM

    It would seem all/any snapshots the owner is unknown.   Any idea why this would be?



  • 16.  RE: Who created the Snapshot

    Posted Sep 07, 2011 10:41 PM

    The script tries to macth the Event, which holds the creator information, with a snapshot based on the timestamp availble on the snapshot and in the event.

    I noticed that sometimes these timestamps might differ with a couple of seconds.

    A solution would be to not look for an exact match of the timestamp, but look for an event that is "close enough". For example a couple of seconds before and after the snapshot create time.

    This poses a certain risk of matching the wrong event with the snapshot, but that can be avoided by adding an additional test, for example for the VM name. It's highly unlikely that you have 2 snapshots for the same VM in a matter of seconds.



  • 17.  RE: Who created the Snapshot

    Posted Sep 07, 2011 10:51 PM

    Agreed - but *how* to do this?   Looking through the script, I see this seemingly relevant function:

    function Get-SnapshotExtra ($snap)
    {
        $guestName = $snap.VM   # The name of the guest

        $tasknumber = 999       # Windowsize of the Task collector

        $taskMgr = Get-View TaskManager

        # Create hash table. Each entry is a create snapshot task
        $report = @{}

        $filter = New-Object VMware.Vim.TaskFilterSpec
        $filter.Time = New-Object VMware.Vim.TaskFilterSpecByTime
        $filter.Time.beginTime = (($snap.Created).AddSeconds(-5))
        $filter.Time.timeType = "startedTime"
        $filter.State = "success"
        $filter.Entity = New-Object VMware.Vim.TaskFilterSpecByEntity
        $filter.Entity.recursion = "self"
        $filter.Entity.entity = (Get-Vm -Name $snap.VM.Name).Extensiondata.MoRef

        $collectionImpl = Get-View ($taskMgr.CreateCollectorForTasks($filter))

        $dummy = $collectionImpl.RewindCollector
        $collection = $collectionImpl.ReadNextTasks($tasknumber)
        while($collection -ne $null){
            $collection | where {$_.DescriptionId -eq "VirtualMachine.createSnapshot" -and $_.State -eq "success" -and $_.EntityName -eq $guestName} | %{
                $row = New-Object PsObject
                $row | Add-Member -MemberType NoteProperty -Name User -Value $_.Reason.UserName
                $vm = Get-View $_.Entity
                $snapshot = Get-SnapshotTree $vm.Snapshot.RootSnapshotList $_.Result
                if ( $snapshot -ne $null)
                {
                    $key = $_.EntityName + "&" + ($snapshot.CreateTime.ToLocalTime().ToString())
                    $report[$key] = $row
                }
            }
            $collection = $collectionImpl.ReadNextTasks($tasknumber)
        }
        $collectionImpl.DestroyCollector()

        # Get the guest's snapshots and add the user
        $snapshotsExtra = $snap | % {
            $key = $_.vm.Name + "&" + ($_.Created.ToLocalTime().ToString())
            if($report.ContainsKey($key)){
                $_ | Add-Member -MemberType NoteProperty -Name Creator -Value $report[$key].User
                write-host $report[$key].User is creator of $key
               
            }
            $_
        }
        $snapshotsExtra
    }

    Isn't this already adjusting by 5 seconds?  This still seems like it's testing for a specific time.  Is there a better way to do this so that I can find an entry, say +/- 10 seconds?



  • 18.  RE: Who created the Snapshot

    Posted Sep 08, 2011 12:02 AM

    It reads the events starting 5 seconds before the create time it gets from the snapshot.

    But later on it calculates a key, containing the time from the event, for the hashtable

    $key = $_.EntityName + "&" + ($snapshot.CreateTime.ToLocalTime().ToString())

    which it then later on uses the time from the snapshot to create a new key which it uses to check if there is an antry with that key in the hash table.

    if($report.ContainsKey($key)){

    What you could do is round the time in the key to for example a 10 seconds interval.

    In other words, these time values, 21:17:10/21:17:14/21:17:19, would all become 21:17:10.

    This is still not a 100% foolproof solution but should produce better matches between the create time from the snapshot and the event time.

    PS: you could of course allso end up with "unknow" creators because that property is simply not there in the event.

    I have seen that happen also a couple of times.



  • 19.  RE: Who created the Snapshot

    Posted Sep 08, 2011 12:24 AM

    Sounds good.  How do I go about rounding the time in the key then?

    (thanks so much for your knowledge and willingness to help!)



  • 20.  RE: Who created the Snapshot

    Posted Sep 08, 2011 05:40 PM

    As shown here:

    The snapshot event/tasks on the VM shows created at 12:51:35 PM (by VOP\JHerold) and the snapshot reminder shows created at 12:52:18 PM but Unknown Creator.  Shouldn't the code have picked this up?

    UPDATE:

    Since the difference in time was 43 seconds, I simply changed -5 to -60 (within 1 minute) and it now identifies the Creator owner - yay!



  • 21.  RE: Who created the Snapshot

    Posted Sep 08, 2011 07:40 PM

    On a busy vCenter the timestamp difference between the action (snapshot in this case) and the corresponding event timestamp can be relatively big. But this is the first time I see such a huge difference.



  • 22.  RE: Who created the Snapshot

    Posted Sep 08, 2011 11:11 PM

    Interesting to note - that my vCenter is an outlier - something for me to investigate.



  • 23.  RE: Who created the Snapshot

    Posted May 15, 2012 04:10 PM

    Great thread!

    Anyone know how difficult it would be to convert this script to perl?



  • 24.  RE: Who created the Snapshot

    Posted May 15, 2012 04:13 PM

    I think you better ask that in the CLI Community.

    William probably already has a Perl script for that :smileywink:



  • 25.  RE: Who created the Snapshot

    Posted Dec 27, 2017 08:10 AM

    LucD​ is it possible using this to look for snapshot creator that was 2-3 months back?



  • 26.  RE: Who created the Snapshot

    Posted Dec 27, 2017 08:16 AM

    Depends how long Task and Events are kept in your vCenter.

    The default is 1 year, in that case, yes, you should be able to find the creator.



  • 27.  RE: Who created the Snapshot

    Posted Jun 13, 2018 05:21 AM

    LudD, is there any where to tweak this?

    i found out my environment might be holding shorter timespan as i could not get a creator of snapshot although the script able to list any VMs which has snapshot.



  • 28.  RE: Who created the Snapshot

    Posted Jun 13, 2018 05:42 AM

    I'm afraid not, afaik.



  • 29.  RE: Who created the Snapshot

    Posted Jun 13, 2018 07:53 AM

    the thing it is able to get the vm snapshot creation details except creator makes me wonder, why.

    if you found anywhere, please give a shout

    thanks



  • 30.  RE: Who created the Snapshot

    Posted Feb 03, 2011 04:44 PM

    Awesome.  I had been messing w/ this for awhile trying to figure out best method.  Thanks as always.



  • 31.  RE: Who created the Snapshot

    Posted Aug 12, 2011 12:16 AM

    Wow, this is so cool guys an all star thread :-)

    thanks guys.



  • 32.  RE: Who created the Snapshot

    Posted May 16, 2012 03:31 PM

    is this script still functional on powerCLI 5.0.1? connecting to our 4.1 U2 vCenter servers produces the below errors.

    thanks

    Method invocation failed because [System.Object[]] doesn't contain a method named 'CreateCollectorForTasks'.
    At test.ps1:37 char:66
    +      $collectionImpl = Get-View ($taskMgr.CreateCollectorForTasks <<<< ($filter))
        + CategoryInfo          : InvalidOperation: (CreateCollectorForTasks:String) [], RuntimeException
        + FullyQualifiedErrorId : MethodNotFound

    You cannot call a method on a null-valued expression.
    At test.ps1:40 char:49
    +      $collection = $collectionImpl.ReadNextTasks <<<< ($tasknumber)
        + CategoryInfo          : InvalidOperation: (ReadNextTasks:String) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull

    You cannot call a method on a null-valued expression.
    At test.ps1:52 char:38
    +      $collectionImpl.DestroyCollector <<<< ()
        + CategoryInfo          : InvalidOperation: (DestroyCollector:String) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull



  • 33.  RE: Who created the Snapshot

    Posted May 16, 2012 04:04 PM

    It looks as if you're connected to multiple vSPhere servers. (check by displaying $defaultVIServers)

    In that case Get-View TaskManager will return an array of TaskManager objects.

    Can you try while connected to 1 vCenter ?



  • 34.  RE: Who created the Snapshot

    Posted May 16, 2012 04:33 PM

    thanks LucD, i tested while only connected to one VC and the errors changed a bit

    You cannot call a method on a null-valued expression.
    At c:\test.ps1:44 char:62
    +         $key = $_.EntityName + "&" + ($snapshot.CreateTime.ToString <<<< ())
        + CategoryInfo          : InvalidOperation: (ToString:String) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull

    Index operation failed; the array index evaluated to null.
    At c:\test.ps1:45 char:11
    +         $report[ <<<< $key] = $row
        + CategoryInfo          : InvalidOperation: (System.Collections.Hashtable:Hashtable) [], RuntimeException
        + FullyQualifiedErrorId : NullArrayIndex



  • 35.  RE: Who created the Snapshot

    Posted May 16, 2012 04:57 PM

    It looks as if the $snapshot variable contains $null.

    Are you using Alan's version of the script (2nd post in this thread) ?



  • 36.  RE: Who created the Snapshot

    Posted May 16, 2012 05:11 PM

    Afraid I get the same result on both versions.

    If i run a simple 'get-vm | get-snapshot' from the same powerCLI window, I  get results returned.

    also tried from a powerCLI session on one of the vCenter servers.



  • 37.  RE: Who created the Snapshot

    Posted May 16, 2012 05:26 PM

    The problem you seem to be having is not with the Get-SNapshot cmdlet, but with the ability to find the event that corresponds with the creation of the snapshot.

    The function only looks at the events from the last 5 days.

    Are you testing with a VM that only has snapshots created during the last 5 days ?



  • 38.  RE: Who created the Snapshot

    Posted May 16, 2012 05:31 PM

    aye, snapshot was created today.



  • 39.  RE: Who created the Snapshot

    Posted Feb 28, 2013 06:55 PM

    I run this script but it just comes back showing nothing. I have snapshots that I created but I get no email.Is there seomthign that needs to be changed for 5.0?



  • 40.  RE: Who created the Snapshot

    Posted Feb 28, 2013 07:00 PM

    The original script writes the results to a CSV file, there is no mail being sent.

    Which script are you using ?



  • 41.  RE: Who created the Snapshot

    Posted Feb 28, 2013 07:06 PM

    # - SnapReminder V1.0 By Virtu-Al - http://virtu-al.net

    #

    # Please use the below variables to define your settings before use

    #

    $smtpServer = "SMTPServerName"

    $MailFrom = "EmailAddress"

    $VISRV = "vCernterServer"

    function Get-SnapshotExtra ($snap)

    {

        $guestName = $snap.VM   # The name of the guest

        $tasknumber = 999       # Windowsize of the Task collector

        $taskMgr = Get-View TaskManager

        # Create hash table. Each entry is a create snapshot task

        $report = @{}

        $filter = New-Object VMware.Vim.TaskFilterSpec

        $filter.Time = New-Object VMware.Vim.TaskFilterSpecByTime

        $filter.Time.beginTime = (($snap.Created).AddSeconds(-5))

        $filter.Time.timeType = "startedTime"

        $filter.State = "success"

        $filter.Entity = New-Object VMware.Vim.TaskFilterSpecByEntity

        $filter.Entity.recursion = "self"

        $filter.Entity.entity = (Get-Vm -Name $snap.VM.Name).Extensiondata.MoRef

        $collectionImpl = Get-View ($taskMgr.CreateCollectorForTasks($filter))

        $dummy = $collectionImpl.RewindCollector

        $collection = $collectionImpl.ReadNextTasks($tasknumber)

        while($collection -ne $null){

            $collection | where {$_.DescriptionId -eq "VirtualMachine.createSnapshot" -and $_.State -eq "success" -and $_.EntityName -eq $guestName} | %{

                $row = New-Object PsObject

                $row | Add-Member -MemberType NoteProperty -Name User -Value $_.Reason.UserName

                $vm = Get-View $_.Entity

                $snapshot = Get-SnapshotTree $vm.Snapshot.RootSnapshotList $_.Result

                if ( $snapshot -ne $null)

                {

                    $key = $_.EntityName + "&" + ($snapshot.CreateTime.ToLocalTime().ToString())

                    $report[$key] = $row

                }

            }

            $collection = $collectionImpl.ReadNextTasks($tasknumber)

        }

        $collectionImpl.DestroyCollector()

        # Get the guest's snapshots and add the user

        $snapshotsExtra = $snap | % {

            $key = $_.vm.Name + "&" + ($_.Created.ToLocalTime().ToString())

            if($report.ContainsKey($key)){

                $_ | Add-Member -MemberType NoteProperty -Name Creator -Value $report[$key].User

                write-host $report[$key].User is creator of $key

            }

            $_

        }

        $snapshotsExtra

    }

    Function SnapMail ($Mailto, $snapshot)

    {

          $msg = new-object Net.Mail.MailMessage

          $smtp = new-object Net.Mail.SmtpClient($smtpServer)

          $msg.From = $MailFrom

          $msg.To.Add($Mailto)

          $msg.Subject = "Snapshot Reminder"

    $MailText = @"

    This is a reminder that you have a snapshot active on $($snapshot.VM) which was taken on $($snapshot.Created).

    Name: $($snapshot.Name)

    Description: $($snapshot.Description)

    "@

          $msg.Body = $MailText

          $smtp.Send($msg)

    }

    Connect-VIServer $VISRV

    foreach ($snap in (Get-VM | Get-Snapshot | Where {$_.Created -lt ((Get-Date).AddDays(-14))})){

          $SnapshotInfo = Get-SnapshotExtra $snap

          $mailto = ((Find-User $SnapshotInfo.Creator).Properties.mail)

          SnapMail $mailto $SnapshotInfo

    }



  • 42.  RE: Who created the Snapshot

    Posted Feb 28, 2013 07:32 PM

    It looks as you're missing the Find-User function. Did you get the script from SnapReminder ?

    Also note that this script will send an email to the users that created the snapshots, not necessarily the person who is running the script



  • 43.  RE: Who created the Snapshot

    Posted Feb 28, 2013 07:38 PM

    I got this from the SnapReminder you referenced. I created a bunch of snapshots with my username so although Iam running the script it should find and email me about mine. What part is missing?



  • 44.  RE: Who created the Snapshot

    Posted Feb 28, 2013 07:41 PM

    Did you create those snapshots longer than 14 days ago ?

    The script checks if the snapshot's creation date is more than 14 days ago.



  • 45.  RE: Who created the Snapshot

    Posted Feb 28, 2013 07:53 PM

    No.



  • 46.  RE: Who created the Snapshot

    Posted Feb 28, 2013 07:53 PM

    In fact what I was hoping to do with this was to run it as a scheduled task that would email users of their snapshots daily.



  • 47.  RE: Who created the Snapshot

    Posted Feb 28, 2013 08:01 PM

    I downloaded the script again, modified the script to 1 day:

    104 foreach ($snap in (Get-VM | Get-Snapshot | Where {$_.Created -lt ((Get-Date).AddDays(-1))})){

    It seems so have found things now. The only error I get now has to do with the emailing.

    Exception calling "Add" with "1" argument(s): "Value cannot be null.
    Parameter name: item"
    At C:\scripts\SnapshotEmail.ps1:86 char:13
    +     $msg.To.Add <<<< ($Mailto)
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : DotNetMethodException
    Exception calling "Send" with "1" argument(s): "A recipient must be specified."
    At C:\scripts\SnapshotEmail.ps1:99 char:12
    +     $smtp.Send <<<< ($msg)
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : DotNetMethodException


  • 48.  RE: Who created the Snapshot

    Posted Feb 28, 2013 08:04 PM

    It looks as if the $MailTo variable is empty when the script tries to add it to the recipients of the email.

    That could be because the script couldn't find the owner of the snapshot or the Find-User function is not returning the email address of the snapshot creator.



  • 49.  RE: Who created the Snapshot

    Posted Apr 23, 2015 08:37 AM

    Hello folks.

    I get the same exceptions mentioned in Post #41. But I couldn't figure out why the $MailTo variable is empty. I tried to locate the error an it seems to, that the function Get-SnapshotExtra doesn't return a prober value for $SnapshotInfo.

    I'm very new to PowerCLI. Could somebody help me to figure out, wether the function Get-SnapshotExtra works or not? What do I have to do?

    Best Regards.

    Trondesson



  • 50.  RE: Who created the Snapshot

    Posted Apr 23, 2015 01:56 PM

    Hi.

    I tried to run the script step by step in a PowerCLI to see what's going wrong.

    I got an exception in the Get-SnapshotExtra($snap)-function.

    PowerCLI C:\Scripts> $key

    UHRZ-Ubuntu-E01&22.04.2015 15:51:54

    PowerCLI C:\Scripts> $_ | Add-Member -MemberType NoteProperty -Name Creator -Value $report[$key].User

    Add-Member : Das Argument kann nicht an den Parameter "InputObject" gebunden werden, da es NULL ist.

    In Zeile:1 Zeichen:6

    + $_ | Add-Member -MemberType NoteProperty -Name Creator -Value $report[$key].User

    +      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        + CategoryInfo          : InvalidData: (:) [Add-Member], ParameterBindingValidationException

        + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.AddMemberCommand

    PowerCLI C:\Scripts> $report[$key].User

    PowerCLI C:\Scripts>

    I guess there is somethin wrong witth $report[$key].User which has no value.

    Can someone help me with that?



  • 51.  RE: Who created the Snapshot

    Posted May 14, 2015 07:00 PM

    LucD,


    When I run this script in my vCenter 5.5 environment on a VM that had a snapshot created today, I don't get the 'created' by value returned. I see the username in the VI event within the VM's event tab but the field is not being output into the spreadsheet. I have even ran it in sections to make sure things are getting populated and it seems like everything is there but the user entry.



  • 52.  RE: Who created the Snapshot

    Posted May 14, 2015 07:21 PM

    I suggest you try the final script Alan posted on the subject, see his PowerCLI: SnapReminder post.

    Even if you don't need the email, the function to find the snapshot information in the events is better



  • 53.  RE: Who created the Snapshot

    Posted Apr 27, 2017 07:51 AM

    Hi LucD,

    Is the script you shared is able to retrieve the creator of snapshot even when this doesnt even listed in task\event in particular vm?

    Sometimes i observed in the event\task it cant capture who was the creator of the snapshot.

    Any reason of this? is it because the snapshot was created more than time it permissable to list in task\event?



  • 54.  RE: Who created the Snapshot

    Posted Apr 27, 2017 08:02 AM

    The UserName is sometimes present in the event.
    Afaik it depends on who or what created the snapshot (Web Client, vSphere Client, CLI, PowerCLI...) if the UserName is there or not.
    But to my knowledge there is no clear statement/document that explains what are the exact conditions to have the UserName in the Event or not.



  • 55.  RE: Who created the Snapshot

    Posted Dec 20, 2017 03:48 PM

    I can run the script without getting any errors but i do not get an email with the reminder to delete. I've confirmed the vcenter server and the SMTP server are correct. I have a snapshot that was created a few days ago and it's checking for snapshots created in the last 14 days so it should see it.The script runs and completes but I see no results. Any suggestions?



  • 56.  RE: Who created the Snapshot

    Posted Dec 20, 2017 04:22 PM

    Can the script resolve your AD account from the account you use in vSphere to create the snapshot?



  • 57.  RE: Who created the Snapshot

    Posted Dec 20, 2017 04:30 PM

    I don't know how to check that but I know that the AD account I use to login to vcenter has my email address associated with it.



  • 58.  RE: Who created the Snapshot

    Posted Dec 20, 2017 05:35 PM

    If you run the script in the ISE or in VSC, you could check the content of the variable $mailto.

    That should hold your email address.

    Another possible issue might be that your SMTP server only accepts connections from specific servers.

    Can you check with a simple Send-MailMessage if the mail arrives in your mailbox?



  • 59.  RE: Who created the Snapshot

    Posted Dec 20, 2017 06:07 PM

    I ran "get-variable -name $mailto" and it returned "Cannot validate argument on parameter 'Name'. The argument is null." I'm assuming there is a way I can view the content from within the running script to get the actual email of the snapshot creator but I don't know how.

    I was able to do a simple send-mailmessage using the same smtp server and I get the email.



  • 60.  RE: Who created the Snapshot

    Posted Dec 20, 2017 06:35 PM

    The name should mailto, not $mailto



  • 61.  RE: Who created the Snapshot

    Posted Dec 20, 2017 06:41 PM

    Here's what i get with that.



  • 62.  RE: Who created the Snapshot

    Posted Dec 20, 2017 06:44 PM

    So there is no content after your ran the script?

    That probably explains why the email doesn't arrive



  • 63.  RE: Who created the Snapshot

    Posted Dec 20, 2017 06:53 PM

    Do you know how I can check why it would have no value?



  • 64.  RE: Who created the Snapshot

    Posted Dec 20, 2017 06:57 PM

    First I would need to see the exact script you are using (there are quite a bit of variations in this thread).

    Can you attach the .ps1 file (take out or mask all the confidential info that might be in there).



  • 65.  RE: Who created the Snapshot

    Posted Dec 20, 2017 07:06 PM

    It's an exact copy and paste from this site http://www.virtu-al.net/featured-scripts/snapreminder/

    The only values that have changed are the SMTP, MailFrom, and VISrv on lines 5-7 to match what we have in our environment.



  • 66.  RE: Who created the Snapshot

    Posted Dec 20, 2017 07:42 PM

    Ok, in the following replace my accountname with yours (only the account, not the domain).

    Then check if the mail address is returned.

    $usr = 'lucd'

    $root = [ADSI]""

    $filter = ("(&(objectCategory=user)(samAccountName=$Usr))")

    $ds = New-Object system.DirectoryServices.DirectorySearcher($root,$filter)

    $ds.PageSize = 1000

    $info = $ds.FindOne()

    $info | Select @{N='User';E={$_.Properties.name}},@{N='Mail';E={$_.Properties.mail}}



  • 67.  RE: Who created the Snapshot

    Posted Dec 20, 2017 07:52 PM

    It looks like you're referencing lines 12-17. Do I also need to add this line?

    $info | Select @{N='User';E={$_.Properties.name}},@{N='Mail';E={$_.Properties.mail}}

    And then replace line 17 with this line?

    $info = $ds.FindOne()

    Edit: After running it with just changing the username name I still have a empty value in the mailto variable.



  • 68.  RE: Who created the Snapshot

    Posted Dec 20, 2017 07:55 PM

    No, no, this is a stand-alone script to check if your email address is returned correctly from the AD search



  • 69.  RE: Who created the Snapshot

    Posted Dec 20, 2017 08:00 PM

    That script returned "Exception calling "FindOne" with "0" argument(s): "The specified domain either does not exist or could not be contacted."



  • 70.  RE: Who created the Snapshot

    Posted Dec 20, 2017 08:13 PM

    Does this return your AD domain?

    ([ADSI]"").distinguishedName



  • 71.  RE: Who created the Snapshot

    Posted Dec 20, 2017 08:25 PM

    It ran but did not return anything.



  • 72.  RE: Who created the Snapshot

    Posted Dec 20, 2017 08:40 PM

    Did you logon to an AD domain?
    Or are you working form a stand-alone station?



  • 73.  RE: Who created the Snapshot

    Posted Dec 20, 2017 08:43 PM

    I logon to an AD domain.



  • 74.  RE: Who created the Snapshot

    Posted Dec 20, 2017 08:56 PM

    Does this make a difference?

    $usr = 'lucd'

    $filter = ("(&(objectCategory=user)(samAccountName=$Usr))")

    $ds = New-Object system.DirectoryServices.DirectorySearcher($filter)

    $ds.PageSize = 1000

    $info = $ds.FindOne()

    $info | Select @{N='User';E={$_.Properties.name}},@{N='Mail';E={$_.Properties.mail}}



  • 75.  RE: Who created the Snapshot

    Posted Dec 20, 2017 09:00 PM

    I get the same error as before.



  • 76.  RE: Who created the Snapshot

    Posted Dec 20, 2017 09:12 PM

    I'm afraid I'm at my wit's end for now.

    The issue with the missing email is obviously due to the fact that the email address can't be obtained from AD.

    Not sure why right now.

    Do your AD admins perhaps have some code that is able to retrieve user info from AD



  • 77.  RE: Who created the Snapshot

    Posted Dec 20, 2017 09:25 PM

    I really appreciate your time spent helping me. I can ask to see if that would be possible to do. I'll update if I can get it working.