PowerShell Automation from .Net

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.

Exchange PowerShell Automation Test

Exchange PowerShell Automation Test


Note: a bugfix was uploaded on 5th January 2015 to fix an issue with the parameter parsing (it would leave a trailing space for the parameter value).

Download ExchangePSAutomationTest

Comments (2)
  1. snickered says:

    Severity Code Description Project File Line Suppression State
    Error CS0103 The name ‘Trim’ does not exist in the current context ExchangePSAutomationTest C:\Code\ExchangePSAutomationTest\ExchangePSAutomationTest\Form1.cs 333 Active

  2. Jo says:

    Hello David,

    I really need to send complex script to handle mailboxes of my Exchange Online Environment, how is it possible with that Nolanguage config. I used to switch it to FullLanguage on Exchange 2013.

    How can I for example send this:

    $cred = new-object system.management.automation.PSCredential $username,$pwd;

    New-Mailbox -DisplayName $fullname -name $ipn -Alias $ipn -OrganizationalUnit $OUComptes -UserPrincipalName $mail -SamAccountName $ipn -FirstName $firstname -LastName $lastname -DataBase $target -LinkedMasterAccount “domain.net\my_id” -LinkedDomainController $ldc -LinkedCredential $cred -DomainController $dc;
    if ($Error[0] -eq $null)
    Set-Mailbox $ipn -EmailAddressPolicyEnabled $false -EmailAddresses “SMTP:$mail” -ForwardingAddress $null
    -RetentionPolicy $policy -RoleAssignmentPolicy $rolePolicy -SingleItemRecoveryEnabled $true -CustomAttribute10 ‘mailbox’
    -DomainController $dc;

Comments are closed.

Skip to main content