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-VMGet-VM | Get-Snapshot | Select VM, Name, Description, Created, SizeMB | Sort SizeMB | ft -AutoSizeDisconnect-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 ?
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
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
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
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
Thanks Luc for your assistance.
it works now 🙂
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> </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)
#*****************************************************************************************
I am new to powershell Can you please insert in above script.I have tried but getting sam error