Search This Blog

Sunday, January 13, 2013

Exchange 2007 Admin in C# on W2008R2 using Visual Studio 2010

I wrote a service which performed Exchange 2007 administration tasks which performed successfully for years running on a Windows 2003 R2 server.  Recently we went through an upgrade to W2008R2 and Exchange 2010 and I began upgrading the service to use the new and very different PowerShell snap-in for Exchange 2010.

Suddenly we partially reversed course, however, and decided to stay with Exchange 2007 while continuing the upgrade to W2008R2 for the server OS.

So I am having to rewrite my original windows service code to run on 64-bit W2008R2 machines.  I remembered that when I initially wrote the service I had several issues getting Visual Studio (then VS2005, now VS2010), the PowerShell runspace, the Exchange 2007 Administration PSSnapin, and the bit-iness of the machine to agree and to let me do what I needed to do.  I remembered that these problems took days to resolve.

I would run into persistent problems getting my C# code to recognize the snap-in, to use the correct version of the System.Management.Automation tools, etc. which would be evidenced with errors like:

"No snap-ins have been registered for Windows PowerShell version 2"

"Could not load file or assembly 'Microsoft.Exchange.PowerShell.Configuration, Version=14.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified."

"MSCorlib.dll is compiled for wrong processor"

Googling around it is clear that this is a common problem and is a bit-iness issue between all the different entities and all of them must be lined up in the right way to make things work.

I established a set of steps that worked for me in a virgin test environment on a virtual machine; I then took it into my production environment (which had suffered installs and uninstalls of the Exchange 2007 and 2010 management tools) and tried it again and it worked.

The steps I followed to get it to work were:

01) Install the Exchange 2007 management tools from the Exchange 2007 SP1 distribution DVD onto the server
02) Update the management tools to service pack 3 (by downloading the Exchange 2007 SP3 download from Microsoft)
03) Start Visual Studio 2010 and create a console application. 
04) Create a class in the console app to hold the Exchange 2007 Admin PowerShell wrapper written by Nick Smith (at http://knicksmith.blogspot.com/2007/03/managing-exchange-2007-recipients-with.html)
05) Have the main() method of the program.cs file call Nick Smith's exchange wrapper, e.g.:

  static void main(string[] args)
  {

    // Do a simple dump of mailbox names
    ExchangeManagementShellWrapper ems = ExchangeManagementShellWrapper.Instance;
        ICollection results;
        results = ems.Runsp
aceInvoke("Get-Mailbox");
        foreach (PSObject item in results)
        {
              Console.WriteLine(item.Members["Name"].Value.ToString());
        } 
  }


06)  Make sure the project's set to build using .NET framework 3.5.
07)  Make sure the project's set to build to the x64 platform
08)  Make sure there's a reference to "C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Management.dll"
09)  Make sure there's a reference to "C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll"

That should do it.  The Exchange 2007 PowerShell cmdlets are only installed as x64 and the System Automation dlls only seemed to work for me if the code is targeted towards .NET 3.5, not .NET 4.0 (which my VS editor defaulted to).

I'll include the source code for the project if there's any interest in that.

No comments: