VMware Cloud Community
mfrycz
Contributor
Contributor
Jump to solution

Once again snapshots...

Hi,

I was looking lately at http://www.virtu-al.net/2009/06/22/powercli-snapreminder/ the most famous script on the net Smiley Wink

My only issue (point where i stuck) is the last part of this script:

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 = "Old Snapshot Reminder!!!"

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

Created by: $($(Find-User $SnapshotInfo.Creator).Properties.name)
Email: $($(Find-User $SnapshotInfo.Creator).Properties.mail)

Name: $($snapshot.Name)
Description: $($snapshot.Description)
Snapshot size: $([math]::Round($snapshot.SizeMB))MB
"@

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

Connect-VIServer $VISRV

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

$SnapshotInfo = Get-SnapshotExtra $snap
$mailto = (groupemail@yourdomain.com)
SnapMail $mailto $SnapshotInfo
}

Which is giving me exactly what i need in my company apart of ehis is sending one email per snapshot Smiley Sad

Would it be possible to separate $MailText for all snapshots and send just one email? something like:

$SnapshotInfo = Get-VM | Get-Snapshot | where { $_.Name.Length -gt 0 -and $_.Created -lt ((Get-Date).AddMinutes(-30))} | Select VM,Name,Description,Created | Sort Created

Where you can have all details sorted (but i need AD user details as well as his email)

Probably its just a small change but sadly out of the reach of my imagination at this stage Smiley Sad

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Should be, the script adds a property, called Creator, to the SnapshotImpl object.

Are you running this in a Gui ?

Can you put a breakpoint at that line and check what is in $report and do a $report | gm to see what properties are there ?


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

View solution in original post

Reply
0 Kudos
16 Replies
LucD
Leadership
Leadership
Jump to solution

Try replacing the last part (the lines after Connect-VIServer $VISRV) of the script with this

 $report = @()
foreach ($snap in (Get-VM | Get-Snapshot | where {$_.Created -lt ((Get-Date).AddDays(-14))})){
    $SnapshotInfo = Get-SnapshotExtra $snap
   
Add-Member -InputObject $SnapshotInfo -Name Email -Value ((Find-User $SnapshotInfo.Creator).Properties.mail)     $report += $SnapshotInfo
} $msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer) $msg.From = $MailFrom $msg.To.Add($Mailto) $msg.Subject = "Snapshot Report"
$msg
.IsBodyHtml = $true
$msg
.Body = $report | ConvertTo-Html
$smtp
.Send($msg)

All the snapshot info is collected in an array called $report.

As an extra, the script adds the mail address of the Creator to each line.

Once all snapshot info is collected it is send as 1 email to the address in $mailto.

Make sure you set the value of the variable $Mailto somewhere.


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

mfrycz
Contributor
Contributor
Jump to solution

Hi Luc,

I swapped the code as suggested and i am getting one email which is good Smiley Happy

Code look like this now:

Connect-VIServer $VISRV

$report = @()
foreach ($snap in (Get-VM | Get-Snapshot | where {$_.Created -lt ((Get-Date).AddMinutes(-30))})){
    $SnapshotInfo = Get-SnapshotExtra $snap Add-Member -InputObject $SnapshotInfo -Name Email -Value ((Find-User $SnapshotInfo.Creator).Properties.mail)
    $report += $SnapshotInfo}

$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = $MailFrom
$msg.To.Add($Mailto)

$msg.Subject = "Snapshot Report"

$msg.IsBodyHtml = $true
$msg.Body = $report | ConvertTo-Html
$smtp.Send($msg)

But the email comes with unreadable format (look at prtscr attached)...

Also not all of this parameters are needed for our needs.

Bolded text in code is not displaying email attributes of the snapshot creator 😕

Maybe some reference in body structure of email where i could add this details as a variable ?

Is there any sort of table formatting for this output ?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Yeah, that's because I dumped the complete snapshot object to the HTML table.

Which properties should be in the mail ?

You can adapt the selection by changing this line into something like this for example

$msg.Body = $report | Select Creator, Description, Created, Vm SizeMB | ConvertTo-Html

If you don't want HTML in the body, you simple change that as well

$msg.IsBodyHtml = $false
$msg.Body = $report | Select Creator, Description, Created, Vm SizeMB

Does that help ?


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

Reply
0 Kudos
mfrycz
Contributor
Contributor
Jump to solution

Luc,

Properties i would like to have best way would be in this format:

==============================

Created by: Twain, Mark
Email: TwainM@yourdomain.com

Name: Name of Snapshot
Description: bla bla bla bla.
Snapshot size: 32282MB

==============================

All was extracted from email body:

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

Created by: $($(Find-User $SnapshotInfo.Creator).Properties.name)
Email: $($(Find-User $SnapshotInfo.Creator).Properties.mail)

Name: $($snapshot.Name)
Description: $($snapshot.Description)
Snapshot size: $([math]::Round($snapshot.SizeMB))MB
"@

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

and reffered afterwards

But if not i am more than happy have them formatted in a table view (as soon as all of them are with exactly what we want)

When i have changed this selection to this for example

$msg.Body = $report | Select Creator, Description, Created, Vm SizeMB | ConvertTo-Html

i recieved blank email Smiley Sad


did also try without HTML formatting but no details either...

$msg.IsBodyHtml = $false
$msg.Body = $report | Select Creator, Description, Created, Vm SizeMB

Any suggestions Smiley Happy

(no errors while running script)

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Ok, let's try it first with a text body in the email.

I think I forgot the Out-STring cmdlet on that line.

Try with

$msg.IsBodyHtml = $false
$msg.Body = $report | Select Creator, Description, Created, Vm SizeMB | Out-String


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

Reply
0 Kudos
mfrycz
Contributor
Contributor
Jump to solution

still nothing with following error:

At C:\Documents and Settings\1846\My Documents\Scripts\SnapReminder.ps1:126 char:29
+ $msg.Body = $report | Select <<<<  Creator, Description, Created, Vm SizeMB | Out-String
    + CategoryInfo          : InvalidArgument: (:) [Select-Object], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.SelectObjectCommand

for line:

$msg.Body = $report | Select Creator, Description, Created, Vm SizeMB | Out-String

Is the Creator, Description, ... a proper parameter names ?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Should be, the script adds a property, called Creator, to the SnapshotImpl object.

Are you running this in a Gui ?

Can you put a breakpoint at that line and check what is in $report and do a $report | gm to see what properties are there ?


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

Reply
0 Kudos
mfrycz
Contributor
Contributor
Jump to solution

Its all there...

Check prtscr's 

could we actually replace the report from showing domain\1111 to pool from AD $(Find-User $SnapshotInfo.Creator).Properties.name as this should be clearer...

Obviously when it will actually send an email Smiley Happy

Reply
0 Kudos
mfrycz
Contributor
Contributor
Jump to solution

Ok,

this is what i got now:

$report = @()
foreach ($snap in (Get-VM | Get-Snapshot | where {$_.Created -lt ((Get-Date).AddMinutes(-30))})){
    $SnapshotInfo = Get-SnapshotExtra $snap Add-Member -InputObject $SnapshotInfo -Name Email -Value ((Find-User $SnapshotInfo.Creator).Properties.mail)
    $report += $SnapshotInfo}

$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = $MailFrom
$msg.To.Add($Mailto)

$msg.Subject = "Snapshot Report"

$msg.Body = $report | Select Creator, Description, Created, VM, SizeMB | Out-String
$smtp.Send($msg)

All looks good in the email format but while i am checking both variables $SnapshotInfo and $report both of them are coming back with this format DOMAIN\11111 so there must be some wrong call on bolded part of the script

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You can get the username from the AD object and add it with another Add-Member to the snapshot object.

$report = @()
foreach ($snap in (Get-VM | Get-Snapshot | where {$_.Created -lt ((Get-Date).AddMinutes(-30))})){
     $SnapshotInfo = Get-SnapshotExtra $snap

    $ADuser = Find-User  $SnapshotInfo.Creator

    Add-Member -InputObject  $SnapshotInfo -Name Email -Value $ADuser.Properties.name

    Add-Member -InputObject  $SnapshotInfo -Name UserName -Value $ADuser.Properties.mail
    $report += $SnapshotInfo

}

$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = $MailFrom
$msg.To.Add($Mailto)

$msg.Subject = "Snapshot Report"

$msg.Body = $report | Select UserName, Description, Created, VM, SizeMB | Out-String
$smtp.Send($msg)


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

mfrycz
Contributor
Contributor
Jump to solution

Luc we are getting there Smiley Wink

You will have to add -MemberType NoteProperty (if not it will shout at you

Add-Member -MemberType NoteProperty -InputObject $SnapshotInfo -Name Email -Value $ADuser.Properties.mail
Add-Member -MemberType NoteProperty -InputObject $SnapshotInfo -Name UserName -Value $ADuser.Properties.name

And all works fine...

In the email though i got extra brackets {} characters for new values:

UserName    : {bla, blabla}
Email       : {bla@bla.com}

Can this be removed ?

PS. That is the last cosmetic fix and we've done here Smiley Happy

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

It must be Friday, I start to miss...

Try this

$report = @()
foreach ($snap in (Get-VM | Get-Snapshot | where {$_.Created -lt ((Get-Date).AddMinutes(-30))})){
     $SnapshotInfo = Get-SnapshotExtra $snap

    $ADuser = Find-User  $SnapshotInfo.Creator

    Add-Member -InputObject  $SnapshotInfo -MemberType NoteProperty -Name Email -Value $ADuser.Properties.name.Trim('{}')

    Add-Member -InputObject  $SnapshotInfo -MemberType NoteProperty-Name UserName -Value $ADuser.Properties.mail.Trim('{}')
    $report += $SnapshotInfo

}

$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = $MailFrom
$msg.To.Add($Mailto)

$msg.Subject = "Snapshot Report"

$msg.Body = $report | Select UserName, Description, Created, VM, SizeMB | Out-String
$smtp.Send($msg)


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

Reply
0 Kudos
mfrycz
Contributor
Contributor
Jump to solution

Ok i got it

just changed:

-Value $(($ADuser).Properties.mail)

-Value $(($ADuser).Properties.name)

and all OK now Smiley Happy

Reply
0 Kudos
mfrycz
Contributor
Contributor
Jump to solution

btw...

$report = @()
foreach ($snap in (Get-VM | Get-Snapshot | where {$_.Created -lt ((Get-Date).AddMinutes(-30))})){
     $SnapshotInfo = Get-SnapshotExtra $snap

    $ADuser = Find-User  $SnapshotInfo.Creator

    Add-Member -InputObject  $SnapshotInfo -MemberType NoteProperty -Name Email -Value $ADuser.Properties.name.Trim('{}')

    Add-Member -InputObject  $SnapshotInfo -MemberType NoteProperty-Name UserName -Value $ADuser.Properties.mail.Trim('{}')
    $report += $SnapshotInfo

}

this didnt work (no details at all for username and email)

But without your help i would probably strugle a much longer Smiley Happy

Thank you Very much LucD (points are going your way)

till next time Smiley Wink

Reply
0 Kudos
BKeadle
Contributor
Contributor
Jump to solution

Can I get in on this?

I'm not getting the snapshot creator information.  The various scripts I've found, namely SnapoReminder by Virtu-Al, seems to intend to get the snapshot creator so they can be notfied about their open/old snapshots.  How/why might I be missing that information in my environment.

I've found a script that queries the vCenter database to retrieve information about who created snapshots, but it's getting this information from the VPX_TASK table and includes all snapshots in the event list:


$SQLSERVER = "VCENTER-IT0101\SQLEXP_VIM"
$Database = "VIM_VCDB"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=$SQLSERVER;Database=$DATABASE;Integrated Security=True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = "select start_time, username, complete_time, entity_name, complete_state " +
                      "from VPX_TASK " +
       "where name like '%.VirtualMachine.createSnapshot' " +
       "order by start_time"
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$SqlConnection.Close()
$DataSet.Tables[0]

Any suggestions?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The part in Alan's script that finds the creator looks through the Events.

Could it be that you are not archiving the events in your vCenter ?

Check from the vSphere Client <Administration><vCenter Server Settings><Database Retention Policy>.

In the Tasks and Events fields you should have a large enough value.

The other reason could be that the snapshots have been created longer ago than the retention period specified in these fields.


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

Reply
0 Kudos