Steve Goodman's Exchange Blog
8Dec/110

Updated – Disabling Auto-mailbox mapping in Exchange 2010

imageIn February this year I wrote about how to disable the automatic mapping of shared mailboxes in Exchange 2010 SP1, using a custom PowerShell script that "wraps" the Add-MailboxPermission command and after execution, removes the attribute in Active Directory that is used to automatically mount the mailbox in Outlook.

With Exchange 2010 SP2, there's great news - this workaround is no longer required, as in SP2 a new parameter has been added to the native cmdlet.

Check out the updated article here, and stay tuned for a future article explaining how to extend this functionality to the Exchange Management Console :-)

20Jun/1128

V1.1 of Exchange Environment Report script available now

imageOver the weekend, I’ve been working on incorporating the many suggestions for improving the Exchange Environment Report script, so a big thanks to everyone who’s found the script useful, found additional uses, reported bugs and suggested additional information that would be useful.

The major new feature with this version is full support for Exchange 2007-only environments, with a similar level of detail. The original version was solely intended to be useful from the Exchange 2010 management shell, so there was some work required to use alternative command parameters. I’ve also used a line of code from an a excellent one liner by Gary Siepser to get the Exchange 2007 database size. As part of the above support, information is also displayed for non-DAG mailbox databases in an Exchange 2010 environment.

In addition, a the following other features have been added:

  • Now only displays the versions of Exchange 2007 and 2010 in use in the green organization section
  • Shows the current Update Rollup, using code based on Bhargav Shukla’s excellent Update Rollups script
  • Average sizes for mailboxes and archive mailboxes on a per-database level
  • Last date/time of full backup (but only if at least one database in each DAG/non-dag list has had a full backup)
  • Circular logging state (again, only shown if at least one database in each DAG/non-dag list has circular logging enabled)

Bugs fixed include checking for Powershell version, improved progress information for large Sites and DAGs, detection for sites with no Exchange servers, no DAGs and a number of changes to the way Database information is collected for Exchange 2007 support.

As well as permissions to Exchange cmdlets and WMI to discover the remote OS and Service Pack, this version also attempts to check the file size of Exchange 2007 databases using WMI ,and attempts to connect to each Exchange server using Remote Registry to check the Update Rollup version.

Just like the previous version this has been tested in multiple Exchange environments including Exchange 2010-only DAG/non DAG, Exchange 2010/2007 mixed and from Exchange 2007, but if you find any more bugs let me know.

So, if you’d like to try out the new version of the script, it’s available for download at the original blog article.

8Jan/110

Report your Exchange Offline Address Book Sizes using Powershell

Just a quick post for Saturday. If you'd like to check your OAB sizes, here's a quick script that allows you to do so quickly and easily. This could be useful to keep track of the space used over time, check all OAB replicas are the same size or to quickly check that the sizes have changes after manually running the Update-OfflineAddressBook cmdlet.

There's few pre-requisites, You need to be on a machine that has at least read access to the C$ shares on the Client Access Servers hosting the OAB folders along with access to get information about the Offline Address Book and OAB Virtual Directories.

Once those pre-reqs are fulfilled, usage is simple:

.\Get-OABSizes.ps1

The output should look similar to this:

image

You can of course pipe the output and filter it, i.e.

.\Get-OABSizes.ps1 | Where {$_.Server -like "EXCH-CA*"} | Select Server,OABSizeKB

image

The Get-OABSizes.ps1 Script

#
# Get-OABSizes.ps1
# Fetches the total file size of each copy of each offline address book
#
# Steve Goodman
#

# Retrieve all OABs
$OABs = Get-OfflineAddressBook
 # Cycle through each OAB
foreach ($OAB in $OABs)
{
    # Cycle through each OAB Virtual Directory for the current OAB
    foreach ($OABVirtualDirectory in $OAB.VirtualDirectories)
    {
        # Get the actual OAB Virtual Directory properties
        $OABVirtualDirectory = Get-OabVirtualDirectory -Identity $OABVirtualDirectory;
        # Retrieve the folder local to the CAS that hosts the OAB, and append the Guid of this OAB
        $LocalOABPath = "$($OABVirtualDirectory.Path)\$($OAB.Guid)";
        # Get the UNC path used to get to the hidden C$ share on the CAS
        $BaseUNCPath = "\\$($OABVirtualDirectory.Server)\C$";
        # Replace the local path with the UNC path to the CAS server
        $UNCOABPath = $LocalOABPath.Replace("C:",$BaseUNCPath);
        # Get the directory listing of the folder hosting the OAB
        $OABItems = Get-ChildItem -Path $UNCOABPath
        # Calculate the total size of the folder hosting the OAB, in bytes
        [int]$TotalBytes = ($OABItems | Measure-Object -Property Length -Sum).Sum;
        # Convert the total size in bytes to kilobytes
        [int]$TotalKBytes = $TotalBytes/1024;
        # Build the output object for this copy of the OAB and output it
        $Output = New-Object Object
        $Output | Add-Member NoteProperty Server $OABVirtualDirectory.Server;
        $Output | Add-Member NoteProperty Name $OABVirtualDirectory.Name;
        $Output | Add-Member NoteProperty OABName $OAB.Name;
        $Output | Add-Member NoteProperty OABSizeKB $TotalKBytes;
        $Output
    }
}

Download Get-OABSizes.ps1

Hope you find this useful.

3Jan/1118

Setup and use the GAL Photos feature using Exchange 2007 [Updated]

If you're not using Exchange Server 2010 yet, then you might wonder if you can take advantage of some of the newer features available in Outlook 2010. While mailtips, personal archives and automatic mailbox mappings aren't possible, you can make use of the GAL photo feature.

It's fairly painless to enable this and the setup steps for your organisation are the same as Exchange 2010. Once you've sorted the org pre-requisites, then the only piece missing is the cmdlets to import the photos. Although you can use Sharepoint 2010 to do this (and delegate it to end-users), I thought it would be useful to have a simple drop-in Powershell script that can accomplish this in the same way as you can in Exchange 2010.

Getting Active Directory Ready

The AD pre-requisites are fairly simple. You need to ensure the attribute the photo is stored in is replicated to the Global Catalog, and ensure you have either a Windows Server 2008 or later Domain Controller in your domain, or simply prepare your Windows 2003 forest schema for 2008:

  1. If you are in a multi domain environment, follow "A minor schema change" in the Exchange Team blog post GAL Photos in Exchange 2010 and Outlook 2010. If it's a single-domain environment you're all set.
  2. If you don't have at least one Windows 2008 / 2008 R2 Domain Controller, you need to run adprep /forestprep from the 2008/2008 R2 setup CD as described in the article Prepare a Windows 2000 or Windows Server 2003 Forest Schema for a Domain Controller That Runs Windows Server 2008 or Windows Server 2008 R2. You don't need to install a Windows 2008 / 2008 R2 domain controller, just update the schema. More details on why this is required here.

Importing Photos

In Exchange 2010, you use the Import-RecipientDataProperty cmdlet to import photos. This command isn't provided in Exchange 2007 so I've written a short Powershell script that can do this for you. It's usage is almost identical to the Import-RecipientDataProperty cmdlets, except that you don't need to specify which property to import (obviously) and you don't need to do submit the file as a byte-encoded array - you just give the filename.

Usage is simple:

.\Import-Picture.ps1 -Identity stevegoodman -Path .\Steve_96x96.jpg

Then, once AD has replicated, the Offline Address Book is updated (for example, using Update-OfflineAddressBook "Default Offline Address Book"), and clients have downloaded the new OAB, photos should now show in Outlook 2010 (or 2003 and 2007 - check my previous article!)

Removing Photos [New]

If you want to remove a photo from a contact, you need to clear the relevant attribute in Active Directory. As above, I've provided a script that can do this - for example, to clear the GAL picture:

.\Clear-Picture.ps1 -Identity stevegoodman

The Import-Picture.ps1 and Clear-Picture.ps1 Scripts

param($Identity,$Path);
#
# Import a JPEG file into Active Directory for use as the Exchange / Outlook GAL Photo
# Best results - Under 10K, 96 x 96
#
# Steve Goodman
if (!$Identity)
{
    throw "Identity Missing";
}
if (!$Path)
{
    throw "Path Missing";
}
if (!(Get-Command Get-User))
{
    throw "Exchange Management Shell not loaded";
}
$User = Get-User $Identity -ErrorAction SilentlyContinue
if (!$User)
{
    throw "User $($Identity) not found";
}
if (!(Test-Path -Path $Path))
{
    throw "File $($Path) not found";
}
$FileData = [Byte[]]$(Get-Content -Path $Path -Encoding Byte -ReadCount 0);
if($FileData.Count -gt 10240)
{
    throw "File size must be less than 10K";
}
$adsiUser = [ADSI]"LDAP://$($User.OriginatingServer)/$($User.DistinguishedName)";
$adsiUser.Put("thumbnailPhoto",$FileData);
$adsiUser.SetInfo()
param($Identity);
#
# Clear the GAL Picture attribute
#
# Steve Goodman
if (!$Identity)
{
    throw "Identity Missing";
}
if (!(Get-Command Get-User))
{
    throw "Exchange Management Shell not loaded";
}
$User = Get-User $Identity -ErrorAction SilentlyContinue
if (!$User)
{
    throw "User $($Identity) not found";
}
$adsiUser = [ADSI]"LDAP://$($User.OriginatingServer)/$($User.DistinguishedName)";
$adsiUser.PutEx(1,"thumbnailPhoto",$null)
$adsiUser.SetInfo()

Download E2007-Picture.zip

Finally, if you have any problems or questions, let me know as usual in the comments…