VMware Cloud Community
Schwags
Contributor
Contributor
Jump to solution

Snapshot Report Including Snap Owner/Creator

I have a script that I run daily to report on open Snapshots.  It's a script that I found online, but then realized we wanted to add the owner for the snap to the information.  Again, I found some code online and was able to add it into the script, however it doesn't always seem to report the owner correctly.  Any help would be greatly appreciated.

Below is the relevant code.  I added a couple of parts that grab data using Get-VIEvent and then post it in (Description and CreatedBy).  The problem is that it doesn't seem to be reliable.  Sometimes the owner comes up blank, and sometimes it shows a different user than who actually took the snapshot.  I'm not great at PowerShell and I wanted to know if someone can suggest what is wrong in the code?  I will also attach the original code at the bottom which is meant to pull snapshot owner which I integrated into the first script.  When I run that by itself, it either tells me the event is not in the database, or sometimes it's correct where the main script is wrong or shows a blank user.

I read also that there is a more reliable way than VIEvents to get the owner of the snap.  I found some code on this board, but I was unable to figure out how to integrate it properly.

# Add VMWare plugin to Powershell and connect to vCenter

Add-pssnapin VMware.VimAutomation.Core

Set-executionpolicy remotesigned -Confirm:$false

Set-PowerCLIConfiguration -InvalidCertificateAction ignore -Confirm:$false

connect-viserver <viserver>

# create table to capture VM snapshot info

$vmtable = New-Object system.Data.DataTable "VMTable"

$col1 = New-Object system.Data.DataColumn VM,([string])

$col2 = New-Object system.Data.DataColumn Snapshot,([string])

$col3 = New-Object system.Data.DataColumn SizeMB,([string])

$col4 = New-Object system.Data.DataColumn Created,([string])

$col5 = New-Object system.Data.DataColumn Description,([string])  #Added by me

$col6 = New-Object system.Data.DataColumn CreatedBy,([string])  #Added by me

$vmtable.columns.add($col1)

$vmtable.columns.add($col2)

$vmtable.columns.add($col3)

$vmtable.columns.add($col4)

$vmtable.columns.add($col5)  #Added by me

$vmtable.columns.add($col6)  #Added by me

#examine all VMs on vCenter, if snapshot found - add it to the table

ForEach ($vm in (Get-VM | Sort-Object -Property Name))

{

  ForEach ($snapshot in (Get-Snapshot -VM $vm.Name | Sort-Object -Property Name))

    {

#$snapevent is how we get the event so we can see snap creator.  Other variables could be used here.  Notes At end

  $snapevent = Get-VIEvent -Entity $snap.VM -Types Info -Finish $snap.Created -MaxSamples 1 | Where-Object {$_.FullFormattedMessage -imatch 'Task: Create virtual machine snapshot'}

  $created = -split $snapshot.Created

  $row = $vmtable.NewRow()

  $row.VM = $vm.Name

  $row.Snapshot = $snapshot.Name

  $row.SizeMB = "{0:N0}" -f $snapshot.SizeMb

  $row.Created = $created[0]

  $row.Description = $snapshot.description  #Added by me

$row.CreatedBy = $snapevent.UserName  #Added by me

  $vmtable.Rows.Add($row)

    }

}

#SnapEvents Notes:

#foreach ($snap in Get-VM | Get-Snapshot)

#{$snapevent = Get-VIEvent -Entity $snap.VM -Types Info -Finish $snap.Created -MaxSamples 1 | Where-Object {$_.FullFormattedMessage -imatch 'Task: Create virtual machine snapshot'}

#if ($snapevent -ne $null){Write-Host ( "VM: "+ $snap.VM + ". Snapshot '" + $snap + "' created on " + $snap.Created.DateTime + " by " + $snapevent.UserName +".")}

#else {Write-Host ("VM: "+ $snap.VM + ". Snapshot '" + $snap + "' created on " + $snap.Created.DateTime + ". This event is not in vCenter events database")}}

#

#Output result example:

#VM: DC2DC001. Snapshot 'pre-5.1.2upgrade' created on 28 July 2013 07:10:26 by vStrong.info\win8user.

#VM: DC1DC001. Snapshot 'pre 5.1.2a upgrade' created on 28 July 2013 07:51:24 by vStrong.info\win7user.

#VM: DC2APP001. Snapshot 'pre-fix' created on 02 August 2012 14:29:19. This event is not in vCenter events database

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

One of the reasons you up blank, could be that the event's timestamp is not 100% the same as the snapshot timestamp.

In Alan's SnapReminder we add a short interval before and after the snapshot creation time.


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

View solution in original post

0 Kudos
9 Replies
LucD
Leadership
Leadership
Jump to solution

One of the reasons you up blank, could be that the event's timestamp is not 100% the same as the snapshot timestamp.

In Alan's SnapReminder we add a short interval before and after the snapshot creation time.


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

0 Kudos
Schwags
Contributor
Contributor
Jump to solution

I tried as you suggested, just working with this piece of code before I implement into the full script.  I believe this was the command you were referencing?  It's still coming back saying that the event is not in vCenter events database.

#

foreach ($snap in Get-VM | Get-Snapshot)

{$snapevent = Get-VIEvent -Entity $snap.VM -Types Info -Finish (($snap.Created).AddSeconds(-5)) -MaxSamples 1 | Where-Object {$_.FullFormattedMessage -imatch 'Task: Create virtual machine snapshot'}

if ($snapevent -ne $null){Write-Host ( "VM: "+ $snap.VM + ". Snapshot '" + $snap + "' created on " + $snap.Created.DateTime + " by " + $snapevent.UserName +".")}

else {Write-Host ("VM: "+ $snap.VM + ". Snapshot '" + $snap + "' created on " + $snap.Created.DateTime + ". This event is not in vCenter events database")}}

#

0 Kudos
LucD
Leadership
Leadership
Jump to solution

That's correct, that is the line I was referring to.

Did you experiment with the 5 seconds, in some environments the time difference could be larger.

You are sure that your Events are kept sufficiently long ?


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

Schwags
Contributor
Contributor
Jump to solution

That was the problem.  I actually went all the way down to -60, and still nothing, but when I flipped to positive 5, it now is showing the right creation user.

Thanks for the help!

0 Kudos
vmk2014
Expert
Expert
Jump to solution

Hi,

It's showing blank output after executing the script.I am looking for Daily snapshot report. kindly help me

Thanks

vm2014

0 Kudos
Schwags
Contributor
Contributor
Jump to solution

I have experimented a bunch with this and it's still fairly inconsistent.  Right now i'm using "$snap.Created.AddMinutes(1) -MaxSamples 5.  If I change to MaxSamples 10, chances are it will get the user, however it usually returns 3 different users instead of 1.  I kind of gave up on it working right at this point.

0 Kudos
Schwags
Contributor
Contributor
Jump to solution

Yes, except everything from the line "SnapEvent Notes" should be commented out.  That stuff at the bottom was from the previous script before I messed with it.  You have some lines there that are uncommented.

And on the line:

$snapevent = Get-VIEvent -Entity $snap.VM -Types Info -Finish $snap.Created -MaxSamples 1 | Where-Object {$_.FullFormattedMessage -imatch 'Task: Create virtual machine snapshot'}

We changed the code up a bit, based on this post.  I do this now:

$snapevent = GetVIEvent $snap.VM -Types Info -Finish $snap.Created.AddMinutes(1) -MaxSamples 5 | Where-Object {$_.FullFormattedMessage -imatch 'Task:  Create virtual machine snapshot'}

You can experiment with changing AddMinutes in positive and negative direction, or changing to AddSeconds and playing with numbers there.  Also you can change MaxSamples, try 1, 5 or 10.  I never found a perfect combination that always works and only returns one correct user.  It's really different for every environment, I just didn't have the time to keep messing with it, not that important for us to have the user.

0 Kudos
Inny
Contributor
Contributor
Jump to solution

Replying here since it was the top result in my Google search.

I settled on the following script for this purpose.

function Get-FolderPath($Folder) {      If ($Folder.GetType().Name -eq 'FolderImpl') {           $FolderPath = $Folder.Name           while ($Folder.Parent) {                $FolderPath = ([string]$Folder.Parent + '\' + $FolderPath)                $Folder = $Folder.Parent           }           $FolderPath -Replace "[^\\]+\\vm\\"      } Else { "N/A" } }  $Datastores = Get-Datastore | Sort Name $snaps = @(); $snapsByDS = @() foreach ($ds in $Datastores) {      $dssnaps    = $ds | Get-VM | Get-Snapshot      $snapsByDS += $ds | Select Name,@{n='SnapshotSizeGB';e={[math]::Round(($dssnaps | Measure-Object -Property SizeGB -sum).Sum,1)}}      $snaps     += $dssnaps } $snaps | Select @{n='FolderPath';e={Get-FolderPath -Folder (Get-VM -Id $_.VMId).Folder}},VM,Created,`                 @{n='Creator';e={(Get-VIEvent -Entity $_.VM -Types Info -Start (Get-Date $snap.Created.AddMinutes(-1)) -Finish (Get-Date $_.Created.AddMinutes(1)) | ?{$_.Info.Name -eq 'CreateSnapshot_Task'} | Select -First 1).UserName}},`                     Name,@{n='SizeGB';e={[math]::Round($_.SizeGB,2)}},Quiesced,Description | ft -a $snapsByDS | ft -a

Which would look something like this:

2020-02-25 17_32_08-HERACLES (user) (HERACLES.solipsis.nl) - Remote Desktop Connection Manager v2.7.png

0 Kudos
ketelamaki
Contributor
Contributor
Jump to solution

If you remove the where clause from the $snapevent = line, you will probably not get that anymore. I know I don't now that I removed that.

0 Kudos