Gary's $this and that about PowerShell and Exchange

I am a Microsoft Senior Premier Field Engineer based out of Atlanta, GA. My focus is on Exchange Server and Powershell. This blog is mainly to share interesting Powershell script samples and tidbits about Exchange. I am a Microsoft Certified Master for

Get Exchange Mailbox Database Size – One-Liner – Version 2

Get Exchange Mailbox Database Size – One-Liner – Version 2

  • Comments 1
  • Likes

In my previous post (Some Handy Exchange Mailbox and Database Size Powershell One-Liners), I introduced a handy one-liner for looking up current mailbox database sizes.  In Exchange 2007, the physical size of the database file isn't listed when you run a cmdlet like “get-mailboxdatabase”.  This piece of information of course is of great interest to many admins out there.  My first post worked pretty well against stand-alone Exchange servers, but had issues with clusters and 2008.  Also, I used my no less preferred method to add the database size to an output object but using “Select-object”.  In this one-liner, I have made a few updates to this one-liner that preserves the original .Net mailboxdatabase object by using “add-member”, and appears to work pretty well with clusters, 2008, stand-alone servers, mount points, …whatever…so far.

Here is one-liner.  You will see that now I am using “add-member” to add a “noteproperty” to the objects in the pipeline.  I ended up doing something slightly abnormal for me.  I performed the “add-member” within a “foreach-object” code block.  Also I added a membertype of “noteproperty” instead of my typical “scriptproperty”.  The truth is both strategies worked fine and yeilded the results I was looking for.  What I discovered during my testing was that if I used a “scriptproperty” there is no error reporting whatsoever if we encounter any errors with the code…in this case a WMI call.  Unfortunately, since we are using WMI, there is a good chance a server may not respond cleanly or quickly.  If WMI times out, then it makes for a poor user experience with zero explanation as to why the data shows up as a big fat 0.  By using a note-property, I can keep the code block out of the .Net member and thus we get to see errors that occur.  I had to use a “foreach-object” loop though to pull this off as now “Add-member” could no longer work in native pipeline mode.

The second fix, is now instead of the using the filesystem provider in PowerShell to retrieve the file size of the database file, I am now using WMI.  Why did I make this choice…simple, I wanted to be able to query the file using the local file path that comes out of the “edbfilepath” properpty on the “mailboxdatabase” objects returned by the “get-mailboxdatabase” cmdlet.  Why use the local path…because that gets me around the path translation I was doing in the previous version of this one-liner.  That translation was why this thing didn't work against clusters.  Now, I simply use WMI to remote the file lookup and thus I can use the local file path, which works now regardless of cluster, mount point, whatever.  I did run into the issue though of having to escape the “\” (backslash) by using them twice in the filter string for the “get-wmiobject” cmdlet, thus you see the replace() method in use.

Special thanks to a few folks that were involved in motivating, testing, and helping me with this code.  Brian Scott, for effectively slapping me across the face about using the filter parameter of “get-wmiobject”, and helping me find CIM_Datafile.  John Carder for motivating me to write this new version and for being a quick tester in his environment where my v1 wouldn't work against his clusters, but this version does.

Enough talk, here is the one-liner:

Get-MailboxDatabase | foreach-object {add-member -inputobject $_ -membertype noteproperty -name mailboxdbsizeinGB -value ([math]::Round(([int64](get-wmiobject cim_datafile -computername $_.server -filter ('name=''' + $_.edbfilepath.pathname.replace("\","\\") + '''')).filesize / 1GB),2)) -passthru} |  Sort-Object mailboxdbsizeinGB -Descending | format-table identity,mailboxdbsizeinGB

Like most of my scripts, I have not extensively tested this as it is merely a demonstration sample and not a production level script.  If you leverage this example to write your own production level code, I would love to hear feedback on how it works for you.  Please, leave comments or email me for anything regarding this post.

-Gary

This posting is provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm.

Comments
  • Used this in an environment report but mailbox sizes are incorrect... if I run the code below I get accurate counts as depicted in the ESM...

    write-host -fore yellow “This script will get each mailboxdatabase and the current user count ”

    foreach($name in get-mailboxdatabase)

    {

    $count=(get-mailbox -database $name).count

    write-host $count -nonewline

    write-host ” mailboxes in $name”

    }

    write-host -fore yellow “The system has a total mailboxes of “$user=(get-mailbox –resultsize unlimited).count

    write-host -fore red $user

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment