Created
August 8, 2016 01:00
-
-
Save nmanzi/b53c3a4dd6f4d3581684031df45edf82 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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