Monday, December 22, 2008

Converting Mail-Enabled recipient to Mailbox-Enabled recipient

    Out of the box, MS Exchange 2003/2007 do not offer any kind of way converting a mail-enabled recipient (MEU) into a mailbox-enabled recpieint (MBXU).  At first, you would think that scenario is least likely. Mail-enabled recipients forward to outside of exchange organization and why would you create a mailbox.  Well, in complex environments where organization has multiple email systems and a user wants to migrate to exchange but already utilizes AD, or if your organization is going through a complex migration.

    To convert an MEU into MBXU, we could just strip the AD object of exchange attributes and then ask exchange to create a mailbox.  However, you will notice that there might be side effects. Any secondary emails that might be attached to the MEU are now gone.  Secondly, a less trivial issue, is that repliability of emails which contain MEU address book entry is now broken. To fix these both, you’ll need to track secondary emails and legacyExchangeDn of the MEU and append them to proxyAddresses attribute when MBXU is created.


$userIdentity = 'testuser'
$mailboxDatabase = exserver\mbxdb'
$err = @()
$user = Get-MailUser -Identity $userIdentity `
-ErrorAction SilentlyContinue -ErrorVariable +err
if ($err.count -ne 0)
{
Write-Error '
The user is not a mail-enabled user.'
return;
}
$mbxDB = Get-MailboxDatabase -Identity $mailboxDatabase `
-ErrorAction SilentlyContinue -ErrorVariable +err
if ($err.count -ne 0)
{
Write-Error "The database value is incorrect."
return;
}
$extAddress = $user.ExternalEmailAddress
$currAddresses = $user.EmailAddresses
$legDn = $user.LegacyExchangeDn
Disable-MailUser $user -Confirm:$false | Out-Null
$mbxUser = Enable-Mailbox $user -Confirm:$false `
-Database $mailboxDatabase
$addresses = $mbxUser.EmailAddresses
if ($mbxUser.LegacyExchangeDn -ne $legDn) {
$addresses.add("X500:$legDn")
}
$currAddresses | ?{ $_ -ne $extAddress } | %{
if ( -not $addresses.Contains($_)) {
$addresses.Add($_) | Out-Null
}
}
if ($addresses.Changed) {
Set-mailbox $mbxUser `
-EmailAddresses $addresses | Out-Null
}

Thursday, December 18, 2008

C# Events and thread-safety


After reading “C# Programming Language”, which is more or less a dictionary of C# language features, I noticed that the spec claims thread-safety in event default accessors.

So code defined like this:

public event SomeEvent;
compiled into something roughly as this:
   1:  private EventHandler __SomeEvent;
   2:  public event SomeEvent {
   3:      add { lock(this) { __SomeEvent += value; }}
   4:      remove { lock(this) { __SomeEvent -= value; }}
   5:  }

Actually, add and remove keywords are translated as add_SomeEvent and remove_SomeEvent methods with [MethodImpl(MethodImplOptions.Synchronized)] attributes and thus equivalent to lock(this) shown above.

However, There is a problem here to achieve thread-safety. Using [MethodImpl(..)] is a bad practice b/c your code is trying to enter a monitor for this object instance. Thus, if another thread of execution obtains the monitor first, your subsequent call to “+=” or “-=” will block and will be hard to troubleshoot.

Instead consider this pattern where you implement custom accessors locking on a private object and give caller to invoke event safely through a method:

private object l_SomeEvent;
private EventHandler __SomeEvent;
public event SomeEvent {
add { lock(l_SomeEvent) { __SomeEvent += value; }}
remove { lock(l_SomeEvent) { __SomeEvent -= value; }}
}
public void OnSomeEvent(EventArgs e) {
EventHandler temp;
lock(l_SomeEvent) { temp = __SomeEvent; }
if (temp != null) { __SomeEvent(this,e); }
}

Tuesday, November 25, 2008

Using Export-Mailbox CmdLet to export to PST file

In order to export mail to a PST file, EMS requires an Outlook MAPI to be present. Otherwise,

11-17-2008_Error_ExportMailboxNot64bitCapable

That means you must use 32-bit version of the Exchange Management Tools on an Outlook-installed workstation because 64bit EMS process cannot load 32-bit MAPI subsystem.

Thus, I quickly ran through a Vista 32bit set up steps.

1. Install Outlook

2. Install IIS Requirements

11-19-2008-IIS_Options_Ex2k7MgmtTools

3. Install 32bit Exchange Management Tools, here.

Done!

Friday, October 17, 2008

New Drop of Gallio 3.0.4 is out

New drop of Gallio is up and ready. It has a number of feature improvements, discussed at here. My main concern is R# 4.1 integration.
Download it now at here.

Tuesday, July 22, 2008

Working with Active Directory Dates

Recently, my friend and colleague asked me about how to limit an ldap search to only return objects that were created after a certain date. 'whenCreated' should be a logical choice to solve that. However, this attribute has an interesting format, see this reference. So, i marked up a few functions to help us work with the date naturally within Powershell.
function ConvertToAdDate([DateTime]$date) {
"{0:0000}{1:00}{2:00}{3:00}{4:00}{5:00}.0Z" -f $date.year,$date.month, `
$date.day, $date.Hour, $date.Minute, $date.Second
}
function ConvertFromAdDate([String] $date) {
$pattern = `
'^(?<year>\d{4})(?<month>\d{2})(?<day>\d{2})(?<hrs>\d{2})`
(?<min>\d{2})(?<sec>\d{2})\.0Z$
'
$match = [regex]::Match($date,$pattern)
if ($match.success) {
$result = New-Object System.DateTime($match.groups["year"].value,`
$match.groups["month"].value,$match.groups["day"].value,`
$match.groups["hrs"].value,$match.groups["min"].value, `
$match.groups["sec"].value,[DateTimeKind]::Utc)
$result.ToLocalTime()
}
else {
$null
}
}

Friday, July 11, 2008

Purging Mailboxes In Exchange 2003

I have recently demonstrated how to Purge a mailbox in Exchange 2007 but did not show anything for Exchange 2003. Here is what I do to purge mailboxes on Exchange 2003 server.

$list = gwmi -ComputerName "ex2k3srv" -Class Exchange_Mailbox -Namespace Root\MicrosoftExchangeV2 | ?{ $_.DateDiscoveredAbsentInDS -ne $null }
$list | %{ $_.Purge() }

For IT admins and Sales guys!!!

It's been all over the web. Still, I need to post this link b/c I'll be coming back to it for entertainment for awhile.

http://www.thewebsiteisdown.com/salesguy.html