Generate Exchange Environment Reports using Powershell
Update 17th August - V1.5.4 - New features and bug fixes (see here for more information)
Update 24th July - V1.5.3 - Bug fixes (see here for more information)
Update 21th July - V1.5 - Re-write with new features including Exchange 2003 support for mixed environments and more detailed information (see here for more information)
Update 21th June - V1.1 - Bug fixes, Exchange 2007-only support in addition to 2010/2010+2007, and new features.
As an Exchange administrator, there’s times when it’s useful to have a visual, straightforward and concise document that gives you a good overview of your environment. Although with tools like Visio and Word you can make such a document, it’s hard to keep these documents up to date or use previous versions to track and check changes.
This script, inspired by the output of an Exchange TAP tool, aims to automatically generate a report that gives you an overview of your environment, Exchange 2003, 2007, 2010 servers and database availability groups - in particular:
- Total Servers per Exchange version & service pack
- Total Mailboxes per Exchange version & service pack
- Totals for Exchange roles across the environment
- A site-by-site breakdown for the following:
- Mailboxes per site
- Exchange servers, version, update rollup and version, service level, highlighted installed roles, OS version and service pack
- A breakdown of each Database Availability Group including:
- DAG name, member count and member list
- Database information such as
- Name
- Mailboxes per database and Average Size
- Archive mailboxes per database and Average Size - only shown if a DB includes Archive mailboxes
- Database and whitespace size
- Database and log disk free space percentage
- Last full backup date/time (new) - only shown if at least one DAG DB has had a full backup
- Circular Logging state (new) - only shown if at least one DAG DB has circular logging enabled
- Server hosting the active copy
- List of servers hosting copies and copy count
- A breakdown of Non-DAG databases including Exchange 2007 and 2003 DBs, including the database information above, along with Storage Group name (where applicable).
The script doesn’t support detailed information about Exchange 2007/2003 CCR/SCC clusters, but these are shown as ClusMBX in the output. At the moment, the script doesn’t show Public Folder information but if there is interest I can add extra features; and of course the source is provided should you wish to alter it to your own needs.
To be able to execute the script, you need to use the Exchange Management Shell (the latest version for your environment, with Powershell 2.0) and be able to get information about AD Sites, Exchange Servers, Mailboxes, Database Availability Groups and Databases. It uses WMI to retrieve OS information and detect Exchange 2007 clusters and calculate Exchange 2007 database size and Remote Registy calls to get Update Rollup information. A normal Exchange administrator should be able to perform these tasks.
Executing the script is straightforward – the only setting you need is to specify where to write the HTML file:
GeSHi Error: GeSHi could not find the language powershell (using path /home/content/03/9366303/html/wp-content/plugins/codecolorer/lib/geshi/) (code 2)
If you want it to email the results, the follow parameters are available to allow the report to be sent directly from the script:
GeSHi Error: GeSHi could not find the language powershell (using path /home/content/03/9366303/html/wp-content/plugins/codecolorer/lib/geshi/) (code 2)
Finally, to schedule the report to be generated nightly, execute with your preferred options and add the -ScheduleAs parameter, for example:
GeSHi Error: GeSHi could not find the language powershell (using path /home/content/03/9366303/html/wp-content/plugins/codecolorer/lib/geshi/) (code 2)
After generating the report, it will attempt to schedule the task and prompt (via schtasks.exe) for the password of the user you have chosen to schedule the report as.
As usual, the script is provided below as-is without any warranties. You can download the script ready to use at the bottom of this post. Comments and suggestions are always welcome.
GeSHi Error: GeSHi could not find the language powershell (using path /home/content/03/9366303/html/wp-content/plugins/codecolorer/lib/geshi/) (code 2)
Download Get-ExchangeEnvironmentReport.ps1
Looking for the previous version? Download version 1.1 here
Related posts:



February 2nd, 2012 - 06:50
Thank you for your great script, it saved me a lot of work!
Every time I’m running your script using the parameter –ServerFilter I get a mailbox count of zero. I looked in your script and changed in sections 2.1 every appearance of “Where {$_.Server -like $ServerFilter}” to “Where {$_.Servername -like $ServerFilter}”. Now mailbox counts are correct.
As we have a pure Exchange 2007 environment, I can’t tell if the problem exists for Exchange 2003 and 2010.
January 30th, 2012 - 08:26
Hi Man!
Great Script. Is there a way that it can be sent to more than 1 recipient?
January 27th, 2012 - 17:25
Hi,
THANKS for writing this, it does save a lot of time!! I have a question. I have a small Exchange 2007 environment, and it isnt reporting the white space properly. I see plenty of 1221 event ID’s with the proper data in the event viewer. any ideas?
Thanks!
February 1st, 2012 - 18:29
Hi Rich,
In the next version of the script I’ll be switching to the EventID 1221 method as it is more reliable and I don’t have to re-invent the wheel for the calculations.
Steve
January 6th, 2012 - 09:40
Hi Steve,
Great script. I have an addition to the wish list. – Last Incremental Backup column
Thanks
February 1st, 2012 - 18:41
Hi Andy,
Cheers! I’m planning on a re-write and this is on the list.
Steve
December 29th, 2011 - 13:42
Hi Steve,
i believe this script could be very usefull for mr , but while i am trying to run this script it is showing me the below error , could you please help me out in this..
File D:\Power shell 2.0\Script\Get-ExchangeEnvironmentReport.ps1 cannot be load
ed. The file D:\Power shell 2.0\Script\Get-ExchangeEnvironmentReport.ps1 is not
digitally signed. The script will not execute on the system. Please see “get-h
elp about_signing” for more details..
At line:1 char:2
+ . <<<< '.\Get-ExchangeEnvironmentReport.ps1'
+ CategoryInfo : NotSpecified: (:) [], PSSecurityException
+ FullyQualifiedErrorId : RuntimeException
Thanks
December 29th, 2011 - 14:22
Run Get-ExecutionPolicy.
If it is set to Restricted, change it to RemoteSigned or Unrestricted.
If it is set to RemoteSigned, move the script to a local drive or change it to Unrestricted.
To change the execution policy, use Set-ExecutionPolicy.
December 27th, 2011 - 13:18
Hi, we use this report tool too, very useful.
Unfortunately, in our exchange environment the Database instances are not sorted alphabetically.
Any Ideas?
MAN-EXCH-001 DB_K 82 1,163.78 MB 107.01 GB 0.44 GB 32.81 GB 22.0% 32.81 GB 22.0% Yes (1)
MAN-EXCH-001 DB_G 82 1,241.31 MB 105.63 GB 0.56 GB 35.35 GB 23.7% 35.35 GB 23.7% Yes (1)
MAN-EXCH-001 DB_H 82 1,175.95 MB 103.38 GB 1.01 GB 37.91 GB 25.4% 37.91 GB 25.4% Yes (1)
MAN-EXCH-001 DB_J 82 1,195.55 MB 103.76 GB 1.44 GB 38.38 GB 25.8% 38.38 GB 25.8% Yes (1)
MAN-EXCH-001 DB_L 82 1,210.02 MB 106.51 GB 2.80 GB 35.94 GB 24.1% 35.94 GB 24.1% Yes (1)
MAN-EXCH-001 DB_E 83 1,148.04 MB 103.76 GB 0.04 GB 38.18 GB 25.6% 38.18 GB 25.6% Yes (1)
MAN-EXCH-001 DB_F 83 1,169.19 MB 102.76 GB 0.05 GB 39.63 GB 26.6% 39.63 GB 26.6% Yes (1)
MAN-EXCH-001 DB_I 82 1,200.10 MB 101.38 GB 0.05 GB 99.76 GB 44.3% 99.76 GB 44.3% Yes (1)
MAN-EXCH-001 DB_M 17 1,204.85 MB 24.38 GB 0.01 GB 67.12 GB 45.0% 67.12 GB 45.0% Yes (1)
December 27th, 2011 - 17:21
Have you tried the solution in a post above using the “sort Name” or “sort-object Name” in the right places in the script?
December 23rd, 2011 - 09:25
Dear Steve,
is it possible to add public folder whitespace from exchange 2003?
Thanks in advance,
André
December 21st, 2011 - 03:50
Running version 1.5.4.
I noticed a small oversight – that when there is only one mailbox in a database (because we’re just setting up coexistence with 2010 and testing) it takes the size of the mailbox and halves it to get the average mailbox size.
December 19th, 2011 - 12:51
Hey Steve,
a very nice tool but I have to adapt it to our needs.
I have added two new filter:
[parameter(Position=5,Mandatory=$false,ValueFromPipeline=$false,HelpMessage='Server Domain Filter (eg NL-*)')][string]$Serverdomain=”[fqdn]“,
[parameter(Position=5,Mandatory=$false,ValueFromPipeline=$false,HelpMessage='Server Name Filter (eg NL-*)')][string]$ServerName=”2c”
and have changed some queries:
$ExchangeServers = [array](Get-ExchangeServer -Domain $ServerDomain) | where-object {($_.Name -match $ServerName)}
$Mailboxes = [array](Get-ExchangeServer -Domain $ServerDomain | where-object {($_.Name -match $ServerName)} |Get-Mailbox -ResultSize Unlimited)
$Databases = [array](Get-ExchangeServer -Domain $ServerDomain | where-object {($_.Name -match $ServerName)} | Get-MailboxDatabase -IncludePreExchange2007 -Status | Sort-Object)
due to this changes the servers and databases are sorted and you have the amount of MBXs per Store within the report.
December 20th, 2011 - 02:26
Hi Mike,
[string]$ServerName=”2c”
What is = 2c ?
December 20th, 2011 - 05:26
One more question, which part should I comment out for removing the entire “whitespace” column ? I don’t need that column at all as they don’t show the correct values.
December 21st, 2011 - 09:45
Dear Szeto,
2c is a filter – for Cluser. It’s a name filter that filters all servers in the domain that contain “2c” in the name.
December 21st, 2011 - 10:14
Nice I got everything working and showing correctly finally..
Thanks
December 18th, 2011 - 04:50
Hey paul,
When i ran the script i got the below error
[PS] C:\>.\Get-ExchangeEnvironmentReport.ps1 -HTMLReport c:\rep.html
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:472 char:29
+ if ($TotalServersByRole[ <<<< $Role] -eq $null)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:472 char:29
+ if ($TotalServersByRole[ <<<< $Role] -eq $null)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:472 char:29
+ if ($TotalServersByRole[ <<<< $Role] -eq $null)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:123 char:60
+ $MailboxStatistics = [array]($ExchangeEnvironment.Servers[ <<<< $Database.Server.Name].MailboxStatistics | Where
{$_.Database -eq $Database.Identity})
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:134 char:35
+ if ($ExchangeEnvironment.Servers[ <<<< $Database.Server.Name].Disks)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
You cannot call a method on a null-valued expression.
At C:\Get-ExchangeEnvironmentReport.ps1:193 char:140
+ $Size = [long](get-wmiobject cim_datafile -computername $Database.Server.Name -filter ('name=''' + $Database.
edbfilepath.pathname.replace <<<< ("\","\\") + '''')).filesize
+ CategoryInfo : InvalidOperation: (replace:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
WARNING: Cannot detect database size via WMI for
You cannot call a method on a null-valued expression.
At C:\Get-ExchangeEnvironmentReport.ps1:213 char:50
+ ActiveOwner = $Database.Server.Name.ToUpper <<<< ()
+ CategoryInfo : InvalidOperation: (ToUpper:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:123 char:60
+ $MailboxStatistics = [array]($ExchangeEnvironment.Servers[ <<<< $Database.Server.Name].MailboxStatistics | Where
{$_.Database -eq $Database.Identity})
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:134 char:35
+ if ($ExchangeEnvironment.Servers[ <<<< $Database.Server.Name].Disks)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
You cannot call a method on a null-valued expression.
At C:\Get-ExchangeEnvironmentReport.ps1:193 char:140
+ $Size = [long](get-wmiobject cim_datafile -computername $Database.Server.Name -filter ('name=''' + $Database.
edbfilepath.pathname.replace <<<< ("\","\\") + '''')).filesize
+ CategoryInfo : InvalidOperation: (replace:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
WARNING: Cannot detect database size via WMI for
You cannot call a method on a null-valued expression.
At C:\Get-ExchangeEnvironmentReport.ps1:213 char:50
+ ActiveOwner = $Database.Server.Name.ToUpper <<<< ()
+ CategoryInfo : InvalidOperation: (ToUpper:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Out-File : Access to the path 'C:\rep.html' is denied.
At C:\Get-ExchangeEnvironmentReport.ps1:974 char:19
+ $Output | Out-File <<.\Get-ExchangeEnvironmentReport.ps1 -HTMLReport c:\rep.html
WARNING: Active Directory server settings remained unchanged.
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:472 char:29
+ if ($TotalServersByRole[ <<<< $Role] -eq $null)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:472 char:29
+ if ($TotalServersByRole[ <<<< $Role] -eq $null)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:472 char:29
+ if ($TotalServersByRole[ <<<< $Role] -eq $null)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:123 char:60
+ $MailboxStatistics = [array]($ExchangeEnvironment.Servers[ <<<< $Database.Server.Name].MailboxStatistics | Where
{$_.Database -eq $Database.Identity})
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:134 char:35
+ if ($ExchangeEnvironment.Servers[ <<<< $Database.Server.Name].Disks)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
You cannot call a method on a null-valued expression.
At C:\Get-ExchangeEnvironmentReport.ps1:193 char:140
+ $Size = [long](get-wmiobject cim_datafile -computername $Database.Server.Name -filter ('name=''' + $Database.
edbfilepath.pathname.replace <<<< ("\","\\") + '''')).filesize
+ CategoryInfo : InvalidOperation: (replace:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
WARNING: Cannot detect database size via WMI for
You cannot call a method on a null-valued expression.
At C:\Get-ExchangeEnvironmentReport.ps1:213 char:50
+ ActiveOwner = $Database.Server.Name.ToUpper <<<< ()
+ CategoryInfo : InvalidOperation: (ToUpper:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:123 char:60
+ $MailboxStatistics = [array]($ExchangeEnvironment.Servers[ <<<< $Database.Server.Name].MailboxStatistics | Where
{$_.Database -eq $Database.Identity})
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:134 char:35
+ if ($ExchangeEnvironment.Servers[ <<<< $Database.Server.Name].Disks)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
You cannot call a method on a null-valued expression.
At C:\Get-ExchangeEnvironmentReport.ps1:193 char:140
+ $Size = [long](get-wmiobject cim_datafile -computername $Database.Server.Name -filter ('name=''' + $Database.
edbfilepath.pathname.replace <<<< ("\","\\") + '''')).filesize
+ CategoryInfo : InvalidOperation: (replace:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
WARNING: Cannot detect database size via WMI for
You cannot call a method on a null-valued expression.
At C:\Get-ExchangeEnvironmentReport.ps1:213 char:50
+ ActiveOwner = $Database.Server.Name.ToUpper <<<< ()
+ CategoryInfo : InvalidOperation: (ToUpper:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Out-File : Access to the path 'C:\rep.html' is denied.
At C:\Get-ExchangeEnvironmentReport.ps1:974 char:19
+ $Output | Out-File <<
December 17th, 2011 - 14:33
Hey paul,
When i ran the script i got the below error
[PS] C:\>.\Get-ExchangeEnvironmentReport.ps1 -HTMLReport c:\rep.html
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:472 char:29
+ if ($TotalServersByRole[ <<<< $Role] -eq $null)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:472 char:29
+ if ($TotalServersByRole[ <<<< $Role] -eq $null)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:472 char:29
+ if ($TotalServersByRole[ <<<< $Role] -eq $null)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:123 char:60
+ $MailboxStatistics = [array]($ExchangeEnvironment.Servers[ <<<< $Database.Server.Name].MailboxStatistics | Where
{$_.Database -eq $Database.Identity})
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:134 char:35
+ if ($ExchangeEnvironment.Servers[ <<<< $Database.Server.Name].Disks)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
You cannot call a method on a null-valued expression.
At C:\Get-ExchangeEnvironmentReport.ps1:193 char:140
+ $Size = [long](get-wmiobject cim_datafile -computername $Database.Server.Name -filter ('name=''' + $Database.
edbfilepath.pathname.replace <<<< ("\","\\") + '''')).filesize
+ CategoryInfo : InvalidOperation: (replace:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
WARNING: Cannot detect database size via WMI for
You cannot call a method on a null-valued expression.
At C:\Get-ExchangeEnvironmentReport.ps1:213 char:50
+ ActiveOwner = $Database.Server.Name.ToUpper <<<< ()
+ CategoryInfo : InvalidOperation: (ToUpper:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:123 char:60
+ $MailboxStatistics = [array]($ExchangeEnvironment.Servers[ <<<< $Database.Server.Name].MailboxStatistics | Where
{$_.Database -eq $Database.Identity})
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:134 char:35
+ if ($ExchangeEnvironment.Servers[ <<<< $Database.Server.Name].Disks)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
You cannot call a method on a null-valued expression.
At C:\Get-ExchangeEnvironmentReport.ps1:193 char:140
+ $Size = [long](get-wmiobject cim_datafile -computername $Database.Server.Name -filter ('name=''' + $Database.
edbfilepath.pathname.replace <<<< ("\","\\") + '''')).filesize
+ CategoryInfo : InvalidOperation: (replace:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
WARNING: Cannot detect database size via WMI for
You cannot call a method on a null-valued expression.
At C:\Get-ExchangeEnvironmentReport.ps1:213 char:50
+ ActiveOwner = $Database.Server.Name.ToUpper <<<< ()
+ CategoryInfo : InvalidOperation: (ToUpper:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Out-File : Access to the path 'C:\rep.html' is denied.
At C:\Get-ExchangeEnvironmentReport.ps1:974 char:19
+ $Output | Out-File <<<
[PS] C:\>.\Get-ExchangeEnvironmentReport.ps1 -HTMLReport c:\rep.html
WARNING: Active Directory server settings remained unchanged.
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:472 char:29
+ if ($TotalServersByRole[ <<<< $Role] -eq $null)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:472 char:29
+ if ($TotalServersByRole[ <<<< $Role] -eq $null)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:472 char:29
+ if ($TotalServersByRole[ <<<< $Role] -eq $null)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:123 char:60
+ $MailboxStatistics = [array]($ExchangeEnvironment.Servers[ <<<< $Database.Server.Name].MailboxStatistics | Where
{$_.Database -eq $Database.Identity})
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:134 char:35
+ if ($ExchangeEnvironment.Servers[ <<<< $Database.Server.Name].Disks)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
You cannot call a method on a null-valued expression.
At C:\Get-ExchangeEnvironmentReport.ps1:193 char:140
+ $Size = [long](get-wmiobject cim_datafile -computername $Database.Server.Name -filter ('name=''' + $Database.
edbfilepath.pathname.replace <<<< ("\","\\") + '''')).filesize
+ CategoryInfo : InvalidOperation: (replace:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
WARNING: Cannot detect database size via WMI for
You cannot call a method on a null-valued expression.
At C:\Get-ExchangeEnvironmentReport.ps1:213 char:50
+ ActiveOwner = $Database.Server.Name.ToUpper <<<< ()
+ CategoryInfo : InvalidOperation: (ToUpper:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:123 char:60
+ $MailboxStatistics = [array]($ExchangeEnvironment.Servers[ <<<< $Database.Server.Name].MailboxStatistics | Where
{$_.Database -eq $Database.Identity})
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At C:\Get-ExchangeEnvironmentReport.ps1:134 char:35
+ if ($ExchangeEnvironment.Servers[ <<<< $Database.Server.Name].Disks)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
You cannot call a method on a null-valued expression.
At C:\Get-ExchangeEnvironmentReport.ps1:193 char:140
+ $Size = [long](get-wmiobject cim_datafile -computername $Database.Server.Name -filter ('name=''' + $Database.
edbfilepath.pathname.replace <<<< ("\","\\") + '''')).filesize
+ CategoryInfo : InvalidOperation: (replace:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
WARNING: Cannot detect database size via WMI for
You cannot call a method on a null-valued expression.
At C:\Get-ExchangeEnvironmentReport.ps1:213 char:50
+ ActiveOwner = $Database.Server.Name.ToUpper <<<< ()
+ CategoryInfo : InvalidOperation: (ToUpper:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Out-File : Access to the path 'C:\rep.html' is denied.
At C:\Get-ExchangeEnvironmentReport.ps1:974 char:19
+ $Output | Out-File <<<
[PS] C:\>
December 14th, 2011 - 20:07
Hi Steve,
Just wanted to thank you for sharing the script. It’s helped me a great deal. Thank you!
December 14th, 2011 - 14:26
Hey Steve,
great script! But sometimes the rollup versions is not detected correctly.
Get-ExchangeUpdateRollups.ps1 gives the correct output.
http://www.bhargavs.com/index.php/2009/12/14/how-do-i-check-update-rollup-version-on-exchange-20xx-server/
December 13th, 2011 - 19:39
Hi Steve, Thanks for the great script. How do I change the filter to exclude. I got few 2003 FE servers on DMZ which are not accessible and would like to skip instead of timing out.
December 13th, 2011 - 14:30
I have noticed that the logs free space reports incorrect. Every run always shows 96.8% free even when I have verified that on log drive was 40% free. Seems to be only on mount point drives (but the DB are also on MP and they report correctly)
December 13th, 2011 - 11:15
I am getting lots of error while executing the script.
Unexpected token ‘UR’ in expression or statement.
At C:\Scripts\Get-ExchangeEnvironmentReport.ps1:537 char:17
+ $Output+=” UR( <<<< $Server.RollupLevel)"
December 13th, 2011 - 07:04
Hi Steve, is it possible to change the sort order inside the HTML report? i have a 2 member DAG in my enviroment and the reports sorts the list by servername. can i change a parameter to sort the list by database name?
THX
Jens
December 12th, 2011 - 17:38
Great Script.
I read the above posts and would like to add. SCOM monitoring is not soo great out of the box when you have such large drives ( for email alerts).
I tried to modify your script but could not get the database list sorted by name. I would really appreciate. Seems to list databases differently on different runs.
Mark
December 12th, 2011 - 18:09
Use the Sort-Object in BOTH locations in section 2.1:
{
_UpProg1 60 “Getting Archive Mailboxes” 1
$ArchiveMailboxes = [array](Get-Mailbox -Archive -ResultSize Unlimited) | Where {$_.Server -like $ServerFilter}
_UpProg1 90 “Getting Databases” 1
$Databases = [array](Get-MailboxDatabase -IncludePreExchange2010 -Status) | Where {$_.Server -like $ServerFilter} |sort-object Name
$DAGs = [array](Get-DatabaseAvailabilityGroup) | Where {$_.Servers -like $ServerFilter}
} else {
$ArchiveMailboxes = $null
$ArchiveMailboxStats = $null
$DAGs = $null
_UpProg1 90 “Getting Databases” 1
$Databases = [array](Get-MailboxDatabase -IncludePreExchange2007 -Status) | Where {$_.Server -like $ServerFilter} | sort-object Name
December 12th, 2011 - 18:24
Ok. I found the spot for gettting the database list (at least for DAG) sorted by name.
Line 820, I added ” | Sort Name ” To the end.
$Databases = [array](Get-MailboxDatabase -IncludePreExchange2010 -Status) | Where {$_.Server -like $ServerFilter} | sort Name
Thanks,
Mark
December 6th, 2011 - 15:34
would love to have PF data added to this report..
Thanks!
December 5th, 2011 - 16:54
Great report. i’d love to add in the last Incremental backup date into the report. Other than that, this report ROCKS!!!!
December 2nd, 2011 - 18:18
Awesome script!!! Trying to get it to run as a task but it wont. Tried copying the powershell push command to a batch file but still no luck. Windows 2008 R2 here. Any help would be greatly appreciated. Thanks.
December 2nd, 2011 - 20:44
Figured it out. We have Exchange 2010. Created a batch file with the following command and created a Task scheduler task to run nightly:
powershell.exe -command “. ‘D:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1′; Connect-ExchangeServer -auto; c:\scripts\Get-ExchangeEnvironmentReport.ps1 -HTMLReport c:\scripts\ev-report.html -SendMail:$true -MailFrom:cas-hub@nowhere.com -MailTo:me@somewhere.com -MailServer:server.domain.com”
December 2nd, 2011 - 15:03
Many environments have Edge servers protected with TMG which blocks WMI and Remote Registry. Rather than having to open up the ports for these services, which is a hard sell for security watchdogs in most environments, it’d be desirable to have another switch in the script to skip the Edge servers.
Cheers
November 30th, 2011 - 00:23
Steve, thank you for this wonderful script! The report is elegant and well laid out.
November 30th, 2011 - 23:40
Thanks, glad you like it.
Steve
November 25th, 2011 - 10:13
Thank you very much Steve
Hope next version, you can add 04 more things:
1. Ability to save the file as date format (to keep history)
2. Show all Servers status not only DAG activated Server (at our side, Servers in DAG are not the same Physical, HDD…)
3. Add RAM, CPU Status.
4. Message queue.
Phong
November 30th, 2011 - 23:35
Thanks I will add them to the list.
November 17th, 2011 - 16:39
Great tool! Just wondering if there is anyway to add functionality where when the database disk free size gets to 2% or something like that, can the box turn to RED?
November 30th, 2011 - 23:26
Hi Jeremy,
To be honest functionality like that I would personally think SCOM would be more suitable for as real monitoring systems provide better real-time reporting and more in depth analysis of actual issues. It’s possible to change the script to do this however.
Steve
November 17th, 2011 - 13:51
Hey Steve,
this is an awsesome script!
When running it in an environment with Exchange Edge servers, it stops due to permissions errors (no access to Edge server). It’s a predictable behaviour, since the edge server is not a member of AD. Is there a way to a) identify Edge servers and b) prompt for credentials?
I can send you the error messages for exploration, if you like.
Regards,
Heiko
November 11th, 2011 - 13:35
Dear Steve,
thank you very much for your excellent script. I have the same problems with the mailbox count. If the script runs to the hole forest it works. If I set up an Filter for example (de*) the mailbox count is always empty.
Could you help me?
November 30th, 2011 - 23:24
Hi Andre,
I’m aware of this and hope to find time to fix in an upcoming release.
Steve
November 11th, 2011 - 13:16
Hi Paul,
i have also some problems with the mailbox counts. When the script runs without a serverfilter the mailbox count works. If i set a filter for example “de*” the mailbox count is always empty.
Could you help me please?
November 9th, 2011 - 02:20
Hey Steve
Awesome script, well written. Wow!!! Works fine for me manually scheduled from a Win2008/Exch2007 HT Server. However, when I use the -ServerFilter, gives me 0 count for mailboxes, both Total and individual DBs. Any idea? Thanks
November 8th, 2011 - 19:58
Steve, running v1.5.4 but not getting any of the Mailboxes counts (total or indivudual db). Everything else displays great.
Also, along with others is there way to run the script either Domain or Site specific? Each domain\site manages their own Exchange servers within the Enterprise.
Thanks,
Jay
November 8th, 2011 - 20:09
Ran against Entire forest and mailbbox counts populate for the domain which I manage (do not have rights in the other domains). Running using Server Filter on my domain mailboxes does not produces the mailbox counts.
Is there a way to accomplish this? Would be nice to run against just those servers during user migration from 2007 to 2010.
Thanks,
Jay
November 8th, 2011 - 23:15
Hi Jay,
I don’t have a solution for you at the moment, but for the next major release I will look at changing it to allow Site or Domain to be specified
Steve
October 27th, 2011 - 13:04
Hi,
I think you made a little mistake in log free space % evaluation
This line:
if ( $Database.LogFolderPath.PathName -like “$($Disk.Name)*”)
To:
if ( ($($Database.LogFolderPath.PathName+”\”)) -like “$($Disk.Name)*”)
In my case, with a mount point for the log, LogFolderPath.PathName end with no “\”, and disk name has one ! So the -like did not match.
If not clear, give it a try it if you have problem with free log space
Best regards.
November 8th, 2011 - 00:23
Thanks Fred I will check out your change, my maths isn’t always perfect
Steve
October 26th, 2011 - 01:19
GREAT SCRIPT
Script runs fine by command line, but when I add to the task in Windows 2008, it never runs. (running as same account that i used manually) – no said errors other then the 0×1
I did try a few things to test copy past the lines from task manager and run from command line. i do get an error when i do that..
here is the command that i have copied and pasted.
-c “pushd C:\Exchange\Scripts; C:\Exchange\Scripts\Get-ExchangeEnvironmentReport.ps1 -HTMLReport c:\ExchangeReports\ExchangeReport.html -SendMail:$true -MailFrom:ExchangeReport@fake.com -MailTo:fakeDL@fake.com -MailServer:someserver
Error:
Push-Location : A parameter cannot be found that matches parameter name ‘HTMLRe
port’.
At line:1 char:72
+ pushd C:\Exchange\Scripts\Get-ExchangeEnvironmentReport.ps1 -HTMLReport <<<<
c:\ExchangeReports\ExchangeReport.html -SendMail:$true -MailFrom:ExchangeRepor
t@fake.com -MailTo:fake@fake.com -MailServer:someserver
+ CategoryInfo : InvalidArgument: (:) [Push-Location], ParameterB
indingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Comm
ands.PushLocationCommand
can you point me in the right direction?
November 16th, 2011 - 14:36
any thoughts on the above error or any suggestions on getting this as a task?
December 2nd, 2011 - 21:02
Here is what I used in a batch file and scheduled in Task Scheduler: powershell.exe -command “. ‘D:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1′; Connect-ExchangeServer -auto; c:\scripts\Get-ExchangeEnvironmentReport.ps1 -HTMLReport c:\scripts\ev-report.html -SendMail:$true -MailFrom:cas-hub@nowhere.com -MailTo:me@somewhere.com -MailServer:server.domain.com”
December 6th, 2011 - 15:32
yep i finally did that as well
called a bat file from sched task
bat file reads:
powershell -command “& c:\scripts\Get-ExchangeEnvironmentReport.ps1 -HTMLReport ExchangeReport.html -SendMail:$true -MailFrom:some@address.com -MailTo:another@address.com -MailServer:smtpserver”
October 24th, 2011 - 20:20
Steve…
I try to set up the script as a task per instructions above, and keep getting this:
+ CategoryInfo : InvalidArgument: (:) [Get-ExchangeEnvironmentReport.ps1], ParameterBindingException
+ FullyQualifiedErrorId : AmbiguousPositionalParameterNoName,Get-ExchangeEnvironmentReport.ps1
What am I doing wrong?
November 8th, 2011 - 00:31
Hiya,
The task scheduling does now work consistently on all platforms so it’s best to manually set this up rather than rely on the script right now.
Steve
October 24th, 2011 - 17:43
What a nice script/report! Thank you, Steve. One request… It would be nice if the report showed the Exchange edition (Ent or Std), like it does for the OS.
October 24th, 2011 - 04:35
Thanks billion Steve.
PERFECT script, looking forward to your solutions to my issues explained in my email.
October 21st, 2011 - 20:33
Hi , when i try to run the Script, i receive the following error.
Incomplete ‘finally’ statement. A finally statement requires a body.
At C:\Documents and Settings\aroura\Desktop\Get-ExchangeEnvironmentReport.ps1:4
4 char:9
+ Finally, <<<< per Database (Non DAG DBs/Exchange 2007/Exchange 2003)
Any idea?
Thank you.
October 23rd, 2011 - 00:02
Hiya
Are you using Powershell Version 2.0 or newer?
Steve
October 21st, 2011 - 09:40
Great script Steve,
Worked a treat for me. I thought i was doing well with powershell until a read through the script.
In the first function _GetDAG…i can see you define your param and create an array and an empty array….how did you get the database info. There is no get-mailboxdatabase command…….what dark magic is this?
Thanks
Emmet
October 23rd, 2011 - 00:03
Hiya,
Don’t worry, nothing weird going on. It get’s the bits earlier on in the script, then passes the objects to the function to save getting the info more than once!
Steve
October 20th, 2011 - 18:49
Great script! Definitely saved me a lot of work. Thanks!!
October 23rd, 2011 - 00:11
Thanks, glad you found it useful!
Steve
October 20th, 2011 - 14:36
Great script Steve,
I thought i was doing ok with powershell until i read your script.
Could you explain how the first function works (Function _GetDAG) ?
How do you get the database info with so few lines of code. You dont use get-mailboxdatabase?? Probably a dumb question…but i’m scratching my head here.
Cheers
Emmet
October 19th, 2011 - 18:48
Steve, great script! Having an issue with the “DB whitespace” calculation. The “DB whitespace” calc comes out as the same as the “DB Size” on 2K3 servers and on 2K7 SP2 CCR it comes out as a very high value as compared to what results from running 2 other scripts that report the same value. (example: your script reports DB1 having a DB size of 101.92 GB and DB Whitespace of 46.50 GB. I run 2 differnet scripts to check for whitespace only and they both come up with 2.55 GB for DB1 whitespace).
Could you explain how your script calculates DB whitespace?
October 27th, 2011 - 05:00
Givens, have you fixed the whitespace issue? I am seeing huge whitespace on 1 of my SGs and some are showing zero
November 8th, 2011 - 00:28
The whitespace issue isn’t fixed in the current release for 2007 and earlier.
Steve
October 14th, 2011 - 06:41
Hi Steve,
looks like I found little room for improvement (to avoid the b-word) in your marvellous tool
The “Av. Mailbox Size” for Exchange 2003 databases is calculated wrong somehow (for all 2k3 DBs).
Sample: 248 Mailboxes, 38.43GB DB Size (and almost 0 whitespace) -> Av MBX Size = 0.10MB.
Version is v1.5.4.
Best wishes,
Klaus
October 3rd, 2011 - 09:13
Hi Steve,
I am little bit confused about this script, kindly assist me , how to use this script..
Thanks
September 28th, 2011 - 15:58
Great thing by the way. to things for your whish list
1. “free Disk space” is not correct if we are using MountPoint
2. add the “path” to the Database/logs as an additional column
Frank
September 29th, 2011 - 23:40
Hi Frank,
MountPoint Disk Space was tested – is it completely wrong? Wondering if I’ve calculated something incorrectly.
Steve
September 27th, 2011 - 11:04
If -SendMail specified, you must also specify -MailFrom, -MailTo and -MailServer ???
But I am putting those in…
September 28th, 2011 - 11:40
Hi Richard,
The -SendMail needs to have -SendMail:$true specified (it’s not a Switch, it’s a bool)
Steve
September 26th, 2011 - 10:29
Hi Steve,
I got a question,
When I´m running the script I get a “Security Warning”
.\Get-ExchangeEnvironmentReport -HTMLReport C:\Scripts\ExchangeEnvironmentReport.html
Security Warning
Run only scripts that you trust. While scripts from the Internet can be useful, this script can potentially harm your
computer. Do you want to run C:\Scripts\Get-ExchangeEnvironmentReport.ps1?
[D] Do not run [R] Run once [S] Suspend [?] Help (default is “D”):
To run the script I need to confirm with “R” key, the problem is when I add the script to schedule task, the script don’t run because of this, is there anything I can add to the command line to supersede the “R” key.
ExecutionPolicy is set to “Unrestricted”
September 28th, 2011 - 11:41
Hi Adam,
A quick woraround may be to crate a new Powershell file and copy/paste the script from the original file into the new file, to ensure it’s seen as a local file.
Steve
January 24th, 2012 - 18:29
You can also open Explorer, right click on the file, select Properties. You should have an option at the bottom of the General tab to Unblock the script.
September 26th, 2011 - 10:15
Amazing script, thanks alot!
September 19th, 2011 - 03:24
Hi Steve,
not sure how can we twick in your script only scan per-sites or server only ?
September 14th, 2011 - 18:32
The Script is very Good , Is there is any possibility of splitting these scripts Individually ?
and also is there is anyway to run these scripts across domain wisw and Server Wise , In our Exchange Environment we do not have access to all the domains and Servers, It will be good f you could guide me on Server Wise.
Regards
Srinivasa K
September 14th, 2011 - 18:30
Hello Steve
The Script is very good , Is there is any posibilities of running this script individually and specific to Domain Wise. We have multiple Doamins in our forest and we have access only to few Domains and Servers.
I want to split these scrips Individually . Please help Me.
September 13th, 2011 - 16:01
Steve,
I was in the process of writing a powershell script that does all of this… man, you saved me a bunch of work! Thanks so much. This is great. You did a fantastic job with the format of the report as well!
Do you have any plans to do something similar with Lync? I’m going to start one. I’m sure it won’t be nearly as pretty as anything you’d write. Thanks and Cheers!
September 13th, 2011 - 22:29
Hi Sean,
I don’t have any plans to do a Lync one. If you do one, let me know and I’ll put a link (no pun intended!) to yours, it sounds very interesting
Steve