Well, PowerCLI makes my life a little bit easier. Believe it or not, each of us vCenter infrastructure admins has one of these: a Windows admin, thinking a snapshot is also a backup. Thankfully, Alan Renouf over at virtu-al.net wrote the SnapReminder, which already helped me a lot! However, occasionally the script isn’t finding the snapshot author (for whatever reason).
Since I want a notification in that case, I modified the script a little bit to suit my needs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# - SnapReminder V1.0 By Virtu-Al - http://virtu-al.net # # Please use the below variables to define your settings before use # $smtpServer = "smtp.home.barfoo.org" $MailFrom = "vcenter@barfoo.org" $adminmail = "christian.heim@barfoo.org" $VISRV = "vcenter.home.barfoo.org" # Add the VI-Snapin if it isn't loaded already if ( (Get-PSSnapin -Name "VMware.VimAutomation.Core" -ErrorAction SilentlyContinue) -eq $null ) { Add-PSSnapin -Name "VMware.VimAutomation.Core" } 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 -Force -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.ReplyTo = $adminmail if (!$mailto) { $msg.To.Add($adminmail) } else { $msg.To.Add($mailto) $msg.CC.Add($adminmail) } $msg.Subject = "Snapshot Reminder for $($snapshot.VM)" $MailText = @" There is an existing snapshot for the VM $($snapshot.VM) wurde am $($snapshot.Created.ToString("dddd, d. MMMM yyyy um HH:mm:ss")). Please check, whether this snapshot is still needed, otherwise please delete it! Just a short reminder: A snapshot doesn't replace a backup! Name: $($snapshot.Name) Description: $($snapshot.Description) Snapshot size: $([math]::Round($snapshot.SizeMB * 1MB / 1GB))GB "@ $msg.Body = $MailText $smtp.Send($msg) } Connect-VIServer $VISRV foreach ($snap in (Get-VM | Get-Snapshot | Where {$_.Created -lt ((Get-Date).AddDays(-5))})){ Get-SnapshotExtra $snap $SnapshotInfo = Get-SnapshotExtra $snap $mailto = ((Find-User $SnapshotInfo.Creator).Properties.mail) SnapMail $mailto $SnapshotInfo } |