Skip to content

Instantly share code, notes, and snippets.

@nmanzi
Created August 8, 2016 01:00
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 nmanzi/b53c3a4dd6f4d3581684031df45edf82 to your computer and use it in GitHub Desktop.
Save nmanzi/b53c3a4dd6f4d3581684031df45edf82 to your computer and use it in GitHub Desktop.
#region Help
# ----------
<#
.SYNOPSIS
OracleZFS-StorageConsumptionReport.ps1 will send an email to a specified address when executed
with a list of projects (according to a filter) and the consumed backup storage for each project.
Highlights:
o Creates a plain but detailed and user-friendly HTML report which is compatible with all modern browsers.
Version History:
[x] Version 1.0 (Release) - 5/08/16
Requirements:
o At least Powershell V3
.DESCRIPTION
OracleZFS-StorageConsumptionReport.ps1 will send an email to a specified address when executed
with a list of projects (according to a filter) and the consumed backup storage for each project.
.PARAMETER Appliances
ZFS storage appliance addresses, single or in array
.PARAMETER APIPort
Configured port number for REST API. Assumes 215.
.PARAMETER APIUsername
Username with permissions to access the ZFS REST API
.PARAMETER APIPassword
Password for the username specified in -APIUsername
.PARAMETER ProjectFilter
Match filter for project names.
.PARAMETER SendMail
Send e-mail option ($true/$false). The default value is "$false".
.PARAMETER SMTPServer
Mail server address.
.PARAMETER SMTPPort
Mail server port. The default value is "25".
.PARAMETER MailTo
A single mail recipient or an array of mail recipients.
.PARAMETER MailFrom
Mail sender address.
.PARAMETER MailFromPassword
Mail sender password for SMTP authentication.
.PARAMETER SMTPServerTLSorSSL
SMTP TLS/SSL option ($true/$false). The default value is "$false".
.EXAMPLE
.\OracleZFS-StorageConsumptionReport.ps1 -Appliances "192.168.0.1","192.168.0.2" -APIUsername "root" -APIPassword "secure" -ProjectFilter "Test" -SMTPServer <server> -MailFrom <Email From> -MailTo <Email To>
.INPUTS
None
.OUTPUTS
Table containing data sent in email.
.NOTES
Author: Nathan Manzi
Website: http://nmanzi.com
Email: nathan@nmanzi.com
Date created: 5/08/16
Last modified: 5/08/16
Version: 1.0
Thanks to http://www.serhatakinci.com for the Hyper-V report the script was based on.
.LINK
http://nmanzi.com
#>
#endregion Help
#region Script Parameters
# -----------------------
[CmdletBinding(SupportsShouldProcess=$True)]
Param (
[parameter(
Mandatory=$true,
HelpMessage='ZFS storage appliance addresses, single or in array')]
[array]$Appliances,
[parameter(
Mandatory=$false,
HelpMessage='Configured port number for REST API. Assumes 215.')]
[string]$APIPort = "215",
[parameter(
Mandatory=$true,
HelpMessage='API Username')]
[string]$APIUsername,
[parameter(
Mandatory=$true,
HelpMessage='API Password')]
[string]$APIPassword,
[parameter(
Mandatory=$true,
HelpMessage='Filter for project name in string format')]
[string]$ProjectFilter,
[parameter(
Mandatory=$false,
HelpMessage='Enable Send Mail (This is just a switch, value can not be assigned)')]
[bool]$SendMail = $false,
[parameter(
Mandatory=$false,
HelpMessage='SMTP Server Address (Like IP address, hostname or FQDN)')]
[string]$SMTPServer,
[parameter(
Mandatory=$false,
HelpMessage='SMTP Server port number (Default 25)')]
[int]$SMTPPort = "25",
[parameter(
Mandatory=$false,
HelpMessage='Mail To (Recipient e-mail address)')]
[array]$MailTo,
[parameter(
Mandatory=$false,
HelpMessage='Mail From (Sender e-mail address)')]
[string]$MailFrom,
[parameter(
Mandatory=$false,
HelpMessage='For SMTP Authentication (Sender e-mail address password)')]
[string]$MailFromPassword,
[parameter(
Mandatory=$false,
HelpMessage='SMTP TLS/SSL option ($true/$false). The default is "$false".')]
[bool]$SMTPServerTLSorSSL = $false
)
#endregion
#region Functions
#----------------
#endregion
#region Program
#--------------
$htmlEmailHead = "
<style>
body{
width:100%;
min-width:1024px;
font-family: Verdana, sans-serif;
font-size:14px;
/*font-weight:300;*/
line-height:1.5;
color:#222222;
background-color:#fcfcfc;
}
p{
color:222222;
}
strong{
font-weight:600;
}
h1{
font-size:30px;
font-weight:300;
}
h2{
font-size:20px;
font-weight:300;
}
#ReportBody{
width:95%;
height:500;
/*border: 1px solid;*/
margin: 0 auto;
}
table{
width:100%;
min-width:1010px;
/*table-layout: fixed;*/
border-collapse: collapse;
border: 1px solid #ccc;
/*margin-bottom:15px;*/
}
table tr:nth-child(odd){
background:#F9F9F9;
}
/*Row*/
tr{
font-size: 12px;
}
/*Column*/
td {
padding:10px 8px 10px 8px;
font-size: 12px;
border: 1px solid #ccc;
text-align:center;
vertical-align:middle;
}
/*Table Heading*/
th {
background: #f3f3f3;
border: 1px solid #ccc;
font-size: 14px;
font-weight:normal;
padding:12px;
text-align:center;
vertical-align:middle;
}
</style>"
$htmlEmailBody = "
<h1>$ProjectFilter - Tier-1 Storage Consumption Report</h1>
<hr/>
<h2>This report details Tier-1 storage consumed by $ProjectFilter.</h2>
<p>Note: 'StorageConsumedGB' does not include any reserved space, this is accounted for in 'StorageBillableGB'."
$htmlEmail = $null
$Report = @()
$APIAuth = [System.Text.Encoding]::UTF8.GetBytes($APIUsername + ":" + $APIPassword)
$APIEncodedAuth = [System.Convert]::ToBase64String($APIAuth)
$APIHeaders = @{"Authorization" = "Basic $APIEncodedAuth"}
# Specify the parameters
$ZFSProjectFilter = $ProjectFilter
# Specify the API function
$APIURI = "/api/storage/v1/projects"
# Build the table
$table = New-Object system.Data.DataTable("StorageConsumption")
$cols = @("Project","StorageConsumedGB","SnapshotConsumedGB","StorageBillableGB")
foreach ($col in $cols) {
$table.Columns.Add($col) | Out-Null
}
# Iterate through the supplied appliance addresses and pull data
foreach ($Appliance in $Appliances) {
# Form and make the API Request
$APIREQ = "https://$Appliance`:$APIPort/$APIURI"
$APIRESP = Invoke-RestMethod -Uri $APIREQ -Headers $APIHeaders -Method Get
# Process the data...
$projectList = $APIRESP.projects | ?{$_.canonical_name -match $ZFSProjectFilter}
foreach ($project in $projectList) {
Write-Debug $project
$row = $table.NewRow()
$row.Project = $project.canonical_name
$spaceUsed = $project.space_data / 1GB
$snapshotUsed = $project.space_snapshots / 1GB
$spaceTotal = $project.space_total / 1GB
$row.StorageConsumedGB = [math]::Round($spaceUsed, 2)
$row.SnapshotConsumedGB = [math]::Round($snapshotUsed, 2)
$row.StorageBillableGB = [math]::Round($spaceTotal, 2)
$table.Rows.Add($row)
}
}
$Report = $table | Sort-Object Project -Descending
#Now we select those values of interest to us and convert the lot into HTML, assigning the styling we defined at the beginning of this script too.
$htmlEmail = $Report | Select Project, StorageConsumedGB | ConvertTo-HTML -head $htmlEmailHead -body $htmlEmailBody
if ($htmlEmail) {
Write-Debug "Report generated, sending email..."
} else {
Write-Debug "Something went wrong. Exiting."
Break
}
#endregion
#region Send Mail
#---------------
if ($SendMail -or $SMTPServer)
{
if ($SMTPServer -and $MailFrom -and $MailTo -and $htmlEmail)
{
$subject = "Backup Storage Consumption Report"
$MailTo = ($MailTo -join ',').ToString()
$mailMessage = New-Object System.Net.Mail.MailMessage
$mailMessage.subject = $subject
$mailMessage.to.add($MailTo)
$mailMessage.from = $MailFrom
$mailMessage.body = $htmlEmail
$mailMessage.IsBodyHtml = $true
$smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
if ($MailFromPassword)
{
$smtp.UseDefaultCredentials = $false
$smtp.Credentials = New-Object System.Net.NetworkCredential($MailFrom, $MailFromPassword);
}
if ($SMTPServerTLSorSSL)
{
$smtp.EnableSSL = $true
}
$smtpSendResult = 1
Try
{
$smtp.send($mailMessage)
}
Catch
{
Write-Error -Message "E-Mail could not be sent"
$smtpSendResult = 0
}
if ($smtpSendResult -eq 1)
{
Write-Debug -Message "E-mail has been sent to the address(es): $MailTo"
}
Remove-Variable -Name smtp
Remove-Variable -Name MailFromPassword
}
}
#endregion
return $table
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment