Even though this blog has numerous PowerShell scripts showing mainly how to use EWS from PowerShell, scripting isn't actually something my team supports (Exchange scripting support is provided by the Exchange team).  What we do support, though, is automation of PowerShell from .Net.

We've had a couple of cases on this recently, and it seems that it is still common to use the incorrect way to connect to the Exchange remote runspace.  Since Exchange 2010, we have not supported loading the Exchange snap-in into either the PowerShell console, or in .Net (it was supported in Exchange 2007).  We even have a KB explaining this. Unfortunately the internet seems to have a number of examples showing the wrong way of connecting.

I have written a sample application that demonstrates two supported techniques for connecting to Exchange management, and it works against Exchange 2010, Exchange 2013, and Exchange Online.  The application (and source) is attached to this blog, and was written in Visual Studio 2013 against .Net 4.5.  The same technique should be used for previous .Net versions also.

When testing against Exchange 2013, I found that even in a domain environment the username must be specified in the domain\username format.  If the domain is missing, you'll probably encounter an Access Denied.

If you connect to Exchange Online using a remote runspace (this is where the code connects directly to the remote runspace, and so the commands are processed there) then attempting to process a script will result in an error: The syntax is not supported by this runspace. This might be because it is in no-language mode.  This is because Exchange Online is configured to only allow you to run commands (as per MSDN: http://technet.microsoft.com/en-us/library/dn433292.aspx ).  The sample application can process a script as commands (tick the Process each line as separate command option), and so long as there are no language elements in the script (i.e. it is just a sequence of commands) then you should receive the expected output.  If you need to process a script that includes language elements, then the only option you have is to use a local PowerShell session and import the remote runspace into it.  The screenshot below shows a successful Get-Mailbox against Exchange Online.