Powershell to Email Disk Usage Report

I use a couple of different technologies to store large quantites of data on my “server” at home, namely Storage Pools combined with Data Deduplication on Windows Server 2012 R2. Up to a couple of weeks ago it was working great but I’ve started to notice oddities which couldn’t really be explained…

So I decided to script up a quick report and then schedule it to email me. This is how I did it.

First, finding out the amount of free space on three physical drives that make up a Storage Pool. It was easy enough to find out how you’d find space of volumes, but not the underlying space on the physical drives, and I’ll have to be honest here, I spent a couple of hours trying to figure it out but had to resort to Serverfault.com (a member of the stackoverflow Q&A sites, a really fantastic resource).

The result of the question was this little scriptlet:

1Get-StoragePool 'MyPool' | Get-PhysicalDisk | Select FriendlyName,@{L='Capacity';E={"{0:N2}TB" -f ($_.Size/1TB)}},@{L='Free Space';E={"{0:N2}TB" -f (($_.Size-$_.AllocatedSize)/1TB)}} | Sort 'Free Space'

Good starter for 10 that.

Next, the volume data:

1Get-Volume | select DriveLetter,FileSystemLabel,@{Name="FreeSpace";Expression={"{0:N1} GB" -f($_.SizeRemaining/1gb)}}

..and the datadeuplication statistics we can simply get from this cmdlet, after we’ve done an import-module deduplication:

1Get-DedupStatus

So that’s the content of the message. How do we email it out? A bit more searching on the web found this gem:

 1$param = @{
 2    SmtpServer = 'smtp.gmail.com'
 3    Port = 587
 4    UseSsl = $true
 5    Credential  = 'you@gmail.com'
 6    From = 'you@gmail.com'
 7    To = 'someone@somewhere.com'
 8    Subject = 'Sending emails through Gmail with Send-MailMessage'
 9    Body = "Check out the PowerShellMagazine.com website!"
10}
11
12Send-MailMessage @param

Notice how we configure an object containing all of the parameters of the message and send them to the Send-MailMessage cmdlet.

Now, my main issue with this snippet, was that it required an interactive dialog to input a user credential to talk to Gmail. So bit of work was required here.I took out the Credential property in the parameter and instead created a secure credential within the script and simply passed it in as a command line option instead:

1$secpasswd = ConvertTo-SecureString "securePassword" -AsPlainText -Force
2$mycreds = New-Object System.Management.Automation.PSCredential ("test@gmail.com", $secpasswd)
3
4Send-MailMessage @param -Credential $mycreds]

So we’ve got all of the components now of what we want to do, what did the final script look like?

 1$param = @{
 2    SmtpServer = 'smtp.gmail.com'
 3    Port = 587
 4    UseSsl = $true
 5    From = 'fromemail@gmail.com'
 6    To = 'myemail@email.com'
 7    Subject = 'Disk Usage Report'
 8}
 9
10#credentials here
11$secpasswd = ConvertTo-SecureString "securepassword" -AsPlainText -Force
12$mycreds = New-Object System.Management.Automation.PSCredential ("fromemail@gmail.com", $secpasswd)
13
14#import dedup module
15import-module deduplication
16
17#start creating content of email
18$body0 = "Physical Disk Space`r`n--------------------"
19$body1 = Get-PhysicalDisk | Select FriendlyName,@{L='Capacity';E={"{0:N2}TB" -f ($_.Size/1TB)}},@{L='Free Space';E={"{0:N2}TB" -f (($_.Size-$_.AllocatedSize)/1TB)}} | Sort 'Free Space'|Format-List|out-string
20$body2 = "Volume Space`r`n--------------------"
21$body3 = Get-Volume | select DriveLetter,FileSystemLabel,@{Name="FreeSpace";Expression={"{0:N1} GB" -f($_.SizeRemaining/1gb)}}|format-list|out-string
22$body4 = "DataDedup Status`r`n--------------------"
23$body5 = Get-DedupStatus | format-list | out-string
24
25#smush all that data together
26$finalbody = $body0+$body1+$body2+$body3+$body4+$body5
27
28#..and send.
29Send-MailMessage @param -Credential $mycreds -Body $finalbody

Look at the end of the powershell datacollection lines, I wanted a nice easy to read format for the mail so I’ve sent it through a format-list and also an out-string. If you don’t do the out-string, it’ll error saying it can’t assign an object to a string.

So, I tested this on the command line, and magically got an email out.

How do we use task scheduler now to run it weekly?

Start > Run…. mmc.exe File > Add/Remove Snap In

Scroll down to Task Schedler and click Add, choose Local Computer and click OK

Go back to the mmc windows now and highlight the task scheduler library and set up a new task. Done