Count emails sitting in a specific queue across multiple Exchange servers

Doing some testing today, I needed to check how many emails were sitting in Exchange queues across 6 different transport servers. The queues in question were outbound queues for journaling.

Since the queues on each server have a numeric name that’s of no use for this, I was able instead to search based on the next hop domain. All of our journal queues point to smart hosts with “journal” in the FQDN.

Here’s how I got the total count of messages sitting in the 6 queues:

Get-TransportServer | Get-Queue | Where-Object {$_.NextHopDomain -like "*journal*"} | Measure-Object -Sum -Property MessageCount

An alternative, which I discovered afterwards, would be to filter directly on Get-Queue instead of piping all of the queues to Where-Object:

Get-TransportServer | Get-Queue -Filter "NextHopDomain -like '*journal*'" | Measure-Object -Sum -Property MessageCount

Further Reading:

Remove Empty Public Folders in 3 Lines of PowerShell

I’ve had this on my to-do list for a long time, and have finally gotten around to looking into it. We’ve largely migrated off Public Folders (thank goodness), but we still have thousands of empty folders sitting there.

I’d originally thought about writing some sort of crazy tree-traversal script to delete empty folders, but as it turns out, this alternative does the job fine. It allows you to delete batches of empty folders at a time. You could schedule the script to run once every hour or so.

The script does the following:

  1. Gets the first 500 Public Folders, narrows that down to those that don’t have subfolders
  2. Filters those down again, to exclude folders that contain items
  3. Deletes the folders, logging the folder name to c:temppf_delete.log
$folders = Get-PublicFolder -Identity "folder name" -Recurse -ResultSize 500 | Where-Object {$_.HasSubFolders -eq $false}
$emptyFolders = $folders | Where-Object -FilterScript {@($_ | Get-PublicFolderItemStatistics).Count -eq 0}
$emptyFolders | ForEach-Object {$_.Identity.ToString() | Out-File c:temppf_delete.log -append; Remove-PublicFolder -Identity $_.Identity -Confirm:$False}

I originally used Get-PublicFolderStatistics to determine the item count within the folder, but that was really slow. I ended up using @(Get-PublicFolderItemStatistics).Count instead, as that was much faster. The latter takes 1 second per folder, as opposed to 21 seconds per folder for the former.

An alternate method would be to loop over the above routine several times, each time retrieving less items. This will clean up nested folders from the top of the tree a little faster:

(1..5) | % {
  $folders = Get-PublicFolder -Identity "folder name" -Recurse -ResultSize 100 | Where-Object {$_.HasSubFolders -eq $false}
  $emptyFolders = $folders | Where-Object -FilterScript {@($_ | Get-PublicFolderItemStatistics).Count -eq 0}
  $emptyFolders | ForEach-Object {$_.Identity.ToString() | Out-File c:temppf_delete.log -append; Remove-PublicFolder -Identity $_.Identity -Confirm:$False}

Obviously, you need to test this thoroughly before running it in a production environment. Run at your own risk.

Outlook/Exchange NDR: “Delivery has failed to these recipients or groups” for user with Send-As permissions

Had a user today that was receiving an NDR when trying to send as another user. This was strange as this user has always had full mailbox access and send-as permissions to the mailbox in question, so the NDR was unexpected.

It turned out to be an issue with cached address entries when typing the sender’s address into the “From” field in Outlook. I removed all of the relevant entries and then resolved the sender from the address book, and the email went through without any issues.

One for the memory banks…

Updating multiple Exchange 2010 Receive Connectors at once

Although I haven’t really delved into it properly yet, PowerShell is an awesome tool to have in your toolkit when managing Exchange. When we deployed Exchange 2010, I supplied the sysadmins in our other offices with a list of PowerShell commands to configure their servers appropriately. This saved a massive amount of time and hassle.

I recently had to bump up the incoming message size limit on our incoming SMTP (from Messagelabs) Receive Connectors to 26MB on five different servers.

Back in the days of Exchange 2003, embarrassingly for me, not that long ago; the same task would have required much mouse clicking and searching for settings. Now, in Exchange 2010, since I’ve followed a naming convention for the connectors across all of the servers, it’s easy to retrieve all of the relevant ones at once:

[PS] C:>Get-ReceiveConnector |Where-Object  {$_.Identity -like "*Messagelabs*"} | fl identity

Identity : SITE1-MAIL-CAS1Incoming SMTP from Messagelabs SITE1-MAIL-CAS1 Identity : SITE1-MAIL-CAS2Incoming SMTP from Messagelabs SITE1-MAIL-CAS2 Identity : SITE2-MAILIncoming SMTP from Messagelabs SITE2-MAIL Identity : SITE3-MAILIncoming SMTP from Messagelabs SITE3-MAIL Identity : SITE4-MAILIncoming SMTP from Messagelabs SITE4-MAIL Identity : SITE5-MAILIncoming SMTP from Messagelabs SITE5-MAIL

Updating the MaxMessageSize on all of the connectors is then as simple as issuing this one liner:

Get-ReceiveConnector | Where-Object  {$_.Identity -like "*Messagelabs*"} | Set-ReceiveConnector -MaxMessageSize 26mb

The great thing with many PowerShell commandlets is that you can “get” the objects you’re after, and then pipe the results into the command that makes the changes.

This is just a really simple example, and most experienced Exchange admins would probably laugh at the fact that I’ve documented something this simple – but I just wanted to highlight how easy it is to make “bulk” changes with PowerShell and EMS, the Exchange Management Shell.

Remember that you might want to run commands such as this with the “-WhatIf” switch just to check what’s going to be affected before going ahead:

[PS] C:>Get-ReceiveConnector |Where-Object  {$_.Identity -like "*Messagelabs*"} |Set-ReceiveConnector -MaxMessageSize 26mb -WhatIf
What if: Configuring Receive connector "SITE1-MAIL-CAS1Incoming SMTP from Messagelabs SITE1-MAIL-CAS1".
What if: Configuring Receive connector "SITE1-MAIL-CAS2Incoming SMTP from Messagelabs SITE1-MAIL-CAS2".
What if: Configuring Receive connector "SITE2-MAILIncoming SMTP from Messagelabs SITE2-MAIL".
What if: Configuring Receive connector "SITE3-MAILIncoming SMTP from Messagelabs SITE3-MAIL".
What if: Configuring Receive connector "SITE4-MAILIncoming SMTP from Messagelabs SITE4-MAIL".
What if: Configuring Receive connector "SITE5-MAILIncoming SMTP from Messagelabs SITE5-MAIL".

Propagate mailbox folder permissions

I recently had the requirement where somebody required another person to access a specific folder in their mailbox. We didn’t want to grant full mailbox access. This normally isn’t a problem as we’d just set the permissions on the individual folders in Outlook, but the user in question had an extensive folder structure set up.

I found several tools that were capable of doing this, but I wasn’t going to pay USD$500+ for a tool I was going to use once. In addition to that, some tools didn’t work against Exchange 2010. That equates to a pretty bad investment for our company as we’re currently migrating from Exchange 2003 to Exchange 2010.

I also toyed with the following ideas:

  1. Doing it in Powershell: I’m no Powershell guru, so it would take some time – plus I’d need to move the user’s mailbox to Exchange 2010 before I could use Powershell
  2. Using EWS and write a desktop app in C# (Interesting, but too time consuming)

The Microsoft Exchange Server Public Folder DAV-based Administration Tool (PFDAVAdmin) can be used to do exactly this (and a myriad of other things). Note that the tool has also been renamed and updated to work with Exchange 2010 (including EX2010 SP1).

I’ll be working with the legacy WebDAV version in this example, as the mailbox in question still resides on the Exchange 2003 server.

Andrew Shugg raised a good point in the comments section:

Worth noting that the “classic” PFDAVadmin requires .NET Framework 1.1, and if you try to install that on a modern server system (e.g. Windows Server 2008, Windows SBS 2008) you’ll get warnings about it breaking things in IIS.

If possible, install PFDAVadmin and the .NET Framework 1.1 on a desktop system or non-critical server.

  1. Downloadand extract PFDAVAdmin
  2. Run the tool, PFDAVAdmin.exe
  3. Go to File, Connect, specify the connection details, and connect
  4. Drill down to the mailbox in question, and then to Top of Information Store
  5. Locate the starting-level folder that you’re going to assign permissions to. Ensure that the permissions are correct at that level (right-click, Folder Permissions)
  6. Right-click on that same folder again, and select Propagate ACEs
  7. Select the ACEs (Access Control Entries) that you wish to propagate
  8. Leave the other settings on their defaults, so we’re Adding/Replacing the specific ACE on subfolders
  9. The tool will then run through all of the folders. In my case, this user had hundreds of folders that needed to be modified:

The same process can be used to remove the permissions later on.

Quite handy.