Palm Beach IT User Group – “PowerShell for the Administrator – All About The Language”

Thank once again to the Palm Beach IT User Group for having my presenting live my session “PowerShell for the Administrator – All About The Language” on May 14th evening.   http://itportalregulus.blogspot.com/

The group had the opportunity to see the evolution from a single one-liner command, to a script file, a function, and a brief taste to a module.  Also, the scripts supplied has an abundant of code snippets that can be reused.

Also, giving example of reusing and modifying a community script (Thx, Jefferey Hicks for his contributions) so you can make it your own.

Here’s some reference links: http://jdhitsolutions.com/blog/2012/02/create-html-bar-charts-from-powershell/ and http://jdhitsolutions.com/blog/2011/12/friday-fun-drive-usage-console-graph/

Special Thanks to Sapien Technology for providing some books to giveaway and to Plurasight for the free one month online subscription.

Here’s the end result.  A function that check the machine disk space, build an HTML file with a graph and send an email thru your live.com SMTP server.

function Get-DiskUsageHTMLGraph{
Param(
	[array] $ComputerNames,
	[string] $ReportPath = "c:\Temp\HTML_DiskSpace.html",
	[boolean] $ViewReport,
	[boolean] $SendEmail,
	[Array] $SendTo
)

	## - Set variable (no function):
	$htmlTitle='Server Drive(s) Report'

## - Configuring the HTML CSS Style sheet for the HTML code: (#FFFFCC)
## - When using Here-String/Splatting you must begin in the first position.
## - The use of Tab is invalid.
$head = @"

 $($htmlTitle)

"@

	## - Define the HTML Fragments as an Array type, add the header and title object:
	[Array] $HTMLfragments = $null; $HTMLfragments += $head;
	$HTMLfragments+="</pre>
<h1>Server Disk Space</h1>
<pre>

";

	## - Build WMI Disk information object and group results by ComputerNames:
	$SystemNames = get-wmiobject -Class Win32_logicaldisk -computer $ComputerNames `
		| Group-Object -Property SystemName;

	## - This is the graph character code:
	 [string] $gCode = [char] 9608;

	## - Loop through each computer object found and create html fragments:
	ForEach ($System in $SystemNames)
	{
	    ## - Get the System name:
		$HTMLfragments+="</pre>
<h2>$($System.Name)</h2>
<pre>
"

	    ## - Create an html fragment for each system found:
	     $html = $System.group `
		| Where-Object {$_.DriveType -notmatch '5|2'} | Sort-Object -Property Name `
		| Select-Object `
			SystemName, @{Label = "DriveID";Expression={$_.Name}}, `
			VolumeName, FileSystem, DriveType, `
	        @{Label="DiskSizeGB";Expression={"{0:N}" -f ($_.Size/1GB) -as [float]}}, `
	        @{Label="FreeSpaceGB";Expression={"{0:N}" -f ($_.FreeSpace/1GB) -as [float]}}, `
	        @{Label="PercFree";Expression={"{0:N}" -f ($_.FreeSpace/$_.Size*100) -as [float]}}, `
			@{Label="Low				if(($_.FreeSpace/$_.Size*100) -le '15') `
				{ `
					"- Critical -"; `
				} `
				Else `
				{ `
					$null; `
				}; `
			  }}, `
		     @{Name="";Expression={ `
		       $UsedPer = (($_.Size - $_.Freespace)/$_.Size)*100; `
		       $UsedGraph = $gCode * ($UsedPer/2); `
		       $FreeGraph = $gCode * ((100-$UsedPer)/2); `
		       "xltFont color=Redxgt{0}xlt/FontxgtxltFont Color=Greenxgt{1}xlt/fontxgt" `
					-f $usedGraph,$FreeGraph; `
	     }} | ConvertTo-Html -Fragment;

	    ## - Replacing replace the tag place holders: (Jefferey's hack at work)
	    $html=$html -replace 'xlt','
	    ##  - Add the Disk information results to the HTML fragment:
	     $HTMLfragments+=$html;

	    ## - Insert a line break for each computer it find:
	     $HTMLfragments+="
";
	}

	## - Add a footer to HTML code:
	$footer=("
<em>Report run {0} by {1}\{2}<em>" -f (Get-Date -displayhint date),$env:userdomain,$env:username)
 $HTMLfragments+=$footer

 ## - Write HTML code to a file on disk:
 ConvertTo-Html -head $head -body $HTMLfragments | Out-File $ReportPath;

 if($ViewReport -eq $true)
 {
 ii $ReportPath;
 }

 if($SendEmail -eq $true)
 {
 ## - Setting the information for hotmail:
 $MyEmailAcct = "UserX@live.com";
 $MyPassword = ConvertTo-SecureString '$myPassword!' -AsPlainText -Force;
 $MyCredentials = new-object -typename System.Management.Automation.PSCredential -argumentlist $MyEmailAcct,$MyPassword
 [Array] $emaillist = @('User1@gmail.com','UserX@live.com');

 ## - OR, send it as a body message in the email:
 $GetError = $null;
 Send-MailMessage `
 -From 'MySysAdmin-DoNotReply@MySysAdmin.com' `
 -To $SendTo `
 -Subject "Diskspace Information for the date - $((Get-Date).ToString("MMddyyyy, HH:MM"))" `
 -BodyAsHtml ([string] (ConvertTo-Html -head $head -body $HTMLfragments)) `
 -SmtpServer 'smtp.live.com' `
 -Credential $MyCredentials `
 -UseSsl `
 -Port 587 `
 -ErrorAction SilentlyContinue `
 -ErrorVariable GetError;

 if($GetError -ne $null)
 {
 $date = (get-Date).ToString("MMddyyyy_HHMMss");
 "Sender: $($getCred1.UserName) `r`n $GetError" | `
 Out-File -FilePath "C:\Temp\log\emailerror_$date.txt";
 };
 };
};

Sample results for email to live.com:

Sample Browser:

Here’s the zipped presentation link: