Exchange Online Powershell BasicAuthToOAuth not working with WSManConnectionInfo

onyx1231 1 Reputation point
2022-09-17T14:40:19.283+00:00

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();  
    }  
  }  

An image of the exception: 242146-basicauthtooauth-wsman.png

Microsoft Exchange Online Management
Microsoft Exchange Online Management
Microsoft Exchange Online: A Microsoft email and calendaring hosted service.Management: The act or process of organizing, handling, directing or controlling something.
4,476 questions
Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,504 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Vasil Michev 103.5K Reputation points MVP
    2022-09-17T14:57:42.693+00:00

    Why aren't you using the V2 module, which supports OAuth via CBA by default? https://learn.microsoft.com/en-us/powershell/exchange/app-only-auth-powershell-v2?view=exchange-ps
    Or even better, the V3 approach that removes the dependency on WinRM/WSMan altogether? https://www.michev.info/Blog/Post/3883/exchange-online-powershell-module-gets-rid-of-the-winrm-dependence
    Scroll down to the second part of the article to see how you can use the same method without even needing PowerShell.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.