I'm back again for more help, this time with producing output in an email. I can get output in the console, but I cannot get the same output in an email.
I found and modified the script posted below. It searches your snapshots, puts them in an array, and then compares their creation date and snapshot count against what you set. All of that works great and produces the following:
I want this same output sent in an email. I want it to look exactly like what you see in the picture. I can't figure it out. What I can get is an email with a body that says:
*
89
That's it. I don't know if it's because of how I declared $Summary, $MaxAge, and $MaxCount, or if the problem is with my email parameters. Could someone take a look and see what I'm doing wrong? I would greatly appreciate it.
# vCenter server name or IP
$vcenter = 'MyVCServer'
# Max number of snapshots to allow per VM
$maxsnapcount = 2
# Max age of any snapshot to allow in days
$maxsnapage = 200
# Display all VM messages? Setting to $false lists only VMs with warnings
$displayall = $false
# Establish credentials
$Username = "domain\adminuser"
$SecurePassword = Get-Content C:\automation\creds.txt | ConvertTo-SecureString
$UserCredential = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$SecurePassword
#region Code
# cls
### Static Variables
# Array containing all snapshots found
[array]$allsnapshots = $null
# Current date minus snapshot max date
$date = (Get-Date).AddDays(-1 * $maxsnapage)
### Gather Inventory
Connect-ViServer -server $vcenter -Credential $UserCredential | Out-Null
$vms = Get-VM | Get-View
Foreach ($vm in $vms)
{
If ($vm.Snapshot -ne $null)
{
# Inventory the VM snapshots
[array]$vmsnapshots = Get-VM -Id $vm.MoRef | Get-Snapshot
# Add the snapshots to the master array
$allsnapshots += $vmsnapshots
# Check to see if the VM has exceeded the max snapshot age
$MaxAge = Foreach ($snap in $vmsnapshots)
{
If ($snap.Created -le $date) {Write-Host -ForegroundColor:Red "[Old Snapshots] $($vm.name) contains an old snapshot named ""$($snap.Description)"" created on $($snap.Created)"}
}
# Check to see if the VM has exceeded the max snapshot count
$MaxCount = If (($vmsnapshots.count) -gt $maxsnapcount)
{
Write-Host -ForegroundColor:Red "[Max Snapshots] $($vm.name) has $($vmsnapshots.count) snapshots";
}
}
ElseIf ($displayall -eq $true) {Write-Host -ForegroundColor:Green "$($vm.name) has no snapshots"}
}
# Summary Information
Write-Host "==============================`nSummary Information`nFound $($vms.count) VMs`nFound $($allsnapshots.count) snapshots"
#endregion
# Email information
# Specify who gets notified
$notificationto = "me@company.com"
$notificationcc = "him@company.com"
# Specify where the notifications come from
$notificationfrom = "notification@company.com"
# specify the SMTP server
$smtpserver = "blah-blah-company.com"
# Summary
$summary = "==============================
`nSummary Information
`nFound $($vms.count) VMs
`nFound $($allsnapshots.count) snapshots"
# Send email
# Declare some mail message params
$mailMessageParams = @{
Body = $Summary, $MaxAge, $MaxCount | ConvertTo-Html | Out-String
To = $notificationto
# CC = $notificationcc
From = $notificationfrom
Subject = "VM Snapshot Report"
SmtpServer = $smtpServer
}
#
# Send email
Send-MailMessage @mailMessageParams -BodyAsHtml
# Disconnect from server
Disconnect-ViServer -Server $vcenter -Confirm:$false
This is a reviewed script that works for me.
$vcenter = 'MyVCServer'
# Max number of snapshots to allow per VM
$maxsnapcount = 2
# Max age of any snapshot to allow in days
$maxsnapage = 200
# Display all VM messages? Setting to $false lists only VMs with warnings
$displayall = $false
# Establish credentials
$Username = "domain\adminuser"
$SecurePassword = Get-Content C:\automation\creds.txt | ConvertTo-SecureString
$UserCredential = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$SecurePassword
#region Code
# cls
### Static Variables
# Array containing all snapshots found
[array]$allsnapshots = $null
$maxAge = @()
$maxCount = @()
# Current date minus snapshot max date
$date = (Get-Date).AddDays(-1 * $maxsnapage)
### Gather Inventory
Connect-ViServer -server $vcenter -Credential $UserCredential | Out-Null
$vms = Get-VM | Get-View
Foreach ($vm in $vms) {
If ($vm.Snapshot -ne $null) {
# Inventory the VM snapshots
[array]$vmsnapshots = Get-VM -Id $vm.MoRef | Get-Snapshot
# Add the snapshots to the master array
$allsnapshots += $vmsnapshots
# Check to see if the VM has exceeded the max snapshot age
Foreach ($snap in $vmsnapshots) {
If ($snap.Created -le $date) {
$text = "[Old Snapshots] $($vm.name) contains an old snapshot named ""$($snap.Description)"" created on $($snap.Created)"
Write-Host -ForegroundColor:Red $text
$maxAge += $text
}
}
# Check to see if the VM has exceeded the max snapshot count
If (($vmsnapshots.count) -gt $maxsnapcount) {
$text = "[Max Snapshots] $($vm.name) has $($vmsnapshots.count) snapshots"
Write-Host -ForegroundColor:Red $text
$maxCount += $text
}
}
ElseIf ($displayall -eq $true) {
Write-Host -ForegroundColor:Green "$($vm.name) has no snapshots"
}
}
# Summary Information
Write-Host "==============================`nSummary Information`nFound $($vms.count) VMs`nFound $($allsnapshots.count) snapshots"
#endregion
# Email information
# Specify who gets notified
$notificationto = "me@company.com"
$notificationcc = "him@company.com"
# Specify where the notifications come from
$notificationfrom = "notification@company.com"
# specify the SMTP server
$smtpserver = "blah-blah-company.com"
# Summary
$summary = "==============================
Summary Information
Found $($vms.count) VMs
Found $($allsnapshots.count) snapshots"
# Send email
# Declare some mail message params
$bodyText = ($Summary.Replace("`n",'::'), '::',($MaxAge -join '::'), '::', ($MaxCount -join'::')) -join '::'
$mailMessageParams = @{
Body = (ConvertTo-Html -Body $bodyText) -replace '::','<br/>' | Out-String
To = $notificationto
# CC = $notificationcc
From = $notificationfrom
Subject = "VM Snapshot Report"
SmtpServer = $smtpServer
}
#
# Send email
Send-MailMessage @mailMessageParams -BodyAsHtml
# Disconnect from server
Disconnect-ViServer -Server $vcenter -Confirm:$false
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Change the line to set the Body parameter to
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks for the reply. That produced the following, which is a vast improvement:
============================== Summary Information Found 423 VMs Found 88 snapshots
It only lacks the maxage and maxcount info.
It is a bit tricky to handle newlines with ConvertTo-Html.
You replace the desired newlines with a random set of characters, and then replace those with a '<br/>' after ConvertTo-Html.
Something like this for example
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I guess you read my mind as I wanted the summary to be on separate lines, just like the write-host output. Your suggestion didn't work, but that's honestly no big deal. What is important, and lacking in the email, is the $maxage and $maxcount. They are completely missing.
Strange, seems to work for me.
So you want the lines that you write to the console to also appear in the email's body?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
This is a reviewed script that works for me.
$vcenter = 'MyVCServer'
# Max number of snapshots to allow per VM
$maxsnapcount = 2
# Max age of any snapshot to allow in days
$maxsnapage = 200
# Display all VM messages? Setting to $false lists only VMs with warnings
$displayall = $false
# Establish credentials
$Username = "domain\adminuser"
$SecurePassword = Get-Content C:\automation\creds.txt | ConvertTo-SecureString
$UserCredential = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$SecurePassword
#region Code
# cls
### Static Variables
# Array containing all snapshots found
[array]$allsnapshots = $null
$maxAge = @()
$maxCount = @()
# Current date minus snapshot max date
$date = (Get-Date).AddDays(-1 * $maxsnapage)
### Gather Inventory
Connect-ViServer -server $vcenter -Credential $UserCredential | Out-Null
$vms = Get-VM | Get-View
Foreach ($vm in $vms) {
If ($vm.Snapshot -ne $null) {
# Inventory the VM snapshots
[array]$vmsnapshots = Get-VM -Id $vm.MoRef | Get-Snapshot
# Add the snapshots to the master array
$allsnapshots += $vmsnapshots
# Check to see if the VM has exceeded the max snapshot age
Foreach ($snap in $vmsnapshots) {
If ($snap.Created -le $date) {
$text = "[Old Snapshots] $($vm.name) contains an old snapshot named ""$($snap.Description)"" created on $($snap.Created)"
Write-Host -ForegroundColor:Red $text
$maxAge += $text
}
}
# Check to see if the VM has exceeded the max snapshot count
If (($vmsnapshots.count) -gt $maxsnapcount) {
$text = "[Max Snapshots] $($vm.name) has $($vmsnapshots.count) snapshots"
Write-Host -ForegroundColor:Red $text
$maxCount += $text
}
}
ElseIf ($displayall -eq $true) {
Write-Host -ForegroundColor:Green "$($vm.name) has no snapshots"
}
}
# Summary Information
Write-Host "==============================`nSummary Information`nFound $($vms.count) VMs`nFound $($allsnapshots.count) snapshots"
#endregion
# Email information
# Specify who gets notified
$notificationto = "me@company.com"
$notificationcc = "him@company.com"
# Specify where the notifications come from
$notificationfrom = "notification@company.com"
# specify the SMTP server
$smtpserver = "blah-blah-company.com"
# Summary
$summary = "==============================
Summary Information
Found $($vms.count) VMs
Found $($allsnapshots.count) snapshots"
# Send email
# Declare some mail message params
$bodyText = ($Summary.Replace("`n",'::'), '::',($MaxAge -join '::'), '::', ($MaxCount -join'::')) -join '::'
$mailMessageParams = @{
Body = (ConvertTo-Html -Body $bodyText) -replace '::','<br/>' | Out-String
To = $notificationto
# CC = $notificationcc
From = $notificationfrom
Subject = "VM Snapshot Report"
SmtpServer = $smtpServer
}
#
# Send email
Send-MailMessage @mailMessageParams -BodyAsHtml
# Disconnect from server
Disconnect-ViServer -Server $vcenter -Confirm:$false
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Ok, now that worked great! Carriage returns and everything!!!
From what I can tell, I didn't establish MaxAge and MaxCount as empty arrays. Next was adding the text to the array after write-host. Is that correct?
Yes, I first form the output in a variable, then write it to the console and store it in the arrays.
Those arrays are then used in the Body of the email.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks for your help, with this and my previous post! Much appreciated.
Hi LucD,
I'm not getting the email output and it shows an error
Input string was not in a correct format.
22 char:57
Thanks
V
That line should be
$SecurePassword = Get-Content C:\automation\creds.txt | ConvertTo-SecureString -AsPlainText -Force
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference