View Only
  • 1.  snapshot report modification - need help from the experts

    Posted Apr 11, 2014 07:38 AM

    Hi Guys,

    I found a great snapshot reporting, credits to the owners for sharing this. I just need help to optimize this script to run faster and add a few items.

    Probably using get-view will make it run faster?

    things that i need added.

    1. cluster name

    2. esxi host

    2. datastore where the snapshot is located.

    3. filename of the snapshot

    here's the code:



        Simple HTML report showing all snapshots on your VMware vSphere



        Run this script to produce a simple HTML report showing all the

        snapshots in your vSphere environment.  This script is designed to

        run without prompting you for credentials, saving the password in

        a (mostly) secure, encrypted file.  You must run the script once

        manually to produce the proper credential file before putting it

        into a scheduled task.


        You must modify the $Key variable below to get unique encryption,

        otherwise anyone who downloads this script would have the same encryption

        key you do!


        Credit to Daniel for the idea of using a unique key value in the

        ConvertTo-SecureString cmdlet allowing multiple computers to use this

        credential file.



        Requires VMware PowerCLI be installed.


        *** IMPORTANT ***

        Required:  Modify the $Key variable to get unique encryption on your



        Idea for the unique


        Name of your vSphere vCenter server, or the name of your ESXi host.

    .PARAMETER Admin

        Name of the administrative account needed to authenticate to vSphere.

    .PARAMETER PathToCredentials

        Path where the script will save the credential file.

    .PARAMETER PathToReport

        Path where the HTML report will be saved.


        Who the emailed report is going to


        Who the emailed report is coming from


        The IP address or name of the SMTP relay you want to use


        .\Report-Snapshots.ps1 -VIServer VCenter1 -Admin Administrator -PathToCredentials \\server\share\cred -PathToReport \\server\share\reports


        Create a report of all the snapshots of VM's under the control of the

        VCenter1 vCenter server.  You will authenticate using the Administrator

        account and save the credential file on "server", in the share called

        "share" and the directory "cred".  The resulting HTML report will be

        saved on the same server and share, but in the directory "reports".


        .\Report-Snapshots.ps1 -VIServer VCenter1 -Admin Administrator -PathToCredentials \\server\share\cred -PathToReport \\server\share\reports -To "" -From "" -SMTPServer "MyExchange1"


        Same as the example above, but overriding the default mailing parameters

        to send to, from and using the MyExchange1

        server to relay the email.




        HTML Report:  SnapshotReport.HTML


        Author:            Martin Pugh

        Key Idea:          Daniel (

        Twitter:           @thesurlyadm1n

        Spiceworks:        Martin9700




           1.2             Updated Get-Credentials function to support domain level credentials in the

                           domainname\username format.

           1.1             By request added a calculation on how old the snapshot is in days. Discovered

                           a "bug" when running the script on a VMware 4.1 system: the

                           SizeGB property does not exist!  Changed to use SizeMB and then manually

                           calculate the snapshot size in GB. Added some better error trapping.  Also

                           parameterized the email settings.

           1.0             Initial Release




    Param (


        [string]$VIServer = "vcenter",

        [string]$Admin = "test",

        [string]$PathToCredentials = "C:\test\creds",

        [string]$PathToReport = "C:\test\report",


        [string]$To = "",

        [string]$From = "",

        [string]$SMTPServer = "testsmtpserver"


    #You must change these values to securely save your credential files

    $Key = [byte]29,36,18,22,72,33,85,52,73,44,14,21,98,76,18,28

    #region Functions

    Function Get-Credentials {

        Param (

            [String]$AuthUser = $env:USERNAME,



        #Build the path to the credential file

        $CredFile = $AuthUser.Replace("\","~")

        $File = $PathToCred + "\Credentials-$CredFile.crd"

        #And find out if it's there, if not create it

        If (-not (Test-Path $File))

        {    (Get-Credential $AuthUser).Password | ConvertFrom-SecureString -Key $Key | Set-Content $File


        #Load the credential file

        $Password = Get-Content $File | ConvertTo-SecureString -Key $Key

        $AuthUser = (Split-Path $File -Leaf).Substring(12).Replace("~","\")

        $AuthUser = $AuthUser.Substring(0,$AuthUser.Length - 4)

        $Credential = New-Object System.Management.Automation.PsCredential($AuthUser,$Password)

        Return $Credential


    Function Set-AlternatingRows {












         Begin {

             $ClassName = $CSSEvenClass


         Process {

             [string]$Line = $HTMLDocument

             $Line = $Line.Replace("<tr>","<tr class=""$ClassName"">")

             If ($ClassName -eq $CSSEvenClass)

             {    $ClassName = $CSSOddClass



             {    $ClassName = $CSSEvenClass


             $Line = $Line.Replace("<table>","<table width=""50%"">")

             Return $Line





    If (-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue))

    {   Try { Add-PSSnapin VMware.VimAutomation.Core -ErrorAction Stop }

        Catch { Write-Host "Unable to load PowerCLI, is it installed?" -ForegroundColor Red; Exit }


    $Cred = Get-Credentials $Admin $PathToCredentials

    Try {

        Connect-VIServer $VIServer -Credential $Cred -ErrorAction Stop | Out-Null


    Catch {

        Write-Host "Error connecting to $VIServer because $($Error[0])" -ForegroundColor Red



    $Header = @"


    TABLE {border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}

    TH {border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color: #6495ED;}

    TD {border-width: 1px;padding: 3px;border-style: solid;border-color: black;}

    .odd  { background-color:#ffffff; }

    .even { background-color:#dddddd; }



    Snapshot Report - $VIServer



    $Report = Get-VM | Get-Snapshot | Select VM,Name,Description,@{Label="Size";Expression={"{0:N2} GB" -f ($_.SizeMB / 1024)}},Created,@{Label="Days Old";Expression={(New-TimeSpan -End (Get-Date) -Start $_.Created).Days}}

    If (-not $Report)

    {   $Report = New-Object PSObject -Property @{

            VM = "No snapshots found on any VM's controlled by $VIServer"

            Name = ""

            Description = ""

            Size = ""

            Created = ""

            'Days Old' = ""



    $Report = $Report |

        Select VM,Name,Description,Size,Created,'Days Old' |

        ConvertTo-Html -Head $Header -PreContent "<p><h2>Snapshot Report - $VIServer</h2></p><br>" |

        Set-AlternatingRows -CSSEvenClass even -CSSOddClass odd

    $Report | Out-File $PathToReport\SnapShotReport.html

    Send-MailMessage -To $To -From $From -Subject "$VIServer Snapshot Report" -Body ($Report | Out-String) -BodyAsHtml -SmtpServer $SMTPServer

  • 2.  RE: snapshot report modification - need help from the experts

    Posted May 08, 2014 07:50 PM

    Well, i have a script that generates what you want. But i use a function which shows the snapshots.

    You can easily call the function passing the Vcenter connection as parameter

    Example: $Report = Get-Snaps (connect-viserver "yourServer")

    Warn me if you want some help modifying it.

    function Get-Snaps(){


          #Filter only Vms which contains Snapshots

          Write-Host "`t Generating Report from Server: $($"

          #Filter Templates and non Snapshotteds Vms

          $vmsWithSnaps = Get-view -viewType VirtualMachine -Property Name,Config.Template,Snapshot -Server $currentVC -Filter @{'Config.Template'='False'}|where{$_.snapshot -ne $null}



                 foreach($vm in $vmswithSnaps){

                    $currVM = $vm|Get-VIObjectByVIView


                            Write-Host "`t`tSnapshots found Here: $($currVM.Name)"

                            $VMsnaps = $currVM | Get-Snapshot

                            $tempReport = $VMsnaps | Select VM,@{N="Vcenter";E={$currentVC.Name}},@{N="Cluster";E={($currVM|get-cluster|select Name).Name}},@{N="Host";E={$currVM.Vmhost.Name}},Name,@{N="PowerState";E={$currVM.PowerState}},Description,Created,SizeGB,Datastores,FileNames,UserName

                            #Get Snapshot Files

                            $snapFiles = Get-HardDisk -Snapshot $VMsnaps

                            #Get who created it

                            $SnapshotEvents = Get-VIEvent -Entity $currVM -type info -MaxSamples 1000 | Where {$_.FullFormattedMessage.contains("Create virtual machine snapshot")}


                                $user = $SnapshotEvents[0].UserName

                            }catch [System.Exception] {

                                $user = $SnapshotEvents.UserName



                                $_.SizeGB = "{0:N2}" -f $tempReport.SizeGB

                                $_.UserName = $user

                                $_.Datastores = ([String]($snapFiles|%{$_.Filename.split("]")[0].split("[")[1]}| select -Unique)).replace(" ",",")

                                $_.FileNames = ([String]($snapFiles|%{($_.FileName).replace(" ","")})).replace(" ",",")






                    #do nothing, let it go



                $tempReport = ""| Select VM,PowerState,Vcenter,Name,Description,Created,SizeGB,UserName

                $tempReport.VM = "No Snapshots found on $($currentVC.Name)"