'How to connect to Exchange Remote PowerShell and run cmdlets programmatically in ASP.NET Core

I want to connect Microsoft.Exchange in my ASP.NET core 5 project. The script I started with is documented here. I'm not able to import the Microsoft.Exchange session into local runspace, which then makes the Exchange cmdlets available directly in a local runspace. I run into known issue which is documented here. I can only connect to remote Exchange runspace in No-Language mode, which will only provide Exchange cmdlets to be executed. So I tried the first resolution from the link above without success:

Make sure that all calls that use .invoke() are also using .AddCommand() and not .AddScript()...

        PowerShell ps = PowerShell.Create();
        PSCommand command = new PSCommand();
        newSession.AddCommand("New-PSSession");
        newSession.AddParameter("ConfigurationName", "Microsoft.Exchange");
        ...
        ps.Commands = command;
        Collection<PSObject> session = ps.Invoke();
        
        command = new PSCommand();
        importSession.AddCommand("Import-PSSession");
        importSession.AddParameter("Session", session[0]);
        ...

For second resolution:

Implement an imported session instead of using .invoke(). For more information, ...

I don't know how to put pieces together. What I did so far is, to connect remote Exchange runspace in No-Language mode:

    string username = @"domain\username";
    string password = "password";
    SecureString ssPassword = new SecureString();
    foreach (char x in password)
        ssPassword.AppendChar(x);
    PSCredential credentials = new PSCredential(username, ssPassword);
    var connInfo = new WSManConnectionInfo(new Uri(@"http://servername/powershell"), @"http://schemas.microsoft.com/powershell/Microsoft.Exchange", credentials);
    connInfo.AuthenticationMechanism = AuthenticationMechanism.Kerberos;
    connInfo.SkipCACheck = true;
    connInfo.SkipCNCheck = true;

    var runspace = RunspaceFactory.CreateRunspace(connInfo);
    runspace.Open();
    Pipeline pipe = runspace.CreatePipeline();
    Command getMailbox = new Command("get-mailbox");
    getMailbox.Parameters.Add("OrganizationalUnit", "OU=XY,DC=domain,DC=com");
    getMailbox.Parameters.Add("Resultsize", "Unlimited");
    pipe.Commands.Add(getMailbox);
    Collection<PSObject> result = pipe.Invoke();
    pipe.Stop();
    runspace.Close();
    runspace.Dispose();

The result of the code snippet above is exactly what I expected but it would be helpful if I can use scripts directly in my project, with respect to the resolutions I linked above.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source