VMware Cloud Community
AlbertWT
Virtuoso
Virtuoso
Jump to solution

Daily script to email offline snapshot report ?

Hi People,

I know that in VCenter we can put alarm to send us email about OPEN snapshot that is actively growing in the ESX(i) hosts but in this case I have different case to handle, it is about CLOSED snapshot (PoweredOff) that is not detectable by the VCenter alarm unless I go with my script as follows:

Connect-VIServer VCenter01-VM
Get-VM | Get-Snapshot | Select VM, Name, Description, Created, SizeMB | Sort SizeMB | ft -AutoSize
Disconnect-VIServer -Confirm False

then it would list several snapshot from small size few hundreds kilobytes up to GB.

Background: if there is snapshot at the VM then the nightly backup will fail.

my goal is to have a script which can do:

1. Generate the list of VM with snapshot and then email it to me daily.
2. if there is no VM with open snapshot, then no need to send email.

Any help please ?

/* Please feel free to provide any comments or input you may have. */
Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

That expression has a fault.

To check fi there are snapshots you can replace that line by

if ( (Get-Snapshot)) {

If there are no snapshots Get-Snapshot will return $null and the condition will evaluate to $false

But this way you will execute the Get-Snapshot cmdlet twice.

It's better to do it this way

Connect-VIServer VCenter01-VM -User "DOMAIN\PowerCLIRO" -Password "xyz" 
 
$snaps =  Get-Snapshot

if ( $snaps) { $smtpSrv = "smtp.domain.com" $from = "vmware.report@domain.com" $to = "admin@domain.com" $subject = "Snapshot Report" $body = $snaps | Select VM, Name, Description, Created, SizeMB | Sort SizeMB $msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body) $smtp = new-object Net.Mail.SMTPclient($smtpSrv) $smtp.send($msg) } else { Exit-PSSession } Disconnect-VIServer * -Confirm:$false


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

View solution in original post

Reply
0 Kudos
7 Replies
LucD
Leadership
Leadership
Jump to solution

Why don't you use the Windows Scheduler to run the script at the time you want ?

How to set this up can be found in Alan's post called Running a PowerCLI Scheduled task.

To send an email, just change the script like this

 Connect-VIServer VCenter01-VM

$smtpSrv
= "smtp.lucd.info"     # Your SMTP mail server
$from = "vmware.report@lucd.info" $to = "lucd@lucd.info"
$subject
= "Snapshot Report"
$body = Get-VM | Get-Snapshot | Select VM, Name, Description, Created, SizeMB | `
   
Sort SizeMB
$msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body) $smtp = new-object Net.Mail.SMTPclient($smtpSrv) $smtp.send($msg) Disconnect-VIServer -Confirm False


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

AlbertWT
Virtuoso
Virtuoso
Jump to solution

Many thanks for the reply,

I'm going to run this script as scheduled script that will send out email to me daily every 8 AM in the morning.

But somehow I got this error message:

You must provide a value expression on the right-hand side of the '-isnot' operator.

At C:\Temp\c3aef171-ebe1-4478-ba02-fad49652b461.ps1:3 char:27

+ if ( (Get-Snapshot) -isnot <<<<  out-null) {

    + CategoryInfo          : ParserError: (:) [], ParseException

    + FullyQualifiedErrorId : ExpectedValueExpression

here's my modified script:

Connect-VIServer VCenter01-VM -User "DOMAIN\PowerCLIRO" -Password "S3cr37!"
if ( (Get-Snapshot) -isnot out-null) {
$smtpSrv = "smtp.domain.com"
$subject = "Snapshot Report"
$body = Get-VM | Get-Snapshot | Select VM, Name, Description, Created, SizeMB | Sort SizeMB
$msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body)
$smtp = new-object Net.Mail.SMTPclient($smtpSrv)
$smtp.send($msg)
} else {
Exit-PSSession
}
Disconnect-VIServer * -Confirm:$false

/* Please feel free to provide any comments or input you may have. */
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

That expression has a fault.

To check fi there are snapshots you can replace that line by

if ( (Get-Snapshot)) {

If there are no snapshots Get-Snapshot will return $null and the condition will evaluate to $false

But this way you will execute the Get-Snapshot cmdlet twice.

It's better to do it this way

Connect-VIServer VCenter01-VM -User "DOMAIN\PowerCLIRO" -Password "xyz" 
 
$snaps =  Get-Snapshot

if ( $snaps) { $smtpSrv = "smtp.domain.com" $from = "vmware.report@domain.com" $to = "admin@domain.com" $subject = "Snapshot Report" $body = $snaps | Select VM, Name, Description, Created, SizeMB | Sort SizeMB $msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body) $smtp = new-object Net.Mail.SMTPclient($smtpSrv) $smtp.send($msg) } else { Exit-PSSession } Disconnect-VIServer * -Confirm:$false


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

Reply
0 Kudos
AlbertWT
Virtuoso
Virtuoso
Jump to solution

Thanks Luc for your assistance.

it works now 🙂

/* Please feel free to provide any comments or input you may have. */
Reply
0 Kudos
amitbil
Contributor
Contributor
Jump to solution

Hi LUCD ,

 

I have script for Snapshot & Datastore report.its genrating report but for sending email authetication required.Can you help me adding that lines to script.

Error:Exception calling "Send" with "1" argument(s): "The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.57 SMTP; Client was not authenticated to
send anonymous mail during MAIL FROM"
At C:\Scripts\Snap&Data\snap&datastore.ps1:176 char:1
+ $smtp.Send($msg)
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SmtpException

 

Here is the script:

# Execute Policy

#set-executionpolicy Unrestricted -Force

 

 

# Set Variables

$SCRIPT_PARENT = "C:\Scripts\Snap&Data"

$Uname = Get-Content Env:USERNAME

$Comp = Get-Content Env:COMPUTERNAME

 

# Remove old files

remove-item ($SCRIPT_PARENT + "\Report\V*.html") -force  

 

 

# Connect VCs from VC_List.txt

$VCs= Get-Content ($SCRIPT_PARENT + "\vc_list.txt") -ErrorAction SilentlyContinue # mention vcenter name where you want to check resources. 

$D = get-date -uformat "%m-%d-%Y-%H:%M" # To get a current date. 

 

Write-Host "Connecting to VC" -foregroundcolor yellow 

 

#*****************************************************************************************

 

foreach($vc in $VCs)  

{  

 

Connect-VIServer $VC -WarningAction 0 

$outputfile = ($SCRIPT_PARENT + "\Report\$($VC).html") #".\Report\$($VC).html" 

Write-Host "" 

Write-Host "Collecting details from $VC" -foregroundcolor green 

Function Get-SnapshotCreator {

Param (

[string]$VM,

[datetime]$Created

)

(Get-VIEvent -Entity $VM -Types Info -Start $Created.AddSeconds(-10) -Finish $Created.AddSeconds(10) | Where FullFormattedMessage -eq "Task: Create virtual machine snapshot" | Select -ExpandProperty UserName).Split("\")[-1]

}

$Report = Get-VM | Get-Snapshot | Select VM,Name,Description,@{Name="SizeGB";Expression={ [math]::Round($_.SizeGB,2) }},@{Name="Creator";Expression={ Get-SnapshotCreator -VM $_.VM -Created $_.Created }},Created,@{Name="Days Old";Expression={ (New-TimeSpan -End (Get-Date) -Start $_.Created).Days }}

If (-not $Report)

{$Report = [PSCustomObject]@{

VM = "n/a"

Name = "n/a"

Description = "n/a"

'Size (GB)' = "n/a"

Creator = "n/a"

Created = "n/a"

'Days Old' = "n/a"

}

}

$HTML = '<style type="text/css"> 

#Header{font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;width:100%;border-collapse:collapse;} 

#Header td, #Header th {font-size:14px;border:1px solid #98bf21;padding:3px 7px 2px 7px;} 

#Header th {font-size:14px;text-align:center;padding-top:5px;padding-bottom:4px;background-color:#cccccc;color:#000000;} 

#Header tr.alt td {color:#000;background-color:#EAF2D3;} 

</Style>' 

$HTML += "<HTML><BODY><Table border=1 cellpadding=0 cellspacing=0 id=Header><caption><font size=3 color=green><h1 align=""center"">Snapshots - $VC</h1></font> 

<h4 align=""right""><font size=3 color=""#00008B"">Date: $D </font></h4></caption> 

<TR> 

<TH><B>VM</B></TH> 

<TH><B>Snapshot Name</B></TH> 

<TH><B>Description</B></TH> 

<TH><B>Size (GB)</B></TH> 

<TH><B>Creator</B></TH> 

<TH><B>Created</B></TH> 

<TH><B>Days Old</B></TH> 

</TR>"

Foreach($Entry in $Report)

{if($Entry."Days Old" -gt "03" -and $Entry."Days Old" -ne "n/a") # Days old threshold - Warning / Yellow

                if($Entry."Days Old" -gt "7") # Days old threshold - Critical / Red

{

     $HTML += "<TR bgColor=#FF0000>" # Red

                     } 

                else 

                  { 

                  $HTML += "<TR bgColor=#FFE600>" # Yellow

                  }

    }

else

  {

  $HTML += "<TR bgColor=#7FFF00>" # Neon Green

  }

$HTML += "

<TD>$($Entry.VM)</TD> 

<TD>$($Entry.Name)</TD> 

<TD>$($Entry.Description)</TD> 

<TD>$($Entry.SizeGB)</TD> 

<TD>$($Entry.Creator)</TD> 

<TD>$($Entry.Created)</TD>

<TD>$($Entry."Days Old")</TD>

</TR>"

}

$HTML += "</Table>"

$HTML += "<Table bgcolor='#cccccc' border=1 cellpadding=0 cellspacing=0 id=Header><caption><font size=3 color=green><h1 align=""center"">Datastores - $VC</h1></font> 

<h4 align=""right""><font size=3 color=""#00008B"">Date: $D </font></h4></caption>

<TR> 

<TH><B>DataStore Name</B></TH> 

<TH><B>Free Space (GB)</B></TD> 

<TH><B>Capacity (GB)</B></TH> 

<TH><B>Provisioned Space (GB)</B></TH> 

<TH><B>Free Space (%)</B></TH> 

</TR>"

$Result = @() 

$Result += Get-View -ViewType Datastore | Where-Object {$_.Name -notlike "datastorenameyouwanttoexcclude*" -and $_.Name -notlike "anotherdatastorenameyouwanttoexclude*"} | Select-Object -Property Name,  

@{N="FreeSpaceGB";E={[Math]::Round($_.Summary.FreeSpace/1GB,0)}},  

@{N="CapacityGB"; E={[Math]::Round($_.Summary.Capacity/1GB,0)}},  

@{N="ProvisionedSpaceGB";E={[Math]::Round(($_.Summary.Capacity - $_.Summary.FreeSpace + $_.Summary.Uncommitted)/1GB,0)}}, 

@{N="FreeSpace";E={[math]::Round(((100* ($_.Summary.FreeSpace/1GB))/ ($_.Summary.Capacity/1GB)),0)}} | sort -Property "FreeSpace" 

Foreach($Entry in $Result) 

if($Entry.FreeSpace -lt "10") # Free space threshold - Warning / Yellow

if($Entry.FreeSpace -lt "05") # Free space threshold - Critical / Red

{

$HTML += "<TR bgColor=FF0000>" # Red

else 

$HTML += "<TR bgColor=FFE600>" # Yellow

}

}

else

{

$HTML += "<TR bgColor=7FFF00>" # Neon Green

}

$HTML += " 

<TD>$($Entry.Name)</TD> 

<TD>$($Entry.FreeSpaceGB)</TD> 

<TD>$($Entry.CapacityGB)</TD> 

<TD>$($Entry.ProvisionedSpaceGB)</TD> 

<TD>$($Entry.FreeSpace)</TD> 

</TR>" 

$HTML += "</TABLE></BODY></HTML>"

$HTML | Out-File $OutputFile 

Disconnect-VIServer $VC -Confirm:$false 

}

 

   

# Send email 

# Add email IDs in email_id.txt file     

$mailto = Get-Content ($SCRIPT_PARENT + "\email_id.txt") -ErrorAction SilentlyContinue 

$SMTPserver = "mail-extern.patec.group"

$msg = new-object Net.Mail.MailMessage   

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

$msg.From = "donotreply.readvsphere@syntegon.com"

$msg.IsBodyHTML = $true  

$msg.To.Add($mailto)

$msg.Subject = "Syntegon Datastore & Snapshot Report  - $vcs"

  

foreach($vc in $vcs)  

{  

     $MailTextT =  Get-Content ($SCRIPT_PARENT + "\Report\*.html") -ErrorAction SilentlyContinue 

     $Sig =  "<html><p class=MsoNormal><o:p>&nbsp;</o:p></p><B> Best Regards, <p> Windows Team </B></p></html>" 

    # $Top = "<html> This Script is executed on Server - <B>$Comp</B> by User - <b> $Uname </b></html>" 

     $MailText= $Top + $MailTextT + $Sig 

    }  

     

$msg.Body = $MailText 

$smtp.Send($msg)  

    

#*****************************************************************************************

Reply
0 Kudos
amitbil
Contributor
Contributor
Jump to solution

I am new to powershell Can you please insert in above script.I have tried but getting sam error

Reply
0 Kudos