Skip to content

Instantly share code, notes, and snippets.

@lucashalbert
Last active April 8, 2019 14:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lucashalbert/6ee0373df57e6218aae798f387c4012c to your computer and use it in GitHub Desktop.
Save lucashalbert/6ee0373df57e6218aae798f387c4012c to your computer and use it in GitHub Desktop.
Creates an HTML snapshot report from the specified vSphere/vCenter server.
<#
####################################################################################
#
# Author: Lucas Halbert <contactme@lhalbert.xyz>
# Date Written: 4/24/2018
# Date Modified: 04/08/2019
# Version: 2019.04.08
# Description: Creates an HTML snapshot report from the specified
# vSphere/vCenter server. This script requires that the VMware
# PowerCLI module to be installed and loaded.
# Note: If connecting to vCenter fails with an "Error: Invalid server
# certificate" error, run the command 'Set-PowerCLIConfiguration
# -InvalidCertificateAction Prompt' in order to prompt for user
# verification on self-signed/invalid certificates.
# License: BSD 3-Clause License
#
# Copyright (c) 2018, Lucas Halbert
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and#or other materials provided with the distribution.
#
# * Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
####################################################################################
#
# Revisions: 2019.04.08 - Add function to check for pre-requisites.
#
# 2018.11.15 - Add parameters for server and filename
#
# 2018.10.30 - functionalize all commands in script and fix styling
#
# 2018.04.24 - Inital draft
#
####################################################################################
#>
# Gather paramters
param(
[Parameter(Mandatory=$true)][string]$server,
[Parameter(Mandatory=$true)][string]$filename
)
# Define function to convert HTML Escapes
Function Convert-HTMLEscape {
<#
convert &lt; and &gt; to < and > It is assumed that these will be in pairs
#>
[cmdletbinding()]
Param (
[Parameter(Position=0,ValueFromPipeline=$True)]
[string[]]$Text
)
Process {
foreach ($item in $text) {
if ($item -match "&lt;") {
(($item.Replace("&lt;","<")).Replace("&gt;",">")).Replace("&quot;",'"')
} Else {
#otherwise just write the line to the pipeline
$item
}
}
}
}
# Define function to set alternating rows
Function Set-AlternatingRows {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True,ValueFromPipeline=$True)]
[string]$Line,
[Parameter(Mandatory=$True)]
[string]$CSSEvenClass,
[Parameter(Mandatory=$True)]
[string]$CSSOddClass
)
Begin {
$ClassName = $CSSEvenClass
}
Process {
If ($Line.Contains("<tr>")) {
$Line = $Line.Replace("<tr>","<tr class=""$ClassName"">")
If ($ClassName -eq $CSSEvenClass) {
$ClassName = $CSSOddClass
} Else {
$ClassName = $CSSEvenClass
}
}
Return $Line
}
}
# Function to set style
Function Set-Style {
# Define all Style tags
$style = "<style>
TABLE{border-width: 1px;border-style: solid;border-color:black;}
TABLE{background-color:#EFFFFF;border-collapse: collapse;}
TH{border-width:1px;padding:5px;border-style:solid;border-color:black;background-color:#DDDDDD;}
TD{border-width:1px;padding-left:5px;padding-right:3px;border-style:solid;border-color:black;}
.odd { background-color:#ccddee;}
.even { background-color:#eeeeff;}
</style>"
Return $style
}
Function Get-SnapshotData {
$style = Set-Style
Get-VM | ForEach {
$vm = $_
$_ | Get-Snapshot | Select @{Label="Host";Expression={$vm.VMHost}},VM,Name,Description,@{Label="Size";Expression={"{0:N2} GB" -f ($_.SizeGB)}},Created | Select Host,VM,Name,Description,Size,Created
} | ConvertTo-Html -Head $style -PreContent "<p><h2>Snapshot Report - $server</h2></p><br>" | Set-AlternatingRows -CSSEvenClass even -CSSOddClass odd | Convert-HTMLEscape | Out-File $filename
}
Function Connect-vCenter($server) {
# Connect to vCenter
Write-Host -NoNewline "Connecting to vCenter..."
Connect-VIServer $server -Protocol https |out-null
if(!$?){
Write-Host -ForegroundColor Red "Could not connect to $server"
exit 2
} else {
Write-Host "Connected to vCenter host"
Get-SnapshotData
}
}
Function Check-PreRequisites() {
# Check if VMware.PowerCLI module is available for import (ie: installed)
if (!(Get-Module -ListAvailable -Name VMware.PowerCLI)) {
Write-Host -ForegroundColor Yellow "This script requires the VMware.PowerCLI Module to be installed."
Write-Host -ForegroundColor Yellow "Please install the module by running the command 'Install-Module -Name VMware.PowerCLI -Scope CurrentUser'"
Return $false
# Check if Vmware.PowerCLI module is loaded
} elseif (!(Get-Module -Name VMware.PowerCLI)) {
Write-Host -ForegroundColor Yellow "This script requires the VMware.PowerCLI Module to be loaded."
Write-Host -ForegroundColor Yellow "Please load the module by running 'Import-Module VMware.PowerCLI -Verbose'"
Return $false
} elseif (Get-Module -Name VMware.PowerCLI) {
Return $true
} else {
Return $false
}
}
# Check if pre-requisites are met
if (!(Check-PreRequisites)) { exit 3 }
if (!$global:DefaultVIServers.Count -gt 0) {
Write-Host "Connecting to $server"
Connect-vCenter $server
} elseif (!$global:DefaultVIServer[0].name.Equals($server)) {
Write-Host "Connecting to $server"
Connect-vCenter $server
} else {
Write-Host "Fetching snapshot data"
Get-SnapshotData
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment