• Exchange 2007/2010/2013 – Gather email statistics like Exchange Profile Analyzer used to give in the past, but now using Powershell !

     

    Want to pull out statistics from Exchange such as :

    · messages sent per mailbox per day

    · messages received per mailbox per day

    · average message size

    … And more if you want ?

    Use Powershell and Excel now !

     

     

    I- If you want to pull data from Exchange 2003 to 2007 Exchange versions, then you can use Exchange Profile Analyzer (EPA):

    This tool uses WebDAV to interrogate the mailboxes and generates user profile data.

     

    II- If you want to pull data from Exchange 2007/2010 servers, then you have to use Powershell to pull out these data

    You cannot use Exchange Profile Analyzer on Exchange 2010 (you still can on Exchange 2007) as in Exchange 2010 and after, we gave up the WebDav protocol.

    But we now use Powershell to query and ask the Exchange 2010 (and 2007) message tracking logs to pull out the same data as we had on EPA.

    You can use the following TechNet script:

    Exchange 2007/2010 Email stats

    http://gallery.technet.microsoft.com/scriptcenter/bb94b422-eb9e-4c53-a454-f7da6ddfb5d6

    And here is how to interpret data using Excel functions. Quick and easy:

    User Profile Analysis for Exchange Server 2010

    http://blogs.technet.com/b/neiljohn/archive/2011/08/09/user-profile-analysis-for-exchange-server-2010.aspx

     

     

    Thanks very much to mjolinor and Neil Johnson for their scripts and explanations !

  • Windows 2008 R2 – WMI Quota issue caused by either a WMI leak or an application overallocating WMI memory

     

    I- Default WMI memory quotas for Windows 2008 R2:

     

    Memory Per Host:  536870912
    Handles Per Host:  4096
    Memory All Hosts:  1073741824
    Process Limit All Hosts:  32
    Threads Per Host:  256

     

    To check what is the current ones on any Windows 2003 and up servers, you can use the following script, and pipe one or more servers on the function from the following script:

     

    #Disclaimer : The below script takes a file with server names as pipeline input.

    #You can write a better function with more time with parameters, error control, etc... 

     #    

    #How to use :     

    #1- run the script to load the function    

    #2- create a text file with server names for which we want to check the WMI quotas    

    #3- Launch Get-Content C:\temp\ServerNames.txt | Check-AllWMIQuotas    

     

    Function Check-AllWMIQuotas {

          Begin {    

          Write-Host "Beginning to process servers from the pipeline"    

          }    

          Process {    

          #Load the __ProviderHostQuotaConfiguration class from the root namespace    

          $objWMI=get-wmiobject -ComputerName $_ -Namespace rootClass __ProviderHostQuotaConfiguration       

          Write-Host "----------- Checking Server $_ ------------"    

          Write-host "Memory Per Host: "$objWMI.MemoryPerHost            

          Write-Host "Handles Per Host: "$objWMI.HandlesPerHost    

          Write-Host "Memory All Hosts: "$objWMI.MemoryAllHosts    

          Write-Host "Process Limit All Hosts: "$objWMI.ProcessLimitAllHosts

          Write-Host "Threads Per Host: "$objWMI.ThreadsPerHost    

          }     

          End {    

          Write-Host Finished !    

          }     

    }    

      

     

    II- Either monitor WMIPrsve process using Perfmon (Process\Private Bytes of all WMI processes (WmiPrvSE*)) to see if memory is skyrocketting and/or take a dump of the WmiPrvSE process to see which application is using all WMI memory from the allocated quota.

    See http://blogs.technet.com/b/kevinholman/archive/2010/06/09/wmi-leaks-memory-on-server-2008-r2-monitored-agents.aspx for some détails.

     

    III- Or if it appears an application needs more WMI memory than allowed by the default quotas, raise the quotas.

    Usually doubling the “Memory Per Host” property is enough. But I usually try first by doubling all properties.

    You can either use WBEMTEST to change the WMI quota, or use Powershell along with GWMI (or Get-WMIObject) to change these on several servers if needed.

    Here is a sample script :

    #Disclaimer : The below script takes a file with server names as pipeline input.   

    #You can do a better function with more time with parameters, error control, etc...

    #How to use :

    #1- run the script to load the function (copy/paste in a .PS1 file or copy/paste it directly on a Powershell window)

    #2- create a text file with server names for which we want to change the WMI quotas   

    #3- Launch Get-Content C:\temp\ServerNames.txt | Double-AllWMIQuotas

      Function Double-AllWMIQuotas {    

          Begin {    

          Write-Host "Beginning to process servers from the pipeline"    

          Write-Host "Storing Windows 2008 R2 default"    

          $defaultMemoryPerHost=536870912    

          $defaultHandlesPerHost=4096    

          $defaultMemoryAllHosts=1073741824    

          $defaultProcessLimitAllHosts=32    

          $defaultThreadsPerHost=256    

          } 

          Process {

          #Load the __ProviderHostQuotaConfiguration class from the root namespace    

          $objWMI=get-wmiobject -ComputerName $_ -Namespace root -Class __ProviderHostQuotaConfiguration    

         #Usually, the below line should be enough, but I recommend to double all values    

          $objWMI.MemoryPerHost=$defaultMemoryPerHost*2    

          #Again, usually the below lines are optional but best practices to be sure we won’t have any Out Of Memory error.    

          $objWMI.HandlesPerHost=$defaultHandlesPerHost*2    

          $objWMI.MemoryAllHosts=$defaultMemoryAllHosts*2    

          $objWMI.ProcessLimitAllHosts=$defaultProcessLimitAllHosts*2    

          $objWMI.ThreadsPerHost=$defaultThreadsPerHost*2 

          #In WMI programming, we have to push the above changes to be applied to the object    

          $objWMI.put()    

         

          End {

          Write-Host Finished !

          }  

    }

    Then, as instructed on the comments on the above scripts, either use a Get-content Servers_List.txt | Double-AllWMIQuotas or use “Server1”,”Server2”,”Server3” | Double-AllWMIQuotas

  • Exchange 2010 - Enabling an Autoreply Message (Out Of Office) using the Exchange Management Shell (Powershell)

     

    Here is how to test it on a user first.

    1> Using powershell, do a $objMailbox = Get-Mailbox Some_Test_User to get the user we will assign the Out Of Office to.

    2> Now define your text (best is to do it in HTML) and store it on 2 variables $InternalMsg and $ExternalMsg like in the example below:

    $InternalMsg = "-- Internal Message -- <BR><BR>Hi, <BR><BR>I am not available until next Monday.<BR><BR>For any emergency, please contact my backup John at 613-555-6789.<BR><BR>Jack Doe"

    $ExternalMsg = "-- External Message -- <BR><BR>Hi, <BR><BR>I am not available until next Monday.<BR><BR>For any emergency, please contact my backup John at 613-555-6789.<BR><BR>Jack Doe"

    clip_image001[4]

    3> Now, it’s time to witness the effect of the OOF application on the user’s mailbox.

    Open either an Outlook or an Outlook Web App session and check the Out Of Office status, which should be deactivated, with no messages configured (greyed anyways) or some older messages configured :

    clip_image002

    clip_image003[4]

    4> Launch the commandlet against the test user by piping the $ObjMailbox variable we set above with the test user mailbox (UserTest1 in my example):

    $objMailbox | Set-MailboxAutoReplyConfiguration -AutoReplyState enabled -ExternalAudience all -InternalMessage $InternalMsg -ExternalMessage $ExternalMsg

    clip_image004

    5> Check in Outlook or OWA that the message is now set to “Send automatic replies” and also that we have the correct message as defined in the script, for both internal and External OOF messages :

    clip_image005[4]

    clip_image006

    Once you verified it, to apply the OOF to the remainder of the mailboxes, or in my example to all mailboxes containing the string “User”, define your $objMailbox variable with a Get-Mailbox *User* for example, and reapply the powershell command:

    $objMailbox | Set-MailboxAutoReplyConfiguration -AutoReplyState enabled -ExternalAudience all -InternalMessage $InternalMsg -ExternalMessage $ExternalMsg

    Note: To deactivate the OOF using Powershell on one or more users (depending how many mailboxes you have on the $ObjMailbox variable above), user the following command:

    $objMailbox | Set-MailboxAutoReplyConfiguration -AutoReplyState disabled

  • How-to procedure – Exchange 2010 SP1+ – Enabling and Troubleshooting Calendar Repair Assistant

     

    Did you ever have users complaining that meetings didn’t show up for some attendees ? Or a boss scheduling a meeting, and the meeting disappears from his calendar ?

     

     

    Note: if the Calendar Repair Assistant has to do too many repairs, there might be an application that is constantly corrupting the calendar(s).

    This can be:

    - An Outlook add-on

    - a misconfigured BlackBerry Server

    - file level antivirus scanning the OST and/or the TMP files on the Outlook working directory (on the users’s profile Appdata/Roaming directory)

    - too many delegates on a single calendar, thus creating conflicts and resulting on meetings not being updated or created

  • How-To procedure – Exchange 2010 SP1+ - repair a corrupted mailbox without dismounting a database

     

      

    Remeber ISINGEG ? The Exchange tool to repair logical corruptions in databases ? Now this tool is over, replaced by a commandlet in Exchange 2010+ which does not need to dismount databases !