Wednesday, May 4, 2016

Determine Client Used to Send Email

Just recently someone asked me if there was a way to determine which email client (Outlook, OWA or ActiveSync) was used to send a particular email. On top of that, this person was also interested is finding out how many emails are sent per day using each of these clients.

The good news is that the Message Tracking Logs register this information. Every email sent has a SourceContext property which contains, amongst other information, the ClientType used to send the email. The important thing is to check this property for SUBMIT events, i.e., when the Mailbox Transport Submission service successfully transmits the email to the Transport service.

For SUBMIT events, the SourceContext property contains the following details:
  • MDB: the mailbox database GUID;
  • Mailbox: the mailbox GUID;
  • Event: the event sequence number;
  • MessageClass: the type of message. For example, IPM.Note;
  • CreationTime: date and time of the message submission;
  • ClientType: for example OWA or ActiveSync.

Please note that this only applies to emails sent by internal users. There is no SUBMIT event when an external sender sends an email to an internal user, meaning there is no ClientType property for these emails. In these cases, the only information we have regarding the sender is what the email headers contain, which does not include email client information.

To check what email client was used to send a particular email, we can run something like the following cmdlet and look at the SourceContext field:
Get-TransportService | Get-MessageTrackingLog -ResultSize Unlimited -Start 05/11/2016 -EventID SUBMIT -Sender -MessageSubject Test | Select SourceContext

This field will contain information like the following:
MDB:34f3dc86-91bb-4ee7-a6a5-3d3ddc536050, Mailbox:a1de664f-9826-43a3-b9c8-3db019c86d8b, Event:29647741, MessageClass:IPM.Note, CreationTime:2016-05-11T07:17:14.922Z, ClientType:MOMT

In this case, MOMT stands for MAPI on the Middle Tier, basically clients that connect using Outlook or any other application that connects using RPC/HTTP or MAPI/HTTP.

To count the number of emails sent using OWA today, we can run something like this:
(Get-TransportService | Get-MessageTrackingLog -ResultSize Unlimited -Start 05/11/2016 -EventID SUBMIT | Where {$_.SourceContext -match "OWA"}).Count

Easy as that! :)

Friday, April 29, 2016

Empty StorageLimitStatus when running Get-MailboxStatistics in Exchange 2013/2016

The old version of this script, used to gather some statistics out of mailboxes, made use of the StorageLimitStatus attribute of mailboxes (when running the Get-MailboxStatistics cmdlet). However, if you run the script in an Exchange 2013/2016 environment, you will notice that this attribute is always blank while with Exchange 2010 it is not... Unfortunately, this is by design...
Unlike versions of the Information Store earlier than the one that comes with Exchange 2013, the Information Store in Exchange 2013 does not cache the values of mailbox quotas. Therefore, the Information Store makes frequent calls to Active Directory (AD) to retrieve the values of mailbox quotas for each mailbox that is specified in the Get-MailboxStatistics cmdlet. Because of the frequent calls to AD, admins may experience poor performance in Exchange. To avoid this, the default Get-MailboxStatistics cmdlet does not retrieve the mailbox quotas and does not display a value in the StorageLimitStatus field...
To work around this issue, all we can do is either use the Exchange Admin Console (EAC):
  1. Log on to EAC by using a user account that is assigned at least the Mail Recipients role;
  2. In the feature pane, click recipients. A list of mailboxes is displayed;
  3. Select the mailbox of which you want to verify the quota status and then click the Edit button on the toolbar;
  4. Click mailbox usage. The mailbox quota usage is displayed.
Or we can use the Exchange Management Shell and run the following cmdlet:
Get-Mailbox "user" | FT *quota*, *size -AutoSize

The script has now been updated for Exchange 2013/2016 environments to work around this "issue".

Outlook Chinese NDR

There is a known bug with Outlook 2010 and 2013 that causes Non Delivery Reports (NDR) to be converted to Chinese-like characters when they are forwarded:

The same NDR does not get converted when being forwarded using OWA or when forwarded as an attachment.

The good news is that there are updates to fix this:

Saturday, April 23, 2016

Monitor Mailbox Database Transaction Logs

Excessive database and/or transaction log growth is, unfortunately, not an uncommon problem in Exchange deployments. On top of being hard to troubleshoot, if it is found too late, it can cause serious issues for users and even the business. As such, it is crucial to have an adequate monitoring solution. However, this is not the case in every single organization, so I decided to write a basic script to keep an eye on the number of logs being generated across databases.
You can, for example, run the script every hour and if any database currently has more logs than a specified threshold, it sends an alert by email with the number of transaction logs for all databases, highlighting the one(s) that triggered the alert, and the current free space for the database (you might need to update it depending on whether you have the .edb file and logs on the same or different locations).
The script simply counts all files in the LogFolderPath location (variable for each database) as this makes it quicker than only looking for *.log files, and still be accurate for what we want to achieve.

You can download the complete final script from the TechNet Script Gallery.

Friday, April 22, 2016

Preserving Auto-Forwarded Messages in Exchange

Over the last few versions of Exchange, the Information Protection team has done an amazing job in improving Exchange’s compliance capabilities. One of these features, called In-Place Hold, does a great job in preserving mailbox items. However, it did not capture emails automatically forwarded by users. This can be important as sometimes emails are forwarded without a copy of the email being stored in the user’s mailbox.

If the email does not get delivered to the mailbox at all, it cannot be placed on hold and, as such, will not be available for eDiscovery. For organizations wanting to stay in compliance, the recommendation has been to either disable automatic forwarding completely or to use Journaling.

Well, not anymore! Microsoft has rectified this and now Exchange Online is able to capture auto-forwarded messages. Transport detects if the user that has AutoForwarding configured is on hold and, if yes, automatically preserves a copy of the email in the Recoverable Items folder, making it available to eDiscovery.

At the time of writing this tip, this feature does not yet seem to be available in Exchange 2016 RTM, but it is already available in Exchange Online. In the following screenshot, we can see an eDiscovery search that contains an item that was sent from Nuno to Mota when Mota had auto forwarding configure to an external recipient without a copy being saved in Mota's mailbox. As we can see, the email was still placed on hold:

Thursday, April 21, 2016

Search Admin Audit Log Old Properties

When searching the Admin Audit Log using the Search-AdminAuditLog cmdlet, you might find some useful information missing:
Search-AdminAuditLog -Cmdlets Set-TransportService

ObjectModified     : EXAIO
CmdletName         : Set-TransportService
CmdletParameters   : {MessageTrackingLogMaxAge, MessageTrackingLogMaxDirectorySize, Identity}
ModifiedProperties : { }
Caller             :
Succeeded          : True
Error              : None
RunDate            : 9/10/2015 8:47:48 AM
OriginatingServer  : EXAIO (15.00.1104.000)

From the above, we can see what was changed (the maximum age for the logs and the maximum allowed size for the directory) but not what these settings were changed to...

To see this, we have to dig deeper into CmdletParameters:
(Search-AdminAuditLog -Cmdlets Set-TransportService).CmdletParameters

Name                                 Value
----                                 -----
MessageTrackingLogMaxAge             45.00:00:00
MessageTrackingLogMaxDirectorySize   10 GB (10,737,418,240 bytes)
Identity                             EXAIO

Now we know exactly what the user Admin changed! But what about if we want to know what these settings were before this change?

By default, the administrator audit log records only the cmdlet name, cmdlet parameters (and values specified), the object that was modified, who ran the cmdlet, when the cmdlet was run, and on what server the cmdlet was run. The administrator audit log does not log what properties were modified on the object. If we want the audit log to also include the properties of the object that were modified, we need to enable verbose logging by setting the LogLevel parameter to Verbose:
Set-AdminAuditLogConfig –LogLevel Verbose

When we enable verbose logging, in addition to the information logged by default, the properties modified on an object, including their old and new values, are included in the audit log:
(Search-AdminAuditLog -Cmdlets Set-TransportService).ModifiedProperties

Name                                 NewValue      OldValue
----                                 --------      --------
MessageTrackingLogMaxAge             45.00:00:00   31.00:00:00
MessageTrackingLogMaxDirectorySize   10 GB         5 GB

Now we know exactly what got changed and what the old configuration was!

User Photo in Exchange, Lync and Active Directory

There are several posts out there about how to upload users’ photos into Active Directory (AD) so they can be used by Exchange or Lync, but very few on how this works or how to export them if we need to.

In AD we can use images no greater than 96×96 pixels in resolution and 100KB or smaller in size. This looks ok in the Lync and Outlook client, but results in a blurred photo when Lync, for example, attempts to upscale the image for use in a conference.

In Lync 2013 (and Skype for Business Server 2015) photos can be stored in the user's mailbox (when using Exchange 2013), allowing for photo sizes up to 648x648 pixels. In addition to that, Exchange automatically resizes these photos for use in different products as needed:
  • 64x64 pixels (96 dpi, 24 bit depth, approx. 2KB), the size used for the AD thumbnailPhoto attribute. If we upload a photo to Exchange, Exchange will automatically create a 64x64 pixel version of that photo and update the user's thumbnailPhoto attribute. However, if we manually update the thumbnailPhoto attribute in AD the photo in the user's mailbox will not automatically be updated. This photo is only used by Lync 2010 or legacy clients, so we are ok;
  • 240x240 pixels if the original picture is larger than 240, otherwise 96 (96dpi, 24 bit depth, approx. 8KB), for use in Outlook, OWA, Skype for Business Web App, and Skype for Business;
  • 648x648 pixels for use in Skype for Business and Skype for Business Web App.

Importing Photos
To use high resolution photos, we have to use the Set-UserPhoto Exchange cmdlet:
Set-UserPhoto “Nuno Mota” -PictureData ([System.IO.File]::ReadAllBytes(“D:\Photos\nuno.jpg”)) –Confirm:$False

As already mentioned, the Set-UserPhoto cmdlet does two things: it stores a copy of a high resolution image in the user’s Exchange mailbox, and stores a copy of the photo as a 64×64 image in the thumbnailPhoto AD attribute.

Exporting Photos
To check someone’s photo, we can use Exchange Web Services and the following URL (updating the user’s email and maybe image size):
If we want to export a user’s photo from AD, we can PowerShell and the following commands:
$photo = (Get-ADUser nuno -Properties thumbnailphoto).thumbnailphoto

We can now save this photo into a JPEG file and or import it directly to a different user for example (useful if the user gets a new account):
Set-Content “D:\Photos\nuno.jpg” -Encoding byte
Set-ADUser mota -Replace @{thumbnailphoto = $photo}

However, if we are using Exchange 2013, we should use Exchange cmdlets to manage users’ photos. This way we can export the 648x648 pixels photo from the user’s mailbox instead of the small one from AD:
(Get-UserPhoto nuno).PictureData | Set-Content “D:\Photos\nuno.jpg” -Encoding byte

If you want to use high resolution photos in Lync as well, you might want to ensure you update your Lync Client policy with a MaxPhotoSizeKB of at least 100 instead of just 30.

Mailbox Database Seed Status

Seeding large mailbox databases can potentially take a long time. Although it is something that usually does not need to be monitored, it is always good to keep an eye on it to see how it is doing. The Get-MailboxDatabaseCopyStatus cmdlet gives us all the information we need for this.

Usually I use this cmdlet in the following format to ensure the mailbox database copies on a particular server are mounted and/or healthy:
Get-MailboxDatabaseCopyStatus -Server "server_name" | Sort Name

But we can use it to get further details for a particular mailbox databases (the following output has been shortened to only include the most relevant information for this tip):

[PS] C:\>Get-MailboxDatabaseCopyStatus “MDB01\EXAIO” | FL

Identity : MDB01\EXAIO
DatabaseName : MDB01
Status : Seeding
MailboxServer : EXAIO
ActiveDatabaseCopy : EXMBX01
ActiveCopy : False
ActivationPreference : 3
IsLastCopyAvailabilityChecksPassed : False
LastCopyAvailabilityChecksPassedTime :
IsLastCopyRedundancyChecksPassed : False
LastCopyRedundancyChecksPassedTime :
ActivationSuspended : True
ContentIndexState : FailedAndSuspended
ContentIndexErrorMessage : Reseeding of the index is required.
ContentIndexErrorCode : 22
CopyQueueLength : 718053
ReplayQueueLength : 0
ReplicationIsInBlockMode : False
ActivationDisabledAndMoveNow : False
AutoActivationPolicy : Unrestricted
ReplayLagStatus : Enabled:False; PlayDownReason:None; Percentage:0; Configured:00:00:00;
DatabaseSeedStatus : Percentage:33; Read:95.19 GB; Written:95.19 GB; ReadPerSec:23.65 MB; WrittenPerSec:23.67 MB

DiskFreeSpacePercent : 60
DiskFreeSpace : 434.7 GB (466,730,405,888 bytes)
DiskTotalSpace : 717 GB (769,869,737,984 bytes)
DatabaseVolumeMountPoint : E:\Mount\edb09\
LogVolumeMountPoint : E:\Mount\edb09\

If we are particularly interested on the progress of the seed operation, we can filter the above output to only include what we want:
(Get-MailboxDatabaseCopyStatus “MDB01\EXAIO”).DatabaseSeedStatus

Saturday, April 9, 2016

Analyze Mailbox Items Class or Type

The purpose of this script is to go through every single item in a mailbox and produce a report listing the class (or type) of each item and how many items of each class were found in the mailbox:

Processed 52 folders and 19163 items.

Name Value
---- -----
IPM.Appointment                          194
IPM.Appointment.ReadiManagerMeeting      2
IPM.Contact                              164
IPM.Note                                 16911
IPM.Note.Exchange.ActiveSync.MailboxLog  2
IPM.Note.Microsoft.Conversation          1616
IPM.Note.Microsoft.Conversation.Voice    67
IPM.Note.Microsoft.Missed                2
IPM.Schedule.Meeting.Canceled            3
IPM.Schedule.Meeting.Request             43
IPM.Schedule.Meeting.Resp.Neg            3
IPM.Schedule.Meeting.Resp.Pos            20
IPM.Schedule.Meeting.Resp.Tent           2
IPM.Sharing                              120
IPM.StickyNote                           14

I created this script to have an idea of how items had been archived by EnterpriseVault across the users’ mailboxes (IPM.NOTE.EnterpriseVault.Shortcut class). The script reports on all item classes, but it can easily be changed to only look for a particular class, such as EV stubs for example.

To download the complete final script, please head on to the TechNet Script Gallery.

Friday, April 8, 2016

Office 365 Admin App for Windows 10

Microsoft has released the beta version of the Office 365 Admin app for Windows 10, which is available for both Windows 10 Desktop and Mobile!

This app gives admins the ability to administer Office 365 directly from their desktop. It supports notification integration with Windows 10 as well as Microsoft Partner scenarios, allowing admins to easily switch organizations if they manage Office 365 for multiple tenants. The mobile version has the exact same user experience making switching from desktop to the mobile app extremely easy.

To install it, search for “office 365 admin” in the Windows App Store and you should find it straight away. Click Install and, once installed, click Open: 

Alternatively, once installed, search for “office 365” in your start menu:

Simply add an account for an Office 365 tenant you want to manage:

Once logged in, the app’s dashboard provides some high level information about the service and the tenant itself:

We can search for all users provisioned in the tenant:

As well as perform a variety of actions on user accounts or gather further information about them:

We can check the current health of the Office 365 tenant:

Read any available messages:

And much, much more! Give it a try :)

Setting Distribution Groups Default OU in Exchange 2010/2013/2016

When creating a Distribution Group in the Exchange Shell or Console, we are given the option to choose which Organizational Unit (OU) in Active Directory (AD) we want the group’s object to be created in:

However, we do not necessarily need to choose an OU. We can tell Exchange where it should create all OUs by default using the Set-OrganizationConfig cmdlet. By default, no OU is selected which means Exchange will create all distribution groups in the Users OU:

Let us say we want all distribution groups to be created in the Exchange -> Distribution Groups OU:

Using the above cmdlet it is easy to globally set the default OU for any newly created distribution group from now on:

When creating a new distribution group now, we still get the exact same wizard with the Organizational unit field not populated. However, if we don’t choose any OU, the distribution group will now be created in the OU we set up above.

Distribution Group SendAs Denied

When trying to assign Send As or Receive As permissions to a Distribution Group in Exchange 2010, 2013 or 2016 using the Add-ADPermission cmdlet, you might get an error message saying Access is denied and insufficient access rights:

Active Directory operation failed on . This error is not retriable. Additional information: Access is denied.
Active directory response: 00000005: SecErr: DSID-031521D0, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0
+ CategoryInfo : WriteError: (0:Int32) [Add-ADPermission], ADOperationException
+ FullyQualifiedErrorId : 5557AD82,Microsoft.Exchange.Management.RecipientTasks.AddADPermission

This is because, by default, Exchange Trusted Subsystem is not granted the “modify permissions” permission. This causes the Add-ADPermission cmdlet to fail with an Access Denied error.
To resolve this problem, add the modify permissions permission for the Exchange Trusted Subsystem to the organizational unit that contains the Distribution Group:
1.       Open Active Directory Users and Computers;
2.       Click View, and then click Advanced Features;
3.       Right-click the OU that contains the distribution lists, and then click Properties;
4.       In the Security tab, click Advanced;
5.       In the Permissions tab, click Add;
6.       In the Enter object name to select box, type Exchange trusted subsystem, and then click OK;
7.       In the Object tab, select This object and all descendants objects in the Apply onto list, locate Modify Permissions in the Permissions list, and then set it to Allow;
8.       Click OK.


Friday, April 1, 2016

Exchange Distribution Group Creation Report

For some organizations, allowing end users to create and manage their own Distribution Groups is a standard practice. It usually alleviates work from ServiceDesk or second/third line support teams and gives users more responsibility and freedom to perform their role.

While this is indeed a great feature, it is always important to have a good naming convention in place and ensure that users adhere to it. But no matter how much we tell users how they should be creating a distribution group, we all know there will be situations where the group is not created as it should have been.

In one hand, for IT to check every day all the groups users created would cause some overhead. On the other hand, leave them for too long and then it might be difficult to rectify a wrongly-created distribution group. So why not automatically generate a report when new groups are created for IT to look at? That way they do not need to keep constantly checking and it is quick and easy to make sure the newly-created groups are OK.

To download the script and the read the entire article, please go to MSExchange’s Exchange Distribution Group Creation Report article page.

Exchange Meeting Room Statistics

Room mailboxes have been available for a very long time now, and most organizations make extensive use of them for all their meeting room bookings. In certain cases, having statistical information about these rooms helps organizations plan or redesign their offices in a more efficient way. This information can show how often certain rooms are utilized, the average meeting duration, who tends to book more meetings, and so on.

In this article we will develop a script to provide us with some of this information and to serve as a stepping stone to gather further information depending on the reader’s particular needs. The end result will look something like this:
In this example, I only searched one meeting room called ITD – 16A – Small CF VC. For the month of December we can see that a total of 115 meetings were booked, out of which 55% are recurring meetings. The average meeting duration was 46 minutes, each meeting had an average of 8 attendees and there were slightly more meetings booked in the morning.

To download the script and the read the entire article, please go to MSExchange’s Exchange Meeting Room Statistics article page.

Saturday, February 27, 2016

Determine Role Needed to Run Specific Exchange Cmdlets

Have you ever wondered what role(s) an account needs in order to run a particular cmdlet? This is important as most organizations follow the Principle of Least Privilege.

Let us say, for example, that we want a particular account to be able to run the Set-ActiveSyncMailboxPolicy cmdlet. What role(s) does that account need?! This is actually simple once we know which cmdlet to use to get this information.

For this example, all we need to run is:
Get-ManagementRoleEntry *\Set-ActiveSyncMailboxPolicy

Now we know that in order to run the Set-ActiveSyncMailboxPolicy cmdlet, we need to add the Recipient Policies role to the role group of the account we want to give access to.

Meeting Room Random Free/Busy Error MapiExceptionRpcServerTooBusy

The other day I was faced with an issue where one or more meeting rooms would randomly not show their free/busy information depending on how many meeting room I was querying at the same time in Outlook. If using Outlook on the Web (aka OWA), a few rooms would not have free/busy information available.

After some digging, I found the following two events logged in the Exchange server (the output has been truncated):
Log Name:      Application
Source:        MSExchange Availability
Event ID:      4009
Task Category: Availability Service
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      EXAIO
Process Microsoft.Exchange.InfoWorker.Common.Delayed`1[System.String]: Unable to open connection for mailbox Exception returned is: Microsoft.Exchange.Data.Storage.StorageTransientException: Cannot query rows in a table. ---> Microsoft.Mapi.MapiExceptionRpcServerTooBusy: MapiExceptionRpcServerTooBusy: Unable to query table rows.

Log Name:      Application
Source:        MSExchange Availability
Event ID:      4009
Task Category: Availability Service
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      EXAIO
Process Microsoft.Exchange.InfoWorker.Common.Delayed`1[System.String]: Unable to open connection for mailbox Exception returned is: Microsoft.Exchange.Data.Storage.StorageTransientException: Cannot open mailbox /o=ADIAEXCHANGE/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Configuration/cn=Servers/cn=EXAIO/cn=Microsoft System Attendant. ---> Microsoft.Mapi.MapiExceptionRpcServerTooBusy: MapiExceptionRpcServerTooBusy: Unable to make connection to the server.

The problem was that the RPC Pool limit was being reached. For each database we can have up to 32 concurrent RPC connections from the same client process. In my case, most meeting rooms were distributed across mainly two databases:
Count Name
----- ----
   83 MDB01
   51 MDB02
    5 MDB03
    3 MDB04
    7 MDB05
    5 MDB06
    4 MDB07
    1 MDB08
    1 MDB09

As you probably guessed, the resolution is to simply split meeting rooms across all databases (when possible). Once I distributed them so there is only 17/18 meeting rooms per database, this error no longer happened.

Monday, February 22, 2016

Create Shadow Copies on the same Active Directory Site

In the Transport High Availability in Exchange 2013 article we discussed, amongst other topics, Exchange’s Shadow Redundancy feature and how it generates redundant copies of e-mails before these being delivered to mailboxes and before Exchange acknowledging to the sending server successfully receiving them.

We also saw that in DAG environments, Exchange gives preference to creating a shadow copy of an email on a DAG member that is located in a different Active Directory (AD) site, if any. But what if we have a DAG that extends one or more AD sites but we want shadow copies to be created only within the same site? If we look at our Transport Config, we will see a ShadowMessagePreferenceSetting parameter (the following output has been truncated):
[PS] C:\> Get-TransportConfig | FL

MaxRetriesForLocalSiteShadow       : 2
MaxRetriesForRemoteSiteShadow      : 4
ShadowHeartbeatFrequency           : 00:02:00
ShadowMessageAutoDiscardInterval   : 2.00:00:00
ShadowMessagePreferenceSetting     : PreferRemote
ShadowRedundancyEnabled            : True
ShadowResubmitTimeSpan             : 03:00:00

The ShadowMessagePreferenceSetting parameters has three possible settings:
  • PreferRemote: Exchange tries to make a shadow copy of the message on a server in a different AD site. If the operation fails, it tries a server in the local AD site;
  • LocalOnly: a shadow copy of the message should only be made on a server in the local AD site;
  • RemoteOnly: a shadow copy of the message should only be made on a server in a different AD site.

Please have in mind that this parameter is only meaningful when the primary server that is trying to make a shadow copy of the message is a Mailbox server that is a member of a DAG that spans multiple AD sites.

As such, if we want our shadow copies to be created within the same site, all we have to do is update the parameter to LocalOnly. However, when we try to do so we might get the following error depending if the other parameters still have their default values:
[PS] C:\> Set-TransportConfig -ShadowMessagePreferenceSetting LocalOnly

The value for MaxRetriesForRemoteSiteShadow must be set to zero for the LocalOnly shadow redundancy preference setting.

So what we need to do is to also update the MaxRetriesForRemoteSiteShadow parameter:
[PS] C:\> Set-TransportConfig -ShadowMessagePreferenceSetting LocalOnly -MaxRetriesForRemoteSiteShadow 0

ExMon for Exchange 2013/2016 Now Available

ExMon, also known as Microsoft Exchange Server User Monitor, has finally been updated for Exchange 2013 and 2016!

You can download the installation file here, as well as a PDF how-to guide on how to use ExMon.

Saturday, February 20, 2016

Distribution Groups Statistics

As an Exchange Administrator, have you ever wondered if all those Distribution Groups are actually being used? Organizations running Microsoft Exchange Server are likely to have been running Exchange for a at least a few years and also likely to continue to do so for a while. After all those years, more and more distribution groups get created, some of them stop being used, some are simply forgotten, etc.

Maybe you got asked by the Audit department or by your manager for a list of the 20 most utilized groups, or maybe you are just curious. The good news is that as long as you have Message Tracking Logs enabled, you can easily get this information!

The easiest way to track messages sent to distribution groups is to list all the expansion events. When a user sends an email to a group, Exchange needs to expand that group in order to know who to send the email to. This gets registered with an EventID of EXPAND. Additionally, the RelatedRecipientAddress field in the EXPAND entry contains the PrimarySmtpAddress of the expanded group. And this is pretty much all the information we need.

Using the following cmdlet, we can get a list of all the emails sent to distribution groups on the 1st of January 2016:
Get-MessageTrackingLog -Start 01/01/2016 –End 01/02/2016 -EventID Expand | Select Timestamp, RelatedRecipientAddress, MessageSubject

But what we really want is to know how many emails were sent to which groups during a particular time. Not a problem! All we need to do is tweak the cmdlet above and add Group-Object:
Get-MessageTrackingLog -Start 01/01/2016 –End 01/02/2016 -EventID Expand | Group RelatedRecipientAddress | Sort Count –Descending | Select Count, Name

Do not forget to add Get-TransportService (or Get-TransportServer in Exchange 2007 and 2010) to get the logs across all transport servers if you have more than one!

If you are interested in getting the Top 20 most used groups, for example, this is also very easy:
Get-TransportService | Get-MessageTrackingLog -ResultSize Unlimited -Start 01/01/2016 -EventID Expand | Group RelatedRecipientAddress | Sort Count -Descending | Select -First 20 | FT Count, Name -AutoSize

Exchange Message Queue RiskLevel

When using the Get-Queue cmdlet to view configuration information for queues on Exchange servers, several properties are available for each queue such as DeliveryType, NextHopDomain, Status, MessageCount, LastError, Velocity, RetryCount, and many, many more.

Some of these properties have already been discussed in articles and/or tips such as Exchange 2013 Queue Velocity. Another interesting one is RiskLevel:

So what is this Risk Level property? Well, according to the Queue filters TechNet article, “this property is reserved for internal Microsoft use, and isn't used in on-premises Exchange 2013 organizations.” As such, I am assuming on-premises customers do not need to worry about this. But just for information, according to the MSDN RiskLevel enumeration webpage, this property has four possible values:
  • Normal: The associated message is normal risk.
  • Bulk: The associated message is part of a bulk mailing.
  • High: The associated message is high risk.
  • Low: The associated message is low risk.