Friday, March 18, 2005

C# WMI Exchange samples

Somebody asked this morning about using WMI and Exchange in c#. There's a lot of good information on the Web about using the System.Management namespace to access WMI but not many Exchange specific C# samples at the moment. I decided to convert a few of the examples I've used in the scripts in my blog.

The first is a simple mailbox size example

System.Management.ConnectionOptions objconn = new System.Management.ConnectionOptions();
objconn.Impersonation = System.Management.ImpersonationLevel.Impersonate;
objconn.EnablePrivileges = true;
string cServername = "servername";
System.Management.ManagementScope exmangescope = new System.Management.ManagementScope(@"\\" + cServername + @"\root\MicrosoftExchangeV2",objconn);
System.Management.ObjectQuery objquery = new System.Management.ObjectQuery("SELECT * FROM Exchange_Mailbox");
System.Management.ManagementObjectSearcher objsearch = new System.Management.ManagementObjectSearcher(exmangescope,objquery);
System.Management.ManagementObjectCollection queryCollection1 = objsearch.Get();
string strDisplay;
foreach( System.Management.ManagementObject instmailbox in queryCollection1 )
{
strDisplay = instmailbox["MailboxDisplayName"].ToString() + " " + instmailbox["size"].ToString();
System.Console.WriteLine(strDisplay);
}

The second is the Mail-Enabling a Public Folder via WMI (Exchange 2003) from this post

System.Management.ConnectionOptions objconn = new System.Management.ConnectionOptions();
objconn.Impersonation = System.Management.ImpersonationLevel.Impersonate;
objconn.EnablePrivileges = true;
string cServername = "servername";
string cPublicFolderPath = "/foldertoenable/";
System.Management.ManagementScope exmangescope = new System.Management.ManagementScope(@"\\" + cServername + @"\root\MicrosoftExchangeV2",objconn);
System.Management.ObjectQuery objquery = new System.Management.ObjectQuery("Select * From Exchange_PublicFolder Where Path='" + cPublicFolderPath + "'");
System.Management.ManagementObjectSearcher objsearch = new System.Management.ManagementObjectSearcher(exmangescope,objquery);
System.Management.ManagementObjectCollection queryCollection1 = objsearch.Get();
foreach( System.Management.ManagementObject instmailbox in queryCollection1 )
{
System.Console.WriteLine(instmailbox["path"].ToString());
System.Console.WriteLine(instmailbox["IsMailEnabled"].ToString());
instmailbox["IsMailEnabled"] = true;
instmailbox.Put();
}


I've posted a txt file version of this up here

18 comments:

Verakso said...

Hi.
I just found your blog, and especially this post about c# WMI and Exchange.

I have for some time now, tried to get at script working that enumerates the mailboxes and their size on an Exchange 2000 Standard, by using CDO.

The problem is that Exch2K doesn't support WMI, and the CDO script has a bug with VBScript and data type long.
The VBLong is approx 2,147,483,647, so all mailboxes bigger than this, gives a wrong number.

You blog gave me inspiration to do this task using C# and the System.Management class. However now I am facing the problem with rights, so I was wondering if you could give some tip, about the class, and how to manage access rights.

Glen said...

System.Mangement is still using WMI so you still need to use this against a Exchange 2003 box.
I blogged something recently about the Exchange namespace security especially if you using this remotely http://gsexdev.blogspot.com/2005/04/querying-microsoftexchangev2-namespace.html . If this doesn't answer you question let me know the specifics around what you issue is. For Exchange 2000 I use a Exoldb script the calculate the size of each folder i haven't had the long problem with VBS but I don’t have anyone with a folder over 2 GB (have some mailbox over 3 GB). You could however do the same thing using Exoledb with C# and it should work okay. The ADO samples are listed in http://support.microsoft.com/?id=320071

Dan (brndofan7@gmail.com) said...

Glen,

Just came across this today and it was a lifesaver. I'm using this in conjunction with an app that pulls AD info for everyone in our domain. Essentially the app pull all AD info and if the "Get Exchange Info" checkbox is checked it gets the exchange info we want (size,lastlogontime,totalitems).

My issue is that when I add in the Exchange piece, the time to run the query increases greatly. If I run this for everyone with only AD info, the results will be returned in about 1 minutes, but running this grabbing the Exchange into took over 2 hours. I've been searching for ways to speed things up, but so far with no luck. Any thoughts?

Thanks,
Dan

Glen said...

If you making a seperate WMI query for every user then this will be slow (I've had the same problems). What i usually try to do when im doing something simular is to do only one query of each of the exchange servers the retrives all the data and then build a dataset of the results and then use a data relation to related the data. I've done something simular but in ADO with script using relating the WMI logon class and ADSI data eg http://gsexdev.blogspot.com/2005/06/displaying-logon-status-using-data.html

Daniel said...

Glen, thanks for this, it's been a real life saver. Just curious, is there any way via WMI to list folder names associated with a mailbox or user?

Thanks

Anonymous said...

Hi Glen,

I am using WMI + C# to query Exchange 2003.
it work fine for the query
"select * from Exchange_Mailbox"

How when I use query
"select * from Exchange_Mailbox"
it gives me error as followings

-----------------------------
System.Management.ManagementException: Provider is not capable of the attempted operation at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode) at System.Management.ManagementObjectEnumerator.MoveNext()
-----------------------------

I just wonder why?

In addition, I would like to ask if you have experience using "Microsoft Exchange Hosting"

It happens that, after I created some email mailbox in "Microsoft Exchange Hosting", I try to use WMI to query Exchange Server, it returns "empty" ManagementObjectCollection

Do u know why? (bitter laugh)

Glen said...

>I am using WMI + C# to query >Exchange 2003.
>it work fine for the query
>"select * from Exchange_Mailbox"
>
>How when I use query
>"select * from Exchange_Mailbox"
>it gives me error as followings

So which query are you having problems with you seem to have repeating what you wrote. That error looks like it might be maybe you hitting a limitation with the provider. Try filter you query.

I dont really have any experience with hosted exchange. But you need to remember just becuase you create a mailboxe doesn't means its been actually provisioned in the Exchange Database hence the WMI class is not going to show anything. Exchange doesn't create the mail folders until after the first logon or the first time a message is sent to a the mailbox.

Anonymous said...

I was looking for something like this for some time now. Now, I am have Access exceptions thrown at me. What kind of permissions do I need to demand to be able to run this code.

- Hector

Anonymous said...

Great info, but I have to wonder why everyone on here is speaking/typing in broken English?

I started reading the first few posts thinking it was just typos, but every post has missing or incorrect words.

Lets see if mine ends up that way and maybe it is a broken server lol. : )

Glen said...

Well not every bodies first language is English, unfortunately mine is its usually because I'm in to much of hurry to check what i type properly

Glen said...

The premissions you need to use the Exchange WMI class is you need to have at least delegated Exchange Admin rights. You might also want to read http://gsexdev.blogspot.com/2005/04/querying-microsoftexchangev2-namespace.html

Cheers
Glen

Pradeep said...

Hi i m gonna use wmi.. a lot i guess.. i wanted to know whether to rely on scripts? or write my app... its like lots of clients.. in a lan.. n a server... THe app will be on server... Colllecting info abt client PC health ..scheduled task etc...
prr713@gmail.com
Please let me know....
Anymore more info will be welcome

Deep said...

one more thing i need get scheduled tasks and create folders in remote PC.. the create method has parameters which seems confusing... do u have any good links? or probably some clean code?
prr713@gmail.com

Lucas said...

Hello,

Is there any way to move exchange mailbox with WMI in C#?

Thanks for help!

Glen said...

No you need to use CDOEXM in 2003 or the Exchange Management Shell in 2007

Cheers
Glen

ZippyZaki said...

Hi Glen,

This is indeed a life saver! By any chance, do you have an example for reading emails from an exchange inbox? That's help me out a lot.

Thanks very much,
Zaki.

Glen said...

You cant use WMI to read mail from a mailbox you need to use something like WebDAV to do this on 2003 or EWS on 2007

Cheers
Glen

Anonymous said...

Thanks for the article and sharing...
I would like to know how to retrieve the safe-senders list from exchange 2003/2007/2010 using C#.

Thanks.