EWS API 2.1 Released

Download:

http://www.microsoft.com/en-us/download/details.aspx?id=42022

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

For your convenience, the package also includes the Exchange Server 2013 token validation library. You can use the EWS Managed API and the library to build mail apps for Outlook that can be authenticated by the identity tokens issued by Exchange 2013. 

EWS API 1.2 Released

Good news, the Exchange Web Services Managed API 1.2.1 was released and it’s available for download

The EWS Managed API 1.2 introduces the following important changes that might affect your client applications:

Microsoft Exchange Server 2010 Service Pack 2 (SP2) is now the targeted version

  1. The following new functionality is exposed:
  2. Getting password expiration date
  3. Updates to the contact type
  4. Store entry identifiers returned on items
  5. Asynchronous notifications
  6. DateTime object precision values
Documentation

http://msdn.microsoft.com/en-us/library/dd633709(v=exchg.80).aspx

Download

http://www.microsoft.com/en-us/download/details.aspx?id=28952

Run Exchange Online PowerShell Commands with C#

Instead of running PowerShell Commands within the Console, in some scenarios, it’s important to automate this procedure and give users the ability to manage Exchange Online. In this sample I’m creating a mailbox. I’m explaining all steps in code.

I Suggest to Run this sample first in a Console Application

image

Leave a message if you have any issues

using System.Collections.Generic;
using System.Management.Automation.Runspaces;
using System.Management.Automation;

// Set credentials to make a remote connection to Outlook Live
string userName = admin@contoso.com;

string password = "password";

SecureString secureString = new SecureString();
foreach (char c in password) secureString.AppendChar(c);
secureString.MakeReadOnly();

PSCredential credential = new PSCredential(userName, secureString);

// Set the connection Info
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(new

   
Uri("https://ps.outlook.com/powershell/"),
        "http://schemas.microsoft.com/powershell/Microsoft.Exchange"
, credential) 

     { AuthenticationMechanism = AuthenticationMechanism.Basic };

// create a runspace on a remote path
// the returned instance must be of type RemoteRunspace

Runspace runspace = RunspaceFactory.CreateRunspace();
PowerShell powershell = PowerShell.Create();
PSCommand command = new PSCommand();
command.AddCommand("New-PSSession");
command.AddParameter("ConfigurationName", "Microsoft.Exchange");
command.AddParameter("ConnectionUri", new Uri("https://ps.outlook.com/powershell/"));
command.AddParameter("Credential", credential);
command.AddParameter("Authentication", "Basic");

//-AllowRedirection
powershell.Commands = command;

// open the remote runspace
runspace.Open();

// associate the runspace with powershell
powershell.Runspace = runspace;

// invoke the powershell to obtain the results
Collection<PSSession> result = powershell.Invoke<PSSession>();

foreach (ErrorRecord current in powershell.Streams.Error)
   
Console.WriteLine(String.Format("The following Error happen when opening the remote Runspace: {0} | InnerException: {1}", 

     current.Exception, current.Exception.InnerException));
Console.ReadLine();
if (result.Count != 1)
   
throw new Exception("Unexpected number of Remote Runspace connections returned.");
// Set the runspace as a local variable on the runspace
powershell = PowerShell.Create();

command = new PSCommand();
command.AddCommand("Set-Variable");
command.AddParameter("Name", "ra");
command.AddParameter("Value", result[0]);
powershell.Commands = command;
powershell.Runspace = runspace;
powershell.Invoke();

powershell = PowerShell.Create();
command = new PSCommand();
const string CreateMailBoxScript = "new-mailbox -Name:'{0}’ -Password:(ConvertTo-SecureString {1}  -AsPlainText -Force) -WindowsLiveID:{2} -FirstName:{3} -LastName:{4} -DisplayName:'{5}’";
command.AddScript(string.Format(CreateMailBoxScript, "Joao", "password", jlivio@contoso.com, "Joao", "Livio", "Joao Livio"));
powershell.Commands = command;
powershell.Runspace = runspace;
powershell.Invoke();

// dispose the runspace and enable garbage collection
runspace.Dispose();

runspace = null;
// Finally dispose the powershell and set all variables to null to free
// up any resources.
powershell.Dispose();

powershell = null;

How to get Exchange Online Folders

You can get all folders based in a criteria, this is useful because it can be queried by a SearchFilter. In this case I’m only get Folders that have at least 1 message because operator is SearchFilter.IsGreaterThan

 

SearchFilter searchFilter = new SearchFilter.IsGreaterThan
(FolderSchema.TotalCount, 0);
 
Unlike messages, in folders, you can use Deep Transversal’s, this means that you can get all Sub Folders on the fly.
 
 

view.Traversal = FolderTraversal.Deep;

 

As always you have to use an Object type of ExchangeService(), see the GetBinding() Method

 

Main Procedure

 

// Create a view with a page size of 10 or number you want.
FolderView view = new FolderView(10)

{
   
PropertySet = new PropertySet
     (BasePropertySet.IdOnly) { FolderSchema.DisplayName }
};

// Identify the properties to return in the results set.
// Return only folders that contain items.
SearchFilter searchFilter = new SearchFilter.IsGreaterThan

  (FolderSchema.TotalCount, 0);

// Unlike FindItem searches, folder searches can be deep traversals.
view.Traversal = FolderTraversal.Deep;

// Send the request to search the mailbox and get the results.
FindFoldersResults findFolderResults = service.FindFolders

  (WellKnownFolderName.Root, searchFilter, view);

// Process each item.
foreach (Folder myFolder in findFolderResults.Folders)

{
    // Go get myFolder.Id, MyFolder.DisplayName etc…
}

// Determine whether there are more folders to return.
if (findFolderResults.MoreAvailable)

{
   
// Make recursive calls with offsets set for the FolderView

    // to get the remaining folders in the result set for Paging.
}

EWS User Impersonation, advantages, why?

 

First off all I respect all points of views, this post is intend only to expose my opinion.

ACTIVATE IMPERSONATION FOR ADMINISTRATOR

First go to Roles & Management and then Discovery Management, Second, add a function ApplicationImpersonation, then add the Administrator User Name

image image

IMPERSONATION IN DETAIL

When you connect to exchange online, you must communicate with an Exchange Web Service within a mailbox user and a password, but if you are logged with a non Administrator user you may not have Full control over the Service. This may be true when you have Hybrid Systems, and in some procedures like CreateReply() or CreateForward() you may experience Access Denied Exceptions.

Another point is if you use the Administrator Credentials and Impersonate another Mailbox you don’t have to know that users credentials and this may be an advantage in all ways.

How can we do this?

Just use your service binding method, or get it here and impersonate the service like this

service.ImpersonatedUserId = new ImpersonatedUserId
   (ConnectingIdType.SmtpAddress, 
      "You non Admin MailBox");

What is the Service Binding in the Exchange Web Services Managed API

The Microsoft Exchange Web Services Managed API have 2 main classes, the FOLDER Class and the ITEM Class. All these 2 need a ServiceObject in order to communicate with a Exchange Web service.

Service Binding use the Autodiscover Object in order to get a Exchange Web Service endpoint URL, something like this https://SERVER.outlook.com/EWS/Exchange.asmx.

The Folder Class

image

The Item Class

image

You can see at the TOP of the hierarchy SERVICEOBJECT that is a type of ExchangeService() Object

So what next? let’s see in more detail, what Outlook do if you add a Microsoft Exchange Account?

image

In this case Outlook will try to resolve thru Autodiscover the domain in the E-mail Address field, and get the Endpoint for the Exchange Web Service, if the credentials are OK, all user configurations and Mail will be attached to Outlook

Service Binding do the same thing, the only difference is that you will assign properties values to a ExchangeService(), and assign user information’s like the Endpoint URL in order to you can use All Objects in the FOLDER and ITEM Class

Let’s see the Method here

Enjoy EWS!

Delete a Message or a List of Messages

You will need the GetBind() method in order to use this code

This method will delete a message based in a Message Unique ID and move it to deleted folders, you can change it for your needs

/// <summary>
/// Deletes the message.
/// </summary>
/// <param name="messId">The mess id.</param>
public static bool DeleteMessageByID(string messId)

{
   
Item mess = Item.Bind(GetBinding(), messId);
   
EmailMessage message = mess as EmailMessage;
   
if (message == null) return false;
   
message.Delete(DeleteMode.MoveToDeletedItems);
   
return true;
}
 

This method will delete a List of messages based in a Message Unique ID that you pass in the List<String> and move it to deleted folders, you can change it for your needs

/// <summary>
/// Deletes the message list.
/// </summary>
/// <param name="messId">The mess id.</param>
public static bool DeleteListOfMessagesByID<string> messId)

{
   
foreach (EmailMessage message in
       
messId.Select(messIdList => Item.Bind(GetBinding(), 
           
messIdList)).Select(mess => mess as EmailMessage))

   
{
       
if (message == null) return false;
       
message.Delete(DeleteMode.MoveToDeletedItems);
   
}
   
return true;
}

 

I you think this helped you, please take 10 second’s and respond to the question in the side bar, Thanks.