kshab
kshab

Reputation: 39

MicrosoftTeams cmdlets not working with AccessToken

I am trying to run cmdlets from powershell module MicrosoftTeams (version 2.0.0) in a C# web application. I am using Authorization code flow and code from the answer provided in this post to acquire token: Acquire AAD token using ASP.Net web forms. Note: I had changed resource in the code to graph.windows.net to acquire AAD token. Token is acquired by using AuthenticationContext.AcquireTokenByAuthorizationCodeAsync Method.

Once the token is acquired, I run the following lines to create a powershell instance in C# and to import MicrosoftTeams Module.

PowerShell pshell
InitialSessionState iss;
iss = InitialSessionState.CreateDefault2();
iss.ImportPSModule(new[] { "MicrosoftTeams" });
pshell = PowerShell.Create(iss);

Then to connect with MicrosoftTeams, I run the following code:

var connectCmd = new Command("Connect-MicrosoftTeams");
connectCmd.Parameters.Add("AadAccessToken", AccessToken);
connectCmd.Parameters.Add("AccountId", "[email protected]");
pshell.Commands.AddCommand(connectCmd);
var result1 = pshell.Invoke();

Code works fine till here.

After this I clear the shell commands and invoke the Get-CsTeamsCallingPolicy cmdlet:

pshell.Commands.Clear();
pshell.Streams.Error.Clear();

pshell.AddScript("Get-CsTeamsCallingPolicy");
var result2 = pshell.Invoke();

After Invoke, I get an exception and this dialog pops up:

enter image description here

Pressing 'Continue' brings back the same dialogue a couple of times.

Exception details from this screen are:

System.Collections.Generic.KeyNotFoundException was unhandled by user code
  HResult=-2146232969
  Message=The given key was not present in the dictionary.
  Source=mscorlib
  StackTrace:
       at System.Collections.Concurrent.ConcurrentDictionary`2.get_Item(TKey key)
       at Microsoft.TeamsCmdlets.Powershell.Connect.Models.AzureSessionProvider.GetAccessToken(String resource, IEnumerable`1 scopes) in D:\a\1\s\src\Microsoft.TeamsCmdlets.PowerShell.Connect\Models\AzureSession.cs:line 80
       at Microsoft.TeamsCmdlets.Powershell.Connect.TeamsPowerShellSession.GetAccessToken(String resource, IEnumerable`1 scopes) in D:\a\1\s\src\Microsoft.TeamsCmdlets.PowerShell.Connect\TeamsPowerShellSession.cs:line 82
       at Microsoft.TeamsCmdlets.PowerShell.Connect.GetCsInternalAccessToken.ProcessRecord() in D:\a\1\s\src\Microsoft.TeamsCmdlets.PowerShell.Connect\GetCsInternalAccessToken.cs:line 61
       at System.Management.Automation.CommandProcessor.ProcessRecord()

After pressing continue for the 3rd time, control goes back to C# code, and I receive the following runtime exception:

Exception calling "GetSteppablePipeline" with "1" argument(s): 
"Exception calling "GetRemoteNewCsOnlineSession" with "1" argument(s): 
"Run either Connect-MicrosoftTeams or new-csonlinesession before running cmdlets."" 

Trying to run this logic from the powershell editor shows similar behavior:

Running the following two lines:

$AccessToken =  'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 
Connect-MicrosoftTeams -AadAccessToken $AccessToken -AccountId '[email protected]'

gives this result:

Account                         Environment Tenant                               TenantId                            
-------                         ----------- ------                               --------                            
[email protected] AzureCloud  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

I then run Get-Team cmdlet:

Get-Team -User [email protected]

which results in this message:

Get-Team : The given key was not present in the dictionary.
At line:1 char:1
+ Get-Team -User [email protected]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-Team], KeyNotFoundException
    + FullyQualifiedErrorId : System.Collections.Generic.KeyNotFoundException,Microsoft.TeamsCmdlets.PowerShell.Custom.GetTeam

Running cmdlet Get-CsTeamsCallingPolicy yields this

Exception calling "GetSteppablePipeline" with "1" argument(s): 
"Exception calling "GetRemoteNewCsOnlineSession" with "1" argument(s): 
"Run either Connect-MicrosoftTeams or new-csonlinesession before running cmdlets.""
At C:\Program Files\WindowsPowerShell\Modules\MicrosoftTeams\2.0.0\net472\SfBORemotePowershellModule.psm1:11369 char:13
+             $steppablePipeline = $scriptCmd.GetSteppablePipeline($myI ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : CmdletInvocationException

If I run Connect-MicrosoftTeams directly without providing access token and accountid, I get the login screens and after login everything works fine but not happening with AadAccessToken.

Same code works fine if connecting to AzureAD module via Connect-AzureAD cmdlet like this both in web application and powershell editor:

Connect-AzureAD -AadAccessToken $AccessToken -AccountId '[email protected]'

If someone has faced and successfully resolved this issue or have some tips on how to resolve this, please help.

I have already tried a lot of things including searching for the specific exception messages and any possible solutions but found nothing that could help in this particular scenario, installed the latest version of MSTeams module, the previous version was old and did not have all the cmdlets that I am looking to work with. I actually installed the preview version of MSTeams module also to see if this issue is fixed in the upcoming release. Uninstalled the deprecated SkypeForBuisnessOnline Connector module, updated windows and so on. If you look at Example 4 in the Microsoft documentation for Connect-MicrosoftTeams, this is what I am following.

Upvotes: 2

Views: 2099

Answers (1)

Allen Wu
Allen Wu

Reputation: 16438

There are several problems in your implementation, I will explain them one by one below.

The answer in this post generates an Microsoft Graph access token rather than an AAD Graph access token. But you put it as the -AadAccessToken. You should put it as -MsAccessToken here because Get-Team is calling Microsoft Graph. But we cannot simply use Connect-MicrosoftTeams -MsAccessToken $AadAccessToken-AccountId '[email protected]' because the -AadAccessToken is necessary. So for testing purpose, we could set it as the same as -MsAccessToken.

So you can use this cmd to connect to Microsoft Teams:

Connect-MicrosoftTeams -AadAccessToken $AadAccessToken -MsAccessToken $AadAccessToken -AccountId '[email protected]'

Then you can run Get-Team -User [email protected] successfully.

But there will be another issue here. Get-CsTeamsCallingPolicy is a cmd under Skype For Business Powershell module. We have to run either Connect-MicrosoftTeams (in Teams module) or new-csonlinesession (in SFB module) before running cmdlets.

It means that Get-CsTeamsCallingPolicy is NOT calling Microsoft Graph or AAD Graph.

So the connection method using -AadAccessToken and -MsAccessToken is NOT enough for you to run this command from the SFB module.

I know you don't want to perform login interactively again here for running Powershell cmd. However, since your account has already enabled MFA, static login will no longer apply.

So next I tried to connect with a service principal by following Example 3 here.

Connect-MicrosoftTeams -TenantId c3eac90d-eb4b-48ef-ac86-7acac472d3cd -CertificateThumbprint 9b6ac64bfb8b48dbb53cca75fb33ce2d -applicationid daaaf729-aaff-45ba-8055-a39dd618fe24

Then the error Run either Connect-MicrosoftTeams or new-csonlinesession before running cmdlets. is bypassed BUT I got a new error when I run `Get-CsTeamsCallingPolicy:

Exception calling "GetRemoteNewCsOnlineSession" with "1" argument(s): "Tenant Domain is empty"

But I clearly specified the tenant id when I logged in with the service principal.

So I think that the Microsoft Teams module is not well integrated with SFB module currently.

Your design cannot be implemented in this way.

Hope all my findings are helpful.

Upvotes: 3

Related Questions