Thursday, January 29, 2015

Script to Remove Old IIS Logs

One of the ongoing issues I seem to run into is Exchange servers running low on disk space for the C: drive. When this happens messages stop flowing because Exchange doesn't want to run out of disk space.

Much of the time, the disk space on C: is being eaten up by IIS logs. IIS does not have any functionality to automatically delete old logs. So, I've seen servers with years of logs stored in C:\Inetpub\Logs\.

Here is a script that you can schedule as a task to remove old IIS log files:
# Adjust these two variables
$iisLogDir = "C:\inetpub\logs"
$deleteAfterDays = 14

#calculate date for deletion
$removeDate = (Get-Date).AddDays(-$deleteAfterDays)

#Delete Files
Get-ChildItem -Path $iisLogDir -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $removeDate } | Remove-Item -Force
This calculates the age of the file based on the creation time. If you want it to be based on modified time use $_.LastWriteTime instead.

The Where-Object command uses !$_.PSIsContainer (not container) to skip directories and only select files.

Friday, January 23, 2015

Elevate to Administrator from a PowerShell Script

I haven't tested it out yet, but here is a link to code that will raise the prompt to admin credentials if you didn't when you started it:

Monday, December 29, 2014

Unhealthy Directory Synchronization Notification - Expired Credentials

As you may be aware, when there are issues with Dirsync connecting to O365, you get an Unhealthy Directory Synchronization Notification email. The email doesn't provide any information other than to check the event logs. I got this notification for my test environment recently.

I happened to have the Synchronization Service Manager (miisclient.exe) open on my Dirsync server and looked in there first. The Active Directory Connector had a status of Success, which is expected. So, all good on the local side. However, the Windows Azure Active Directory Connector had a status of "stopped-extension-dll-exception".

The Application event log gave more information:
  • Directory Synchronization, Event ID 115 - Access to Windows Azure Directory has been denied
  • Directory Synchronization, Event ID 0 - Update your password and try again
  • Directory Synchronization, Event ID 655-  Failed credential provisioning ping
The cause of my error was an expired password on the account I was using for directory synchronization. I was using a dedicated cloud account in Office 365 that I was not monitoring. The password for the account expired and was not allowing authentication for the account.

The fix was to perform the following:
  1. Log in to Office 365 as an administrator and reset the password for the directory synchronization account.
  2. Update the password in Dirsync.
To update the password in Dirsync, you can run Directory Sync Configuration again. However, instead, I updated the credentials in Synchronization Service Manager. To do this in Synchronization Service Manager, use the following steps:
  1. Open Synchronization Service Manager (miisclient.exe).
  2. In Synchronization Service Manager, click Management Agents and double-click Windows Azure Active Directory Connector.
  3. In the Properties window, click Connectivity.
  4. On the Connectivity page, update the Password and click OK.
  5. Run Start-OnlineCoexistenceSync (or wait for Dirsync to do it automatically)

Update Dirsync Credentials

The long term fix for this issue to prevent the Dirsync credentials from expiring on the account. In the graphical interface of O365 management, you can configure a password expiration policy for all cloud accounts but not individual cloud accounts. To set the password expiration policy for a single account, you need to use Windows PowerShell and the command Set-MsolUser -UserPrincipalName -PasswordNeverExpires $true.

A complete set of instructions is here:

Friday, December 19, 2014

Updated Exchange Online Protection Addresses - Jan 2015

Microsoft has indicated that they are going to be updating the Exchange Online Protection addresses in January 2015. Here is a link with the new IP addresses:
What does this mean to you? Well, these are the outbound addresses from EOP to your on premises email system. So, if you are using EOP for your on-premises email system, you need to ensure that your firewall is updated to allow traffic from these IP addresses to your on-premises email system.

Also, it is not explicitly stated, but I would be concerned that mailflow for hybrid environments will be affected. So, it may be necessary to go into the receive connector used for hybrid mailflow and allow these IP addresses there also. I'll try to check on my hybrid system when the changes go into effect in January and update this post.

Saturday, December 6, 2014

Terminal Services Device Redirector Missing

We have a client using SBS 2008 that is unable to use printer redirection to print locally when connected to the server via RDP. Printer redirection is basic functionality in RDP and normally works without any setup at all. We took over maintenance on this server from another organization about 4 years ago, but never had any need to test or use printer redirection until recently.

After taking a look at the event logs, we saw EventID 1103 for Microsoft-Windows-TerminalServices-Printers with the following message:
An internal communication error occurred.  Redirected printing will no longer function for a single user session.  Check the status of the Terminal Services Device Redirector in the System folder of Device Manager.
The Terminal Services Device Redirector is a device driver that is responsible for printer redirection. On this server, the Terminal Services Device Redirector did not exist in Device Manager. So, we need to install it.

Conveniently, several web sites provide instructions on how to use the devcon utility to install the RDPDR driver and get this going again. However, many of these are for Windows Server 2003. On Windows Server 2008, which is 64-bit, the included devcon utility doesn't work properly because it is 32-bit. The 32-bit version of devcon can query drivers, but not change or add them. It will give a delightfully generic error message of "Devcon Failed".

So, step 1 is to download the 64-bit version of devcon. It is included as part of the Windows Driver Kit. This article describes how to download the 600 MB Windows Driver Kit and extract only the 64-bit version devcon from it:
After you have the correct version of devcon, installation of the Terminal Services Device Redirector is easy. Run the following command and then restart the server (note the space between inf and root):
  • devcon -r install %windir%\inf\machine\inf root\rdpdr
After a reboot I was able to redirect printers properly. I have no idea how this went missing in the first place.

Microsoft has a TechNet article about this event ( but I found at least one item in it may be inaccurate. The article states that there should be a registry key for the RDPDR at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\RDPDR. The system I was working on did not have this registry key before or after I fixed it by installing the Terminal Services Device Redirector. Instead, there was some information added to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\System\0003. This may be because I added it manually.

The article also mentions the idea of reinstalling Terminal Services as a fix. Given that this server did not have Terminal Services installed, I'm not sure how we would have accomplished that. It had remote access enabled in Admin mode, but not full on Terminal Services.

If what I have written doesn't fix your issue with Terminal Services printing, take a look at this article by It has a whole bunch of issues to look at:

Friday, November 28, 2014

Outlook 2013 - Constant restarts required

During a recent migration from Exchange 2007 to Exchange 2013, we ran into an issue that I was unaware of. Outlook 2013 was popping up multiple times per day with the following message:
The Microsoft Exchange administrator has mad a change that requires you to quit and restart Outlook.
After doing some research this appears when the default public folder database for a Mailbox database is set to a non-existent public folder database. In our scenario, we removed Exchange 2007 public folders after introducing Exchange 2013. Consequently, the Exchange 2013 databases were configured to use the Exchange 2007 public folder database as default. After removing the Exchange 2007 public folder database, the Exchange 2013 database were still configured to use the deleted public folder database that was now in deleted objects.

This issue seems to be specific to Outlook 2013 and Exchange 2013 CU5. I have not applied CU6 because there are known compatibility issues with Exchange 2007 coexistence for ActiveSync.

The fix for this was to use ADSI Edit and clear the msExchHomePublicMDB attribute on the database object. The databases for Exchange 2013 are located in: CN=Configure,DC=domain,DC=com > CN=Services > CN=Microsoft Exchange > CN=OrganizationName > CN=Administrative Groups > CN=Exchange Administrative Group (FYDIBOHF23SPDLT) > CN=Databases.

Properties of Mailbox Database in ADSI Edit

For more information about this issue, see:
UPDATE: We were also running into a strange issue with Outlook 2007 where clients would connect and be able to send messages immediately but not send for a few minutes. That issue was also resolved by removing the reference to the old public folder database.

Monday, November 24, 2014

Searching the Message Tracking Log for Virus Recipients

We had a client get infected with a virus today that used Outlook for sending messages out. This was unusual. Most viruses attempt to deliver email themselves and can be blocked by the firewall. Because this virus used Outlook, the messages were sent through the Exchange server which is allowed to deliver email to the Internet.

Three specific users got infected and I wanted to be able to inform those that were sent messages not to open them. I could get this information from the message tracking log based on the subject of the message. I used three commands to dump the information to a text file.

First, get the list of messages sent by a specific user:
$UserMessages=Get-MessageTrackingLog -Start "MM/DD/YYY 00:00:00AM" -Resultsize Unlimited | Where-Object {$_.MessageSubject -like "SubjectOfVirusMessage" -and $_.EventID -like "Send" -and $_.Sender -like "SenderEmailAddress"

Second, build a list of message recpients:
ForEach ($m in $UserMessages) {$UserRecipients=$UserRecipients+$_.Recipients}

Finally, dump to text file.
$UserRecipients > C:\UserRecipients.txt

I then provided the text file to each user to inform the necessary recipients.