Archive for the ‘Exchange’ Category

Mail apps for Outlook makes developing Outlook customizations simple and straightforward. A mail app is just a webpage that is hosted inside Outlook. Outlook activates it and makes it available to the user contextually with respect to the item that the user is currently viewing. The user controls starting any available mail app and the app can run seamlessly across the Outlook rich clients, Outlook Web App and OWA for Devices, such that you need to install a mail app only once for a mailbox and it will work on the devices and on the Outlook clients that it is designed for.
When a user starts the app, Outlook provides a context object that contains information about the current item and also enables access to the Exchange Web Services (EWS) of the current mailbox (using the mailbox’s “makeEwsRequestAsync” method).
I have been asked to provide, inside Outlook, some statistical information about the current email’s sender like the number of messages, number of unread messages etc. After considering the available options, I have found that implementing such a requirement with a mail app is the easiest method.  The main disadvantage relative to a classic Outlook Add-in is that the app can work only on Exchange Online or Exchange Server 2013 or a later version, but this was not an issue in my environment.
In my app (source available at the bottom) I used the EWS services to query the sender information. The “makeEwsRequestAsync” method expects a string parameter with a valid SOAP request message, but creating this SOAP message manually can be burdensome. I have found it easier to create a .NET console application that will query the relevant information using EWS proxy and then used an application like Fiddler to capture the generated SOAP message.  The rest of the application is very straightforward, just html with light JavaScript to bind the information to the page.
After starting the app it will looks something like this:
Sender Info App
In the Configuration.js file, you can configure the “More info about …” link to navigate to a report about the current sender. For example, in my environment, I used it to open a webpage with information from our CRM about the specific contact, if exists. The configuration file also allows modifications to any of the displayed labels.
The “Sender Info” app deployment process includes two main steps:

  1. Deploy the web site: Copy the content of the Website folder to any Web server that can serve content over HTTPS and is accessible to your users. Optionally, update the file Configurations.js (under the “AppRead” folder) to set a specific “More info about …” link.
  2. Deploy the app manifest file:
    1. Edit the SenderInfoOutlookApp.xml file, find each occurrence of “~remoteAppUrl” and replace it with the URL of the web site from the previous step.
    2. Using the Exchange Admin Center (EAC), install the updated manifest file as described here.

Download the app and the source

Read Full Post »

You can probably find several blog posts out there about remotely executing simple commands and scripts against Exchange servers, but trying to implement these examples on a “real” functional script, can introduce some annoying problems that nobody seems to mention. This was the case when I tried to develop a web page that was supposed to assist with managing a multi-tenant exchange 2010 SP2 environment. I got some startup scripts from Jacob Dixon’s blog and after some minor modifications I was able to execute them locally on the Exchange server without any problems, it was only when I tried to call these scripts from my web page that problems started:

  • Problem 1: Following a TechNet library post (http://technet.microsoft.com/en-us/library/dd335083), I tried, firstly, to open a remote PowerShell session from a C# application, to the Microsoft.Exchange configuration on a CAS server. I connected successfully but found that the execution context was very limited and restricted as it didn’t even allow assigning PowerShell variables (got an “Assignment statements are not allowed in restricted language mode or a Data section” exception), meaning you almost can’t do any scripting with it.
  • Problem 2: So I tried connecting to the default PowerShell  WSMAN (http://{ServerName}:5985/wsman) and executing the script, only to find that though I have full permissions, when trying to execute an exchange’s command, it asked to provide the server argument as it didn’t recognize it executing on an exchange server.  I didn’t want to change my scripts, so I didn’t continue with this approach.
  • Problem 3: So I tried to open a local PowerShell session and from this session I used the Import-Session commandlet to connect to the remote Microsfot.Exhange configuration.  I connected successfully and had full permissions with the right execution context. However,  while re-trying to execute the script I found that the commandlet New-Mailbox doesn’t exist.
    Quick solution:  Executed the “Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010” command and magically the command is available.
  • Problem 4:  Trying again to execute the script, I got a new error: “New-Mailbox : Load balancing failed to find a valid mailbox database.”. Ok – so I tried to specify the database explicitly with the –Database argument and got this error: “New-Mailbox : Couldn’t find database “{DB Name}”. Make sure you have typed it correctly. ”. I googled it and found some forums that suggested to make sure the database exists and is mounted, of course my mailbox database did exist and was mounted as the script worked from the local exchange server. So I tried a different approach;  opened a remote PowerShell session to the default PowerShell WSMAN and from that remote session I imported a new session to the Microsoft.Exchange configuration. This approach eliminated the error message and the mailbox was successfully created.
  • Problem 5:The PowerShell script also included some Active Directory commands, for creating a new AD account with the mailbox, which required loading the activedirectory module. When I tried to import the module I got this warning:
    • Error initializing default drive: ‘Unable to contact the server. This may be because this server does not exist, it is currently down, or it does not have the Active Directory Web Services running.‘.

    Not really a helpful message but googling it I understood that I got into a double hop problem, as the AD is installed on a different machine. So I decided to open the first remote session with the CredSSP authentication method (which enables double hops). This wasn’t a trivial task but luckily, Drew has an excellent blog post about this topic (http://werepoint.blogspot.ca/2012/03/setting-up-ps-remoting-for-all-that.html) that helped me to enable it.

  • Problem 6: After successfully creating a remote PowerShell session with the CredSSP authentication, I tried again to import the activedirectory module and got “Out of Memory” Exception.  To solve this one, I executed this command on the remote server:
winrm set winrm/config/winrs @{MaxMemoryPerShellMB="1024"}
  • Problem 7: Now my script was executing successfully but with all the parameters still hardcoded on the script, when I tried to make it more generic and pass the remote script parameter values from the C# application I found that I could not use the following code:
    powershell.Runspace.SessionStateProxy.SetVariable("{Param name}", "{Param value}");

    As the SessionStateProxy object doesn’t initialize with a remote PowerShell sessions. To overcome this, I changed my code to iterate the parameters and for each, add a “Set-Variable” Command with the relevant values like

foreach (var parameter in parameters)
   Command command = new Command("Set-Variable");
   command.Parameters.Add("Name", parameter.Key);
   command.Parameters.Add("Value", parameter.Value);


So, after a challenging day I ended up with a basic but complete demo for remotely running a script on Exchange 2010 SP2 server that creates a new Tenant’s mailbox. Hopefully this post will save you some time implementing similar tasks. I attached here the code for this demo web page.

Read Full Post »