1

I'm working on a solution where users can wipe mobile devices registered with Exchange 2010, through a webpage, using Outlook Web Access is not an option. I've installed Exchange Management Tools on my dev machine and the app pool is using an identity that has the necessary rights to perform the commands (assigned role group "Recipient Management"). I'm using the following code to perform the wipes

string deviceId = "deviceid";
    string username = "username";

    RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();
    PSSnapInException snapInException = null;
    PSSnapInInfo info = rsConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out snapInException);
    if(snapInException != null)
        throw snapInException;
    using(var runspace = RunspaceFactory.CreateRunspace(new MyPowershellHost(), rsConfig))
    {
        runspace.Open();

        using(var pipeline = runspace.CreatePipeline())
        {
            pipeline.Commands.AddScript(@". ""C:\Program files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1""");
            pipeline.Commands.AddScript("Connect-ExchangeServer -auto");
            pipeline.Invoke();
        }

        ActiveSyncDeviceConfiguration actualDevice;

        using(var pipeline = runspace.CreatePipeline())
        {
            pipeline.Commands.AddScript(string.Format("Get-ActiveSyncDeviceStatistics -Mailbox {0}", username));
            var result = pipeline.Invoke();
            actualDevice = result.Select(x => x.BaseObject as ActiveSyncDeviceConfiguration).Where(x => x.DeviceID.EndsWith(deviceId)).SingleOrDefault();
        }

        if(actualDevice != null)
        {
            var identity = actualDevice.Identity as ADObjectId;
            using(var pipeline = runspace.CreatePipeline())
            {
                var cmd = new Command("Clear-ActiveSyncDevice");
                cmd.Parameters.Add("Identity", identity.DistinguishedName);
                pipeline.Commands.Add(cmd);
                pipeline.Invoke();
            }
        }
    }

I can get this working when the user account is added as a local administrator on the machine and also is logged onto windows. I can accept if the user has to be local administrator but having the user constantly logged in is not practical for a server application. The MyPowershellHost class is just a basic host implementation to allow the RemoteExchange.ps1 script to run since it's interacting with the UI.

I can't figure out if the user need extra privilegies or I'm just doing it wrong.

Xorandor
  • 462
  • 3
  • 14

1 Answers1

1

One of the key issues you'll be having is the way that you're connecting to Exchange. You don't need to load the management tools script like the console does, you just use the PowerShell remoting. You don't even need the management tools installed on the web server.

Also, loading the snap-in directly is unsupported by Exchange 2010.

See http://technet.microsoft.com/en-us/library/dd297932.aspx for details.

Sample code:

using (var ps = PowerShell.Create()) {
    ps.AddScript("$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionURI 'http://[host]/PowerShell/' ; Import-PSSession -Session $session");
    ps.Invoke();
    // ... further powershell pipelines - now connected to Exchange and cmdlets are loaded
}

You should also investigate sending an empty PSDataCollection to Invoke that has had Complete() called on it. This will stop the Powershell pipeline from blocking on an input request, something that will hang your webserver process.

var psInput = new PSDataCollection<PSObject>();
psInput.Complete();
JT.
  • 469
  • 6
  • 9