使用 C# 连接到 Exchange Online PowerShell

本文中的代码示例使用 Exchange Online PowerShell V3 模块从 C# 连接到Exchange Online。

若要安装 Exchange Online PowerShell 模块,请参阅安装和维护 Exchange Online PowerShell 模块

提示

Exchange Online PowerShell V3 模块中的 REST API 连接需要 PowerShellGet 和 PackageManagement 模块。 有关详细信息,请参阅 PowerShellGet for 基于 REST 的连接在 Windows 中

如果在尝试连接时遇到错误,请在 Connect-ExchangeOnline cmdlet 上使用 SkipLoadingFormatData 开关。

示例 1:使用 PowerShell 运行空间创建单个连接

using System.Collections.ObjectModel;

using System.Management.Automation;

using System.Management.Automation.Runspaces;

using System.Security;

void SingleConnectionToExchangeOnline()

{

    // Setup the Initial Session State of each runspace in the pool

    // Import the ExchangeOnlineManagement module.

    // Set the Execution Policy of the runspace.

    InitialSessionState iss = InitialSessionState.CreateDefault();

    iss.ImportPSModule(new string[] { "ExchangeOnlineManagement" });

    iss.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.RemoteSigned;

    iss.ThrowOnRunspaceOpenError = true;

    Runspace runspace = RunspaceFactory.CreateRunspace(iss);

    runspace.Open();

    // Run the Connect-ExchangeOnline command in the runspace to create a connection with EXO.

    PowerShell ps = PowerShell.Create(runspace);

    ps.AddCommand("Connect-ExchangeOnline");

    ps.AddParameters(new Dictionary<string, object>

    {

        ["Organization"] = "contoso.onmicrosoft.com",

        ["CertificateFilePath"] = "C:\\Users\\Certificates\\mycert.pfx",

        ["CertificatePassword"] = GetPassword(),

        ["AppID"] = "a37927a4-1a1a-4162-aa29-e346d5324590"

    });

    // Execute the script synchronously.

    Collection<PSObject> connectionResult = ps.Invoke();

    // Clear the connection commands before running cmdlets.

    ps.Commands.Clear();

    // Create a new command to execute an Exchange Online cmdlet.

    ps.AddCommand("Get-Mailbox");

    ps.AddParameter("Identity", "ContosoUser1");

    Collection<PSObject> results = ps.Invoke();

    // Check if there were any errors.

    if (!ps.HadErrors)

    {

        // Write the results to console.

        foreach (PSObject result in results)

        {

            Console.WriteLine(result.ToString());

        }

    }

    else

    {

        // Write the errors to console by accessing the error stream of the Powershell object.

        foreach (ErrorRecord error in ps.Streams.Error)

        {

            Console.WriteLine(error.ToString());

        }

    }

}

SecureString GetPassword()

{

    // Return the Password as a SecureString

}

示例 2:使用 PowerShell 运行空间池创建多个连接

使用此代码示例并行运行多个Exchange Online PowerShell cmdlet。

PowerShell CreateConnectionCommand(RunspacePool pool)

{

    PowerShell ps = PowerShell.Create();

    ps.RunspacePool = pool;

    ps.AddCommand("Connect-ExchangeOnline");

    ps.AddParameters(new Dictionary<string, object>

    {

        ["Organization"] = "contoso.onmicrosoft.com",

        ["CertificateFilePath"] = "C:\\Users\\Certificates\\mycert.pfx",

        ["CertificatePassword"] = GetPassword(),

        ["AppID"] = "a37927a4-1a1a-4162-aa29-e346d5324590"

    });

    return ps;

}

void ParallelConnectionsToExchangeOnline()

{

    // Setup the Initial Session State of each runspace in the pool

    // Import the ExchangeOnlineManagement module.

    // Set the Execution Policy of the runspace.

    InitialSessionState iss = InitialSessionState.CreateDefault();

    iss.ImportPSModule(new string[] { "ExchangeOnlineManagement" });

    iss.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.RemoteSigned;

    iss.ThrowOnRunspaceOpenError = true;

    // Create a RunspacePool initialized with the Initial Session State.

    using (RunspacePool pool = RunspaceFactory.CreateRunspacePool(iss))

    {

        // Configure the number of runspaces to maintain in the RunspacePool.

        pool.SetMaxRunspaces(3);

        pool.SetMinRunspaces(3);

        // Set the ThreadOptions to reuse the same threads for the runspaces so that

        // the Exchange Online cmdlets will be available after running Connect-ExchangeOnline in each runspace.

        pool.ThreadOptions = PSThreadOptions.ReuseThread;

        pool.Open();

        // Run the Connect-ExchangeOnline cmdlet in all the runspaces in the pool

        // so that any cmdlets can be run in them after that.

        PowerShell ps1 = CreateConnectionCommand(pool);

        PowerShell ps2 = CreateConnectionCommand(pool);

        PowerShell ps3 = CreateConnectionCommand(pool);

        // Execute each of the 3 Connect-ExchangeOnline commands asynchronously.

        IAsyncResult job1 = ps1.BeginInvoke();

        IAsyncResult job2 = ps2.BeginInvoke();

        IAsyncResult job3 = ps3.BeginInvoke();

        // Get the results of the commands.

        PSDataCollection<PSObject> connectionResult = ps1.EndInvoke(job1);

        PSDataCollection<PSObject> connectionResult2 = ps2.EndInvoke(job2);

        PSDataCollection<PSObject> connectionResult3 = ps3.EndInvoke(job3);

        // Execute two Exchange-Online commands in parallel using the runspacepool.

        // All of them have an active connection to Exchange Online.

        // NOTE : Cmdlets that update the same object or can cause conflicting
        // results should not be run in parallel as they can lead to an undefined
        // outcome.

        PowerShell commandPS1 = PowerShell.Create();

        commandPS1.RunspacePool = pool;

        commandPS1.AddCommand("Get-Mailbox");

        commandPS1.AddParameter("Identity", "ContosoUser1");

        PowerShell commandPS2 = PowerShell.Create();

        commandPS2.RunspacePool = pool;

        commandPS2.AddCommand("Get-Mailbox");

        commandPS2.AddParameter("Identity", "ContosoUser2");

        IAsyncResult commandJob1 = commandPS1.BeginInvoke();

        IAsyncResult commandJob2 = commandPS2.BeginInvoke();

        // Wait for the commands to finish and return the results.

        PSDataCollection<PSObject> command1Result = commandPS1.EndInvoke(commandJob1);

        PSDataCollection<PSObject> command2Result = commandPS2.EndInvoke(commandJob2);

        // Check if there were any errors.

        if (!commandPS1.HadErrors)

        {

            // Write the results to console.

            foreach (PSObject result in command1Result)

            {

                Console.WriteLine(result.ToString());

            }

        }

        else

        {

            // Write the errors to console by accessing the error stream of the Powershell object.

            foreach (ErrorRecord error in commandPS1.Streams.Error)

            {

                Console.WriteLine(error.ToString());

            }

        }

        // Check if there were any errors.

        if (!commandPS2.HadErrors)

        {

            // Write the results to console.

            foreach (PSObject result in command2Result)

            {

                Console.WriteLine(result.ToString());

            }

        }

        else

        {

            // Write the errors to console by accessing the error stream of the Powershell object.

            foreach (ErrorRecord error in commandPS2.Streams.Error)

            {

                Console.WriteLine(error.ToString());

            }

        }

    }

}