VMware Cloud Community
SteveCSchofield
Enthusiast
Enthusiast

snapshot reminder notification advice

PowerCLI newbie...

1) I've been attempting to use the snapshot reminder script posted @ http://www.virtu-al.net.   I've been unable to get the script to work with vSphere 5.5.  It's not finding the user or adding the user to the object in the function below.  Is there another property that has the user who created the snap?

2) I'm curious in the function below an object is NOT returned instead it sets the variable $snapshotsExtra.  Does this make the data available outside the function scope?

Here is the function that isn't populating NoteProperty property

function Get-SnapshotExtra ($snap){

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

Write-Host "Processing $guestName"

$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"

$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

}

0 Kudos
9 Replies
LucD
Leadership
Leadership

The function does return something, in fact it returns the object in the $snapshotsExtra through the pipeline.

This function relies on the fact that the TaskEvent of type VirtualMachine.createSnapshot is present in the Events and Tasks tables in the DB.

The username is retrieved from those specific events.

Are these TaskEvents present for the selected time period ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
SteveCSchofield
Enthusiast
Enthusiast

Thanks for the fast response.  The function was confusing cause I'm using to 'returning' data.  still a bit fuzzy on it's implementation, I'll trust you.

Are these TaskEvents present for the selected time period ?

There are entries on the specific vm's containing a user.  The environment I'm using is a test environment, there is 4 or 5 snaps (which 4 of them are under 30 days old).  There is one snap that is a couple years old, which is ok for testing purposes.   The user account that was created doesn't have an email address on the user account.  Would that make a difference?

0 Kudos
LucD
Leadership
Leadership

Yes, Alan's script looks up to email address to send the creator of the snapshot an email.

If there is no email address, nothing will be sent


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
SteveCSchofield
Enthusiast
Enthusiast

I'm afraid this script isn't working, I updated my account in AD that created the snap and no go with retrieving the email address.  I ran as a read-only account and as my "super duper" account.   I wonder if others have this working in vSphere 5.5.  The one thing unique about the snaps they are 'appliances' (imported OVF template).  Would that make a difference?

Is there a specific version of powershell I need to run this in? x86?   I'm running on a win 7 machine...

Thanks for your assistance.

0 Kudos
LucD
Leadership
Leadership

No special PS version required afaik.

Do you get any error messages ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
SteveCSchofield
Enthusiast
Enthusiast

I don't get any errors.  I'm posting my script that I'm using.  I've even dumbed it down to not go through the foreach look.  When I look at the members $SnapshotInfo = Get-SnapshotExtra $snap[0] it doesn't contain the creator property "aka NoteProperty". I don't confess to be a newbie at powershell although I'm not sure why the property isn't being set.  I've been trying to debug with PowerGUI (which crashes), Am I missing something obvious?

function LoadSnapin{
  param($PSSnapinName)
  if (!(Get-PSSnapin | where {$_.Name   -eq $PSSnapinName})){
    Add-pssnapin -name $PSSnapinName
  }
}
LoadSnapin -PSSnapinName   "VMware.VimAutomation.Core"

$smtpServer = "mail.example.com"
$MailFrom = "steve@example.com"
$VISRV = "vCenter1"

function Find-User ($username){
if ($username -ne $null)
{
  $usr = (($username.split("\"))[1])
  $root = [ADSI]""
  $filter = ("(&(objectCategory=user)(samAccountName=$Usr))")
  $ds = new-object system.DirectoryServices.DirectorySearcher($root,$filter)
  $ds.PageSize = 1000
  $ds.FindOne()
}
}

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){
$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"

$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
}

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.CC.Add($MailFrom)
$msg.Subject = "Snapshot Reminder" + $Mailto

$MailText = @"
This is a reminder that you have a snapshot active on $($snapshot.VM) which was taken on $($snapshot.Created) GMT/UTC.

Name: $($snapshot.Name)

Description: $($snapshot.Description)
"@

$msg.Body = $MailText
$smtp.Send($msg)
}

$cred = Get-Credential "domain\user"
Connect-VIServer -server $VISRV -credential $cred

#foreach ($snap in (Get-VM | Get-Snapshot | Where {$_.Created -lt ((Get-Date).AddDays(-1))})){
$snap = Get-VM | Get-Snapshot | Where {$_.Created -lt ((Get-Date).AddDays(-1))}
$SnapshotInfo = Get-SnapshotExtra $snap[0]
$mailto = ((Find-User $SnapshotInfo.Creator).Properties.mail)
SnapMail $mailto $SnapshotInfo
#}

0 Kudos
LucD
Leadership
Leadership

The Get-SnapshotExtra function uses the creation time of the event and the creation time of the snapshot, to link these two together.

In other words to link the username to the snapshot.

The function accepts a 5 second deviation between the 2 timestamps.

It could be that in your environment the event does not fall within this 5 second deviation.

The following short script should be able to show that.

$events = Get-VIEvent -Start (Get-Date).AddMinutes(-15) |
where {$_ -is [VMware.Vim.TaskEvent] -and $_.Info.DescriptionId -eq "VirtualMachine.createSnapshot"}

$events | Select CreatedTime,UserName,@{N="VM";E={$_.Vm.Name}},
 
@{N="Snap Created";E={
   
Get-VM -Name $_.Vm.Name | Get-Snapshot |
   
Sort-Object -Property Created -Descending |
   
Select -First 1 -ExpandProperty Created}}

You will have to adapt the Start parameter value in the first line to make sure to find the event that corresponds with the snapshot you are investigating.

If yours is a somewhat bigger environment, you will probably have to add the -MaxSamples ([int]::MaxValue) parameter on the Get-VIEvent cmdlet.

By default this only returns 100 events.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
SteveCSchofield
Enthusiast
Enthusiast

I'll give that a shot and let you know either way.   Thanks for your assistance!

0 Kudos
steveschofield
Enthusiast
Enthusiast

Here is a script I ended hacking together.  I added an additional function called Sanitize.  Enjoy!

VMware Snapshot reminder script - IISLogs.com

0 Kudos