Exchange Online Powershell BasicAuthToOAuth not working with WSManConnectionInfo

Viewed 58

Our code currently uses WSManConnectionInfo class to connect to O365. We use basic auth and are trying to upgrade to modern auth. I turned off basic auth in my tenant. Following this guide here, https://www.michev.info/Blog/Post/2997/connecting-to-exchange-online-powershell-via-client-secret-fl..., I am able to connect successfully in PowerShell by getting an access token and using New-PSSession cmdlet. I use the following commands:

Add-Type -Path 'C:\Program Files\WindowsPowerShell\Modules\AzureAD\2.0.2.140\Microsoft.IdentityModel.Clients.ActiveDirectory.dll'
 
$authContext45 = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList " https://login.windows.net/mytenant.onmicrosoft.com"
$secret = Get-ChildItem cert://localmachine/my/thumbprint
$CAC = [Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate]::new(appId,$secret)
$authenticationResult = $authContext45.AcquireTokenAsync("https://outlook.office365.com",$CAC)

$token = $authenticationResult.Result.AccessToken
$Authorization = "Bearer {0}" -f $Token
$Password = ConvertTo-SecureString -AsPlainText $Authorization -Force
$Ctoken = New-Object System.Management.Automation.PSCredential -ArgumentList "OAuthUser@tenantGUID",$Password
 
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/PowerShell-LiveId?BasicAuthToOAuthConversion=true -Credential $Ctoken -Authentication Basic -AllowRedirection -Verbose
Import-PSSession $Session

However, when I try to use C# WSManConnectionInfo to do the same thing, I get this strange error whenever I try to open the runspace:

System.Management.Automation.Remoting.PSRemotingTransportException HResult=0x80131501 Message=Connecting to remote server outlook.office365.com failed with the following error message : The WS-Management service cannot process the request. Cannot find the https://schemas.microsoft.com/powershell/Microsoft.Exchange session configuration in the WSMan: drive on the outlook.office365.com computer. For more information, see the about_Remote_Troubleshooting Help topic. Here is the code:

    public static Collection<PSObject> GetUsersUsingOAuthPublic()
    {
        var authContext = new AuthenticationContext("https://login.windows.net/mytenant.onmicrosoft.com");
        X509Store certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);

        certStore.Open(OpenFlags.ReadOnly);
        X509Certificate2Collection certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, certThumbprint, false);
        certStore.Close();
        var cac = new ClientAssertionCertificate(appId, certCollection[0]);
        var authResult = authContext.AcquireTokenAsync("https://outlook.office365.com", cac);

        var token = authResult.Result.AccessToken;
        string auth = string.Format("Bearer {0}", token);
        System.Security.SecureString password = new System.Security.SecureString();

        foreach (char c in auth)
        {
            password.AppendChar(c);
        }

        PSCredential psCredential = new PSCredential(string.Format("OAuthUser@{0}", tenantId), password);

        WSManConnectionInfo connectionInfo = new WSManConnectionInfo(
            new Uri("https://outlook.office365.com/powershell-liveid?BasicAuthToOAuthConversion=true"),
            "https://schemas.microsoft.com/powershell/Microsoft.Exchange",
            psCredential
            );
        connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
        connectionInfo.SkipCACheck = true;
        connectionInfo.SkipCNCheck = true;

        using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
        {
            return GetUserInformation(10, runspace);
        }
    }

I open the runspace like so:

    public static Collection<PSObject> GetUserInformation(int count, Runspace runspace)
    {
        using (PowerShell powershell = PowerShell.Create())
        {
            powershell.AddCommand("Get-Users");
            powershell.AddParameter("ResultSize", count);
            runspace.Open();
            powershell.Runspace = runspace;
            return powershell.Invoke();
        }
    }

The exception: Image of exception

1 Answers

As far as I know this is not supported by Microsoft. To connect to Exchange Online with MFA you should use one of the supported methods described here: https://learn.microsoft.com/en-gb/powershell/exchange/connect-to-exchange-online-powershell?view=exchange-ps

Please check my answer for connecting using the certificate thumbprint in a form of unattended script which is the closest to what you would like to achieve: Connecting to Exchange Online with a Certificate and C#

Your other options for connecting are:

  • Interactive scripting using browser-based single sign-on
  • Device-based log in
  • Inline credentials

all of those options are described in my link above

Related