Get-MailboxFolder is not working & Exchange Web Services…getting started

Triggered by a comment/question  from Robbie De Sutter, on one of my previous blog posts (Exchange 2010: And then there is the long awaited cmdlet Add-MailboxFolderPermission), being:

First of all I'm running an international business, hence my users do not have a "Calendar" folder, but an "Agenda" (Dutch) or "Kalendar" (German) or ... How to deal with that (without me tracking which language every user is using)?

it got me thinking if there was an easy way, out of the box, to get a list like “user x has a Kalendar”, “user y has a Calendar”, and “user z is happy with his Calendrier”"…

Option 1. Use the cmdlet Get-MailboxFolder

Exchange 2010 provides you with a cmdlet named “Get-MailboxFolder”, which is described on TechNet as one that will “retrieve folders for a specified mailbox when the mailbox owner runs the command”, so let’s see. Logged in as Administrator on my demo machine, I can run the cmdlet, and get an overview of all mailbox folders for my own account…

ilvancri-0077   

but when trying to run the cmdlet against another user’s mailbox, the following error pops up:

The specified mailbox “ilvancri” doesn’t exist” , whereas the mailbox definitely exists, as can be seen by running the cmdlet Get-Mailbox ilvancri:

ilvancri-0078

Looking back at the TechNet article, it did state “when the mailbox owner runs the command”, thinking about RBAC, it’s time to see who is allowed to run the cmdlet Get-MailboxFolder, by running the following “Get-ManagementRole –Cmdlet “get-mailboxfolder”

ilvancri-0079

The return shows that the role “MyBaseOptions”, scoped to Self, is the only one that is allowed to run the cmdlet Get-MailboxFolder.

ilvancri-0080

Now, one might thing….easy….let’s create a new role, pick MyBaseOptions as the parent role, and change the ImplicitRecipientReadScope to OrganizationConfig…but that won’t work…as seen here on TechNet (Understanding Management Role Scopes) which clearly states:

“You can't change the implicit scopes defined on management roles. You can, however, override the implicit write scope and configuration scope on a management role. When a predefined relative scope or custom scope is used on a role assignment, the implicit write scope or configuration scope of the role is overridden, and the new scope takes precedence. The implicit read scope of a role can't be overridden and always applies. For more information about predefined or custom explicit scopes, see the related sections later in this topic.”

Using Bing, I came across this TechNet forum article: Get-MailboxFolder cmdlet is not working, which describes what I had seen, but it did include a solution, submitted by Exchange MVP Amit Tank, “to use in that case programmatic way with EWS would be easier way to query folders for other users...”, followed by a reply from the original poster being “Thanks Amit, I did it using EWS, specifically I used FindFolderType for this.”

Time to use EWS…

Option 2. Use EWS and FindFolderType

Searching the internet, it was easy to find a ton of scripts, using FindFolderType, but since I’m not a developer, it wasn’t easy to get started (copy-paste of script in Notepad didn’t do it ;-)), so therefore I want to show you how easy it is to get started with EWS and show you a very easy script that will retrieve folders and show them in a simple msgbox :-)

Step 1. Install Visual Studio

I decided to install Visual Studio 2010 Premium on a Windows 2008 R2 standalone server, so not a member my Exchange demo environment.

Step 2. Download and Install the Exchange Managed API

“The Microsoft Exchange Web Services (EWS) Managed API 1.0 provides a managed interface for developing client applications that use Exchange Web Services. The EWS Managed API simplifies the implementation of applications that communicate with Microsoft Exchange Server 2007 Service Pack 1 (SP1) and later versions of Microsoft Exchange. Built on the Exchange Web Services SOAP protocol and Autodiscover, the EWS Managed API provides a .NET interface to EWS that is easy to learn, use, and maintain.”

I downloaded and installed version 1.0, but there is also a version 1.1 in beta now:

 

Pic0422

Step 3. Launch Visual Studio

I decided to create a new Windows Form Application

 ilvancri-0081

 ilvancri-0082

In the Solution Explorer, I expand my project, called Hello World, and right-click References

  Pic0436

There is select to Add a reference

Pic0437

And I browse to the location of the Microsoft.Exchange.WebServices.dll which has been installed by deploying the EWS Managed API!

 Pic0438

After clicking OK I can see that I have a reference to Microsoft.Exchange.WebServices.

 Pic0439

Using the toolbox, it’s easy to create a new button, and enter some code, as said, VERY SIMPLE code, I’m a newbie :-)

The code below will send an email to ilvancri..

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Exchange.WebServices.Data;
using System.Net;

namespace Hello_World
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

        private void button1_Click(object sender, EventArgs e)
{
ExchangeService service = new ExchangeService();
service.Credentials = new NetworkCredential("user", "<password>",”<domain>");
service.Url = new Uri("
https://mail.cs14.local/EWS/Exchange.asmx");
            EmailMessage message = new EmailMessage(service);
message.Subject = "Hello from the EWS Managed API";
message.Body = "Now that's easy!";
message.ToRecipients.Add("ilvancri@cs14.local");
message.SendAndSaveCopy();
}

  }

  }

And this one will show the mailbox folder names for a user called user5

private void button2_Click(object sender, EventArgs e)
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
service.Credentials = new NetworkCredential("user", "<password>",”<domain>");
service.Url = new Uri("
https://mail.cs14.local/EWS/Exchange.asmx");
    service.AutodiscoverUrl("user5@cs14.local");
FolderView view = new FolderView(30, 1, OffsetBasePoint.Beginning);
view.PropertySet = new PropertySet(BasePropertySet.IdOnly);
view.PropertySet.Add(FolderSchema.DisplayName);
view.PropertySet.Add(FolderSchema.ChildFolderCount);
view.Traversal = FolderTraversal.Shallow;
FindFoldersResults findfolderresults = service.FindFolders(WellKnownFolderName.MsgFolderRoot, view);
foreach (Folder myfolder in findfolderresults.Folders)
{
MessageBox.Show("Folder: " + myfolder.DisplayName);
}

}

To find out more about Exchange Web Services, and dive into some examples, I strongly encourage you to have a look at the following links:

Once I do have a script that creates the desired output of user x has calendar, user z has a calendrier, I’ll let you know….

Ilse