« Posts under Exchange

Exchange: Stop Email Exfiltration

When your users leave or get removed from the organization they may still be getting company confidential information. Here is how you can find out and stop this from happening.

»Read More

Exchange: Database Leveling Redux

Some time ago I tackled the challenge of constructing a variant of the bin packing algorithm for leveling out Exchange databases’ size with the least amount of mailbox migrations necessary. Since then, I’ve been approached by a few people in dreadfully large environments looking for help with errors and compatibility issues around the script I released. I’ve finally rounded back to this script to do it some justice.

»Read More

Exchange Mailbox Auditing with Powershell

Some time ago I wrote a script and GUI for performing security audits of Exchange mailbox and calendar rights in an environment. This script was far more popular than I anticipated and, I’m ashamed to say, was rather poorly written by my current Powershell standards. There is an obvious need to simplify the extraction of mailbox permissions or my old script would not still be so popular. So I’ve started to revisit my old code for this project in hopes of remaking it with my PowerShell reporting engine. The first step in this process is to pull out the several bits of code that do the actual rights/permissions extraction. I think I’ve finally got this part done and see no reason not to release this mini-library of functions first.

»Read More

Lync and UM Correlation with Powershell

I’ve been working on an Exchange/Lync voice deployment lately and have found a new level of frustration for the lack of connectivity between the several voice components involved in turning up such a solution. That being said it is not very difficult to validate your deployment with a bit of Powershell.

There are a few necessary results to gather where I believe it can be easy to ‘miss’ configuration steps when turning up or disabling users:

  • You enable a user for enterprise voice but forget to set their pin
  • You enable a user for enterprise voice but forget to UM enable their mailbox
  • You disable a previously lync enabled user (enterprise voice enabled or not) and forget to disable them in Lync
  • You enable a user for lync enterprise voice and um enable their mailbox but use the wrong extension.

These are just a few areas which can go awry in your environment either during the initial deployment or simply occur over time.

Here is a pretty simple function which I’ve put together which gathers info about all lync enabled accounts and contacts in the environment. As I extrapolate the Exchange UM information from AD attributes this function needs only be run on a Lync server or remote session. Here are the important bits broken down for those who are interested. If you just want the function and do not care for my ramblings you can download it either at the technet gallery or at my new github repo.

First ensure that the lync modules are loaded and available (I use -Verbose:$false throughout the script as I only want my own verbose output to be shown, not verbose output from every lync cmdlet that runs). ‘Break’ is a nice way to simply exit the function. As it is very unlikely this function will be called in a non-standalone manner this kind of non-terminating non-error throwing exit is fine. I throw out a warning at least.

I also break out the properties I’m going to be snatching from users and contacts in AD. This is not at all necessary but it makes for easier script reading later on. Contacts and users are not the same so were I to try and use the user properties against a contact when querying AD I’d get errors.

I then go ahead and query AD for users which are lync enabled. I use an old school LDAP filter because I’m an old school type of guy (well that and opath filters do not always have the nuanced properties available for me to filter against).

If the user is Lync enabled then they also have a primary user address so I use that to gather even more information about the account. I have to do this in order to get the PIN information as that is not held in AD from what I could tell. In fact, if you remove the -Verbose:$false from the Get-CSClientPinInfo and run this whole function with the -Verbose parameter you will see the Lync cmdlet spit out primary frontend server names that are getting queried for PIN info.

At this point since I already have the Lync info I go ahead and use it to determine if the user is UM enabled or not. If it is UM enabled I look for any proxyAddress starting with eum: followed by some digits and that is very likely an extension for the voicemail for this user.

With the information we have collected I create another object and return it. I use a bit of regex trickery to extract the telephone number and extension from the full LYnc URI while I’m at it.

As it is very possible to have enterprise voice enabled contacts (that is all an autoattendant is in AD) we should probably get that information as well. I use Get-ADObject with another ldap filter to only look for contacts which are lync enabled.

I then return everything pretty much the same way as I did for user accounts except skip the voicemail and pin checking (though now that I’m writing this and thinking about it a pin check against enterprise voice enabled contacts may not be a bad idea….).

With this function you can now create and export reports with some interesting information that may help in your deployment. Here are a few examples.

As always, I welcome feedback and improvements. You can download the function in its entirety from the technet gallery or at my new github repo.

 

Exchange: Handling Old Log and Other Files

In Exchange old logs can really build up fast. Not database transaction logs but rather temporary transport, client access, IIS, and other debug related crap that typically default to locations either on your system drive or Exchange install path. Of course, Powershell scripting can provide a decent solution for this problem.

Introduction

More than any other version, Exchange 2013 seems to like logging information to disk. By default, much of what gets logged will not auto-rotate (or if it does, it happens infrequently) either so you end up with this slow ticking time-bomb in your environment.

I’ve been using a few one liners for a while now to pare down old logs and such from Exchange 2013 servers. In a pinch this still works just fine:

The down side to this quick approach is that you have to run this directly on each server and there is no real reporting on how much space you are saving. It also requires knowing where some of the logs are ahead of time (c:\inetpub). Finally, this only gets a small subset of the logs most likely to balloon out of control.

In any case it is all very manual and is just a quick hack. So I finally decided to put an official script together instead. And, as I tend to do with scripts, I probably over-engineered the solution. But it works for me and may be valuable to you even if you are not explicitly using it for Exchange.

Interesting Script Notes

One of the issues with existing scripts for cleaning out exchange logs is that they are based around the files being located in the same locations on every server. I get around this with some psremoting (invoke-command) to gather web logging locations and exchange install paths.

Note: Enable remoting with the following in a cmd prompt:

winrm quickconfig

Since I’m already using psremoting to get log file locations I also use it again for some of the folder size reporting to get some performance boosts. (Remotely enumerating several hundred files can take a very long time in powershell but you can get around this with Scripting.FileSystemObject run locally on a system). This only makes sense if you are looking for entire folder size information. If you are filtering folders by file type or date for utilization there is no real choice but to use builtin powershell looping.

Here is the function I put together for getting the folder size with all of these factors. I added in some logic at the very beginning to determine if the path is local or remote as well.

I’ve wrapped up a number of additional functions with this folder size function in a single script with some predefined scenarios to make the script easier to use. The scenarios included are:

RetrieveValidFolders – Gather a list of valid Exchange logging and temp folders which you can use to pipe into other functions to perform custom actions.

ReportOldLogSize – Gather a list of valid Exchange logging and temp folders and also enumerate their total size as well as the size of all the old logs that exist before the specified number of days. This includes message tracking logs.

DeleteOldLogs – Attempt to delete all logs which are older than the number of days specified. This does NOT include message tracking logs.

DeleteOldLogsTestRun – Same as DeleteOldLogs but without actually deleting anything (adds –WhatIf to all Remove-Item commands). This does NOT include message tracking logs.

These scenarios work in concert with the available parameters to give you more control of which servers will be targeted and how many days worth of logs you want to keep.

DaysToKeep – The number of days of log files you wish to retain.

ServerFilter – Target specific Exchange 2013 servers. By default all (*) servers in the environment are targeted.

FileTypes – The types of old files to report upon or delete. By default this is *.log and *.blg. You may want to manually set this to * instead to force psremoting and fast directory size enumeration.

It should be noted that I’m not even trying to rotate or save the old files with this script. This is was written to report upon and optionally delete old logs and other temporary files related to Exchange 2013. Obviously take care with what you delete in your own environment.

The default file types which will be reported upon or cleaned up are *.log and *.blg (daily performance counter files). Optionally you may want to include *.bak to get some of the perfmon counter load backup files as well.

Examples

Here is a report of logs older than 14 days. Note that the message tracking logs are included here but are not part of the actual deletion scenarios unless you make manual modifications (add in your own scenario).

image

Here is a more complicated example which targets one specific server. The following lines will gather only total folder size information via psremoting (thus speeding up processing time) first. We then delete any *.log, *.blg, and *.bak files older than 14 days. Finally we generate a report on the folders previous vs. its current size. Again notice that I don’t futz with message tracking at all. But since it is included in the report aspect of this script the folder for message tracking actually goes up in size!

SizeDiffReport

Conclusion

This should be a pretty easy script to schedule via task scheduler if you so desired. To download the script in its entirety visit the technet gallery.

Update: Get-CalendarPermission

Going through older code is a bit like looking through an old yearbook or photo album. If the pictures within are old enough you usually end up laughing at how little you recognize yourself and maybe even marvel a bit at how far you have come. This old function I wrote isn’t the worst of my code but I was still able to update it for measurable improvements.

»Read More

Exchange: Receive Connector Tango! – Part 2

In part 1 of this series I discussed some basic knowledge requirements to get a better grip on receive connectors in Exchange. I continue that conversation with some examples of improperly configured connectors and the issues they may cause. I finish up the discussion with a script you can use to scan your environment for such configurations. »Read More

Exchange Log Level GUI Script

I ran into a situation recently where I was forced to amp up the Exchange logging levels to further troubleshoot an issue with some pretty specific Exchange components. I found myself wanting a quick GUI to view and set the levels but found none. So I used this as an opportunity to learn a bit about xaml based GUIs and powershell. The result is this simple, but useful, Exchange log level GUI script which was written for Exchange 2013 but should also run on 2010.

»Read More

Exchange: Receive Connector Tango! – Part 1

Exchange receive connectors are often configured incorrectly or worse, insecurely. This is the first of a two part series about Exchange receive connectors and what to look out for when setting them up. »Read More

Exchange: Update Distribution Group Managers Script

A small script to automatically update distribution group owners based on an AD security group.

»Read More

Follow

Get every new post delivered to your Inbox

Join other followers