VMware Cloud Community
Jneagle
Enthusiast
Enthusiast
Jump to solution

Snapshot report - Unable to produce email output

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:

results.jpg

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

1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

This is a reviewed script that works for me.

# 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

$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

View solution in original post

Reply
0 Kudos
11 Replies
LucD
Leadership
Leadership
Jump to solution

Change the line to set the Body parameter to

Body = ConvertTo-Html -Body $Summary, $MaxAge, $MaxCount | Out-String


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

Reply
0 Kudos
Jneagle
Enthusiast
Enthusiast
Jump to solution

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.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Body = (ConvertTo-Html -Body ($Summary.Replace("`r`n",'::'), '::', $MaxAge, '::', $MaxCount) -replace '::','<br/>') | Out-String


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

Reply
0 Kudos
Jneagle
Enthusiast
Enthusiast
Jump to solution

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.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

This is a reviewed script that works for me.

# 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

$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

Reply
0 Kudos
Jneagle
Enthusiast
Enthusiast
Jump to solution

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?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
Jneagle
Enthusiast
Enthusiast
Jump to solution

Thanks for your help, with this and my previous post! Much appreciated.

Reply
0 Kudos
vmk2014
Expert
Expert
Jump to solution

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

pastedImage_1.png

Thanks

V

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

That line should be

$SecurePassword = Get-Content C:\automation\creds.txt | ConvertTo-SecureString -AsPlainText -Force


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