Automation

 View Only
Expand all | Collapse all

Snapshot report

  • 1.  Snapshot report

    Posted Aug 25, 2022 03:20 AM

    I got a snapshot report that is designed to show VM's with snapshots that are 5 days old and then show the description of the snapshot, the size of the snapshot, the date it was created, the age, and the creator of the snapshot and I am not sure it is working.  It is showing some VMs with no snapshots at all and rarely shows some of the details I was trying to pull.  Here is the script:

    #############################
    # Variables #
    #############################
    $date = Get-Date -format "yyyy-MMM-dd"
    $datetime = Get-Date
    $filelocation = "\var\www\Snapshots\snapshot-$date.htm"

    #############################
    # Content #
    #############################

    $timeDiff = 2
    $report = Get-View -ViewType VirtualMachine -Filter @{'Runtime.PowerState'='poweredOn';'Snapshot'=".+"} |
    Select -First 50 name,
    @{N='Description';E={
    function Get-Snap{
    param([PSObject]$snap)
    $snap
    if($snap.ChildSnapshotList){
    $snap.ChildSnapshotList | %{
    Get-Snap -Snap $_
    }
    }
    }
    $script:snaps = $_.Snapshot.RootSnapshotList |
    where{$_.CreateTime -le (Get-Date).AddDays(-5) | % {
    Get-Snap -Snap $_ }
    }
    ($script:snaps | sort-Object -property Name).Name -join '|'}},
    @{N='Size';E={
    ((Get-VM -Name $_.Name | Get-Snapshot -Name $script:snaps.Name).SizeGB | %{"{0:N1}" -f $_}) -join '|'
    }},
    @{N='Date Created';E={($script:snaps | sort-Object -property Name).CreateTime -join '|'}},
    @{N="Age";E={
    $now = Get-Date
    ($script:snaps | %{(New-TimeSpan -End $now -Start $_.CreateTime).Days}) -join '|'}},
    @{N='Created By';E={
    $startEvents = $script:snaps.CreateTime
    $start = $startEvents | Sort-Object | Select -First 1
    (Get-VIEvent -Entity $_.Name -Start $start.AddSeconds(- $timeDiff) -MaxSamples ([int]::MaxValue) |
    Where-Object {$_ -is [VMware.Vim.TaskEvent] -and $_.Info.DescriptionId -eq 'VirtualMachine.createSnapshot'} |
    ForEach-Object -Process {
    $event = $_
    $startEvents | ForEach-Object -Process {
    if([math]::Abs((New-TimeSpan -Start $event.CreatedTime -End $_.ToLocalTime()).TotalSeconds) -lt $timeDiff){
    $event
    }
    }
    } | Select-Object -ExpandProperty UserName) -join '|'}}

    ## Build Count Var
    $count = $report | where{$_.Snapshot -ne ''}

    #############################
    # Add Text to the HTML file #
    #############################
    $report | where{$_.Snapshot -ne ''} | ConvertTo-Html –Title "VMware Snapshot Check " –Body "<H1>VMware Snapshot Check</H1>" -Head "<link rel='stylesheet' href='style.css' type='text/css' />" | Out-File $filelocation
    ConvertTo-Html –title "VMware Snapshot Check " -body "<H4>Date and time</H4>",$datetime -head "<link rel='stylesheet' href='style.css' type='text/css' />" | Out-File -Append $filelocation
    ConvertTo-Html –title "VMware Snapshot Check " -body "<H4>VM Count</H4>",$count.Count -head "<link rel='stylesheet' href='style.css' type='text/css' />" | Out-File -Append $filelocation



  • 2.  RE: Snapshot report

    Posted Aug 25, 2022 06:57 AM

    You have to be a bit more specific on the "rarely shows some of the details I was trying to pull".
    Which properties are not shown?
    Note that the script uses events to obtain additional info on the snapshots.
    If the event for a snapshot does not exist anymore, that info can not be retrieved.

    To check why it shows VMs without Snapshots, you will have to check if the following returns such VMs.

    Get-View -ViewType VirtualMachine -Filter @{'Runtime.PowerState'='poweredOn';'Snapshot'=".+"} |
    Select Name,@{N='Snapshots';E={$_.Snapshot.Count}}


  • 3.  RE: Snapshot report

    Posted Aug 25, 2022 02:38 PM

    ok I think the issue is its not applying the filter to show snapshots that are 5 days old.  That command is showing some VMs with snapshots but they are not past that expiration date.



  • 4.  RE: Snapshot report

    Posted Aug 26, 2022 11:20 AM

    The Get-View is returning any VMs that are powered on and that do have a snapshot.

    Only in the Description calculated property, the script limits the traversal of the root snapshot tree to entries that are 5 or more days old.

    This script will not be limited to snapshots that are 5 days or older



  • 5.  RE: Snapshot report

    Posted Aug 26, 2022 02:47 PM

    How do I fix it?



  • 6.  RE: Snapshot report

    Posted Aug 26, 2022 04:35 PM

    You tell me.
    You apparently used my script from Re: PowerCLI SnapShot Creator in Report - VMware Technology Network VMTN and added that Where-clause.
    You must have had an idea what that Where-clause was supposed to be doing?

    Also, note that the script only looks at the first 50 VM returned by Get-View.



  • 7.  RE: Snapshot report

    Posted Sep 01, 2022 06:41 PM

    I am trying to only look at snapshot that are older than 5 days, but not sure I did it right or where to filter it at.



  • 8.  RE: Snapshot report

    Posted Sep 05, 2022 09:50 AM

    Here's a script I use with Saved Credentials in a secure cred file and run with Task scheduler to delete snapshots older than 3 days:

     

    Import-Module VMware.PowerCLI
    
    #Make sure invalid certificate errors don't halt the script
    Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -confirm:$false
    #Turn off CEIP
    Set-PowerCLIConfiguration -Scope User -ParticipateInCEIP $false -confirm:$false
    
    #Interactive use
    #connect-viserver -Server <vcenter IP or name> -Verbose
    
    #Script use
    $creds = Get-VICredentialStoreItem -file "C:\Scripts\vmware\vmservicecred.xml"
    Connect-viserver -Server $creds.Host -User $creds.User -Password $creds.Password
    
    
    :: Delete snapshots older than 3 days ::
    Get-VM | Get-Snapshot | Where {$_.Created -lt (Get-Date).AddDays(-3)} | Remove-Snapshot -Confirm:$false

    You can just delete or comment out "Remove-Snapshot -Confirm:$false" from the last like and run the script interactively. Adjust to the number of days you want.



  • 9.  RE: Snapshot report

    Posted Sep 05, 2022 09:53 AM

    Here' another script that can be run interactively or as a scheduled task to Email a formatted report of all snapshots:

    #$vCenterServer = "<IP or Name>"
    
    # Connect to the vcenter server
    #connect-viserver -Server $vCenterServer -Verbose
    
    #Script use
    $creds = Get-VICredentialStoreItem -file “C:\Scripts\vmservicecred.xml”
    Connect-viserver -Server $creds.Host -User $creds.User -Password $creds.Password
    
    # Set Email Variables
    $fromemail = "vcenter@domain.tld"
    $users = "vcadmin@doman.tld"
    $server = "smtp.domain.tld"
    $subject = "VMware Snapshot Report for " + (get-date -Format d/M/yyyy)
    #---uncomment to use email authentication---#
    #$username = ""
    #$smtppassword = ""
    #$secpasswd = ConvertTo-SecureString $smtppassword -AsPlainText -Force
    #$smtpCredential = New-Object System.Management.Automation.PSCredential ($smtpusername, $secpasswd) 
    
    #Get all snapshots
    $Snapshots = Get-VM | Get-Snapshot | select Description,Created,VM,SizeMB,SizeGB
    
    # Format snapshot Size
    function Get-SnapshotSize ($Snapshot)
    {
        if ($snapshot.SizeGB -ge "1")
        {
            $Snapshotsize = [string]([math]::Round($snapshot.SizeGB,3)) + " GB"
            }
            else {
            $Snapshotsize = [string]([math]::Round($snapshot.SizeMB,3)) + " MB"
            }
       Return $Snapshotsize
    }
    
    # Style the dates - colourise 
    function set-SnapshotDate ($snapshot)
    {
        $greenValue = (get-date).AddDays(-1)
        $RedValue = (get-date).AddDays(-3)
        
        if ($snapshot.created -gt $greenValue)
            {
                $backgroundcolor = "green"
            }
        elseif ($snapshot.Created -lt $greenValue -and $snapshot.Created -gt $RedValue)
            {
                $backgroundcolor = "yellow"
            }
        else 
            {
            $backgroundcolor = "red"
            }
        return $backgroundcolor
    }
    
    #Format the HTML
    function Format-HTMLBody ($body)
    {
        $newbody = @()
        foreach ($line in $body)
        {
            ## Remove the Format Header
            if ($line -like "*<th>Format</th>*")
                {
                    $line = $line -replace '<th>Format</th>',''
                }
            ## Format all the Red rows
            if ($line -like "*<td>red</td>*")
                {
                    $line = $line -replace '<td>red</td>','' 
                    $line = $line -replace '<tr>','<tr style="background-color:Tomato;">'
                }
            ## Formating all the Yellow Rows
            elseif ($line -like "*<td>yellow</td>*")
                {
                    $line = $line -replace '<td>yellow</td>','' 
                    $line = $line -replace '<tr>','<tr style="background-color:Orange;">'
                }
            ## Formating all the Green Rows
            elseif ($line -like "*<td>green</td>*")
                {
                    $line = $line -replace '<td>green</td>','' 
                    $line = $line -replace '<tr>','<tr style="background-color:MediumSeaGreen;">'
                }
            ## Building the new HTML file
                $newbody += $line
        }
        return $newbody
    }
    
    # --------------------------------Create the report-------------------------------- #
    # ----------Header and Style-------------- #
    $date = (get-date -Format d/M/yyyy)
    $header =@"
     <Title>Snapshot Report - $date</Title>
    <style>
    body {   font-family: 'Helvetica Neue', Helvetica, Arial;
             font-size: 14px;
             line-height: 20px;
             font-weight: 400;
             color: black;
        }
    table{
      margin: 0 0 40px 0;
      width: 100%;
      box-shadow: 0 1px 3px rgba(0,0,0,0.2);
      display: table;
      border-collapse: collapse;
      border: 1px solid black;
    }
    th {
        font-weight: 900;
        color: #ffffff;
        background: black;
       }
    td {
        border: 0px;
        border-bottom: 1px solid black
        }
    </style>
    "@
    # ----------Header and Style-------------- #
    
    # Create title for the Table
    $PreContent = "<H1> Snapshot Report for " + $date + "</H1>"
    
    # Convert to HTML
    $HTMLmessage = $Snapshots | select VM,Created,@{Label="Size";Expression={Get-SnapshotSize($_)}},Description,@{Label="Format";Expression={Get-SnapshotDateStyle($_)}}| sort Created -Descending | ConvertTo-Html -Head $header -PreContent $PreContent
    
    # -------Formay the HTML Report ------------- #
    $Report = Format-HTMLBody ($HTMLmessage)
    
    # --------------------------------Create the report-------------------------------- #
    
    # Email report
    send-mailmessage -from $fromemail -to $users -subject $subject -BodyAsHTML -body ([string]$Report) -priority Normal -smtpServer $server #-Credential $smtpCredential
    
    # Logoff the server
    Disconnect-VIServer -Confirm:$false


  • 10.  RE: Snapshot report

    Posted Oct 05, 2023 03:58 AM

    Can anyone help to modify this script to add more 3 rows for the datastore name, datastore size, datastore free size



  • 11.  RE: Snapshot report

    Posted Jan 24, 2024 07:38 AM

    Can help to modify this script to add more column for datastore size, datastore free space & VM size 



  • 12.  RE: Snapshot report

    Posted Sep 05, 2022 10:15 AM

    The procedure to create a saved credential file is as follows:

    The credential file creation must be done in the context of the user that will be reading the saved and encrypted credentials.

    This user needs VM power user permission in vCenter and runasbatch in windows. 

    1. Open CMD prompt / powershell window
    2. Execute: "runas /noprofile /user:"{username}" powershell.exe
      1. Enter the password
      2. This will open powershell console as the user specified.
    3. Execute the powerCLI command, "New-VICredentialStoreItem" command, specify the Username and password.

    #> New-VICredentialStorItem -host <IP or name of vCenter> -User "DOMAIN\VCAdmin" -password "<accountpassword>" -file c:\script\vmservicecred.xml



  • 13.  RE: Snapshot report

    Posted Sep 05, 2022 10:20 AM

    You are aware that the VICredentialStore does not work on PSv7?



  • 14.  RE: Snapshot report

    Posted Sep 05, 2022 11:06 AM

    Hi ,

    No I was not aware of that.

    What command should you use as a replacement?

    All these scripts run with  6.7.



  • 15.  RE: Snapshot report

    Posted Sep 05, 2022 11:39 AM

    There is no PowerCLI native solution, but there are others like the SecretManagement and SecretStore modules.
    They require a bit more work but the SecretStore module allows one to plug in some of the more common secret storage solutions.