MicrosoftTeams cmdlet 不使用 AccessToken
MicrosoftTeams cmdlets not working with AccessToken
我正在尝试在 C# Web 应用程序中 运行 来自 powershell 模块 MicrosoftTeams(版本 2.0.0)的 cmdlet。我正在使用此 post 中提供的答案中的授权代码流和代码来获取令牌:Acquire AAD token using ASP.Net web forms。注意:我已将代码中的资源更改为 graph.windows.net 以获取 AAD 令牌。使用AuthenticationContext.AcquireTokenByAuthorizationCodeAsync方法获取token。
获得令牌后,我运行以下行在 C# 中创建一个 powershell 实例并导入 MicrosoftTeams 模块。
PowerShell pshell
InitialSessionState iss;
iss = InitialSessionState.CreateDefault2();
iss.ImportPSModule(new[] { "MicrosoftTeams" });
pshell = PowerShell.Create(iss);
然后为了连接 MicrosoftTeams,我 运行 以下代码:
var connectCmd = new Command("Connect-MicrosoftTeams");
connectCmd.Parameters.Add("AadAccessToken", AccessToken);
connectCmd.Parameters.Add("AccountId", "xxxxxxx@xxxxxx.onmicrosoft.com");
pshell.Commands.AddCommand(connectCmd);
var result1 = pshell.Invoke();
代码到这里都可以正常工作。
在此之后,我清除 shell 命令并调用 Get-CsTeamsCallingPolicy cmdlet:
pshell.Commands.Clear();
pshell.Streams.Error.Clear();
pshell.AddScript("Get-CsTeamsCallingPolicy");
var result2 = pshell.Invoke();
Invoke 后,出现异常并弹出此对话框:
按 'Continue' 多次返回相同的对话。
此屏幕的异常详细信息是:
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\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\s\src\Microsoft.TeamsCmdlets.PowerShell.Connect\TeamsPowerShellSession.cs:line 82
at Microsoft.TeamsCmdlets.PowerShell.Connect.GetCsInternalAccessToken.ProcessRecord() in D:\a\s\src\Microsoft.TeamsCmdlets.PowerShell.Connect\GetCsInternalAccessToken.cs:line 61
at System.Management.Automation.CommandProcessor.ProcessRecord()
第 3 次按继续后,控制返回到 C# 代码,我收到以下 运行time 异常:
Exception calling "GetSteppablePipeline" with "1" argument(s):
"Exception calling "GetRemoteNewCsOnlineSession" with "1" argument(s):
"Run either Connect-MicrosoftTeams or new-csonlinesession before running cmdlets.""
尝试 运行 来自 powershell 编辑器的这个逻辑显示了类似的行为:
运行下面两行:
$AccessToken = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
Connect-MicrosoftTeams -AadAccessToken $AccessToken -AccountId 'xxxxxxx@xxxxxx.onmicrosoft.com'
给出这个结果:
Account Environment Tenant TenantId
------- ----------- ------ --------
xxxxxxx@xxxxxx.onmicrosoft.com AzureCloud xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
然后我 运行 Get-Team cmdlet:
Get-Team -User xxxxxxx@xxxxxxx.onmicrosoft.com
导致此消息:
Get-Team : The given key was not present in the dictionary.
At line:1 char:1
+ Get-Team -User xxxxxxx@xxxxxxx.onmicrosoft.com
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Team], KeyNotFoundException
+ FullyQualifiedErrorId : System.Collections.Generic.KeyNotFoundException,Microsoft.TeamsCmdlets.PowerShell.Custom.GetTeam
运行 cmdlet Get-CsTeamsCallingPolicy 产生这个
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.0.0\net472\SfBORemotePowershellModule.psm1:11369 char:13
+ $steppablePipeline = $scriptCmd.GetSteppablePipeline($myI ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : CmdletInvocationException
如果我 运行 直接连接 MicrosoftTeams 而不提供访问令牌和帐户 ID,我会看到登录屏幕,登录后一切正常,但 AadAccessToken 不会发生。
如果在 Web 应用程序和 powershell 编辑器中通过 Connect-AzureAD cmdlet 连接到 AzureAD 模块,相同的代码工作正常:
Connect-AzureAD -AadAccessToken $AccessToken -AccountId 'xxxxxxx@xxxxxxx.onmicrosoft.com'
如果有人遇到并成功解决了这个问题,或者有一些关于如何解决这个问题的提示,请提供帮助。
我已经尝试了很多事情,包括搜索特定的异常消息和任何可能的解决方案,但在这种特定情况下没有找到任何可以帮助的东西,安装了最新版本的 MSTeams 模块,以前的版本很旧并且没有没有我希望使用的所有 cmdlet。我实际上还安装了 MSTeams 模块的预览版,以查看此问题是否会在即将发布的版本中得到解决。卸载了已弃用的 SkypeForBuisnessOnline 连接器模块,更新了 windows 等。如果您查看 Connect-MicrosoftTeams 的 Microsoft 文档中的示例 4,这就是我所关注的内容。
你的实现有几个问题,下面我会一一说明。
answer in this post 生成 Microsoft Graph 访问令牌而不是 AAD Graph 访问令牌。但是你把它写成-AadAccessToken
。您应该在此处将其作为 -MsAccessToken
放置,因为 Get-Team
正在调用 Microsoft Graph。但是我们不能简单地使用 Connect-MicrosoftTeams -MsAccessToken $AadAccessToken-AccountId 'xxxxxxx@xxxxxx.onmicrosoft.com'
因为 -AadAccessToken
是必需的。因此为了测试目的,我们可以将其设置为与 -MsAccessToken
.
相同
因此您可以使用此 cmd 连接到 Microsoft Teams:
Connect-MicrosoftTeams -AadAccessToken $AadAccessToken -MsAccessToken $AadAccessToken -AccountId 'xxxxxxx@xxxxxx.onmicrosoft.com'
那么就可以运行Get-Team -User xxxxxxx@xxxxxxx.onmicrosoft.com
成功了
但是这里还有一个问题。 Get-CsTeamsCallingPolicy
是 Skype For Business Powershell 模块下的一个命令。在 运行 宁 cmdlet 之前,我们必须 运行 Connect-MicrosoftTeams
(在 Teams 模块中)或 new-csonlinesession
(在 SFB 模块中)。
这意味着 Get-CsTeamsCallingPolicy
不是 调用 Microsoft Graph 或 AAD Graph。
所以使用 -AadAccessToken
和 -MsAccessToken
的连接方法 NOT 不足以让你从 SFB 模块 运行 这个命令。
我知道您不想在此处为 运行ning Powershell cmd 再次执行交互式登录。但是,由于您的帐户已经启用了 MFA,静态登录将不再适用。
接下来我尝试按照示例 3 here.
连接服务主体
Connect-MicrosoftTeams -TenantId c3eac90d-eb4b-48ef-ac86-7acac472d3cd -CertificateThumbprint 9b6ac64bfb8b48dbb53cca75fb33ce2d -applicationid daaaf729-aaff-45ba-8055-a39dd618fe24
然后错误 Run either Connect-MicrosoftTeams or new-csonlinesession before running cmdlets.
被绕过 但是 我在 运行 `Get-CsTeamsCallingPolicy:
时遇到了一个新错误
Exception calling "GetRemoteNewCsOnlineSession" with "1" argument(s): "Tenant Domain is empty"
但是我在使用服务主体登录时明确指定了租户id。
所以我认为Microsoft Teams 模块目前与SFB 模块没有很好地集成。
您的设计不能以这种方式实现。
希望我的所有发现对您有所帮助。
我正在尝试在 C# Web 应用程序中 运行 来自 powershell 模块 MicrosoftTeams(版本 2.0.0)的 cmdlet。我正在使用此 post 中提供的答案中的授权代码流和代码来获取令牌:Acquire AAD token using ASP.Net web forms。注意:我已将代码中的资源更改为 graph.windows.net 以获取 AAD 令牌。使用AuthenticationContext.AcquireTokenByAuthorizationCodeAsync方法获取token。
获得令牌后,我运行以下行在 C# 中创建一个 powershell 实例并导入 MicrosoftTeams 模块。
PowerShell pshell
InitialSessionState iss;
iss = InitialSessionState.CreateDefault2();
iss.ImportPSModule(new[] { "MicrosoftTeams" });
pshell = PowerShell.Create(iss);
然后为了连接 MicrosoftTeams,我 运行 以下代码:
var connectCmd = new Command("Connect-MicrosoftTeams");
connectCmd.Parameters.Add("AadAccessToken", AccessToken);
connectCmd.Parameters.Add("AccountId", "xxxxxxx@xxxxxx.onmicrosoft.com");
pshell.Commands.AddCommand(connectCmd);
var result1 = pshell.Invoke();
代码到这里都可以正常工作。
在此之后,我清除 shell 命令并调用 Get-CsTeamsCallingPolicy cmdlet:
pshell.Commands.Clear();
pshell.Streams.Error.Clear();
pshell.AddScript("Get-CsTeamsCallingPolicy");
var result2 = pshell.Invoke();
Invoke 后,出现异常并弹出此对话框:
按 'Continue' 多次返回相同的对话。
此屏幕的异常详细信息是:
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\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\s\src\Microsoft.TeamsCmdlets.PowerShell.Connect\TeamsPowerShellSession.cs:line 82
at Microsoft.TeamsCmdlets.PowerShell.Connect.GetCsInternalAccessToken.ProcessRecord() in D:\a\s\src\Microsoft.TeamsCmdlets.PowerShell.Connect\GetCsInternalAccessToken.cs:line 61
at System.Management.Automation.CommandProcessor.ProcessRecord()
第 3 次按继续后,控制返回到 C# 代码,我收到以下 运行time 异常:
Exception calling "GetSteppablePipeline" with "1" argument(s):
"Exception calling "GetRemoteNewCsOnlineSession" with "1" argument(s):
"Run either Connect-MicrosoftTeams or new-csonlinesession before running cmdlets.""
尝试 运行 来自 powershell 编辑器的这个逻辑显示了类似的行为:
运行下面两行:
$AccessToken = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
Connect-MicrosoftTeams -AadAccessToken $AccessToken -AccountId 'xxxxxxx@xxxxxx.onmicrosoft.com'
给出这个结果:
Account Environment Tenant TenantId
------- ----------- ------ --------
xxxxxxx@xxxxxx.onmicrosoft.com AzureCloud xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
然后我 运行 Get-Team cmdlet:
Get-Team -User xxxxxxx@xxxxxxx.onmicrosoft.com
导致此消息:
Get-Team : The given key was not present in the dictionary.
At line:1 char:1
+ Get-Team -User xxxxxxx@xxxxxxx.onmicrosoft.com
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Team], KeyNotFoundException
+ FullyQualifiedErrorId : System.Collections.Generic.KeyNotFoundException,Microsoft.TeamsCmdlets.PowerShell.Custom.GetTeam
运行 cmdlet Get-CsTeamsCallingPolicy 产生这个
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.0.0\net472\SfBORemotePowershellModule.psm1:11369 char:13
+ $steppablePipeline = $scriptCmd.GetSteppablePipeline($myI ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : CmdletInvocationException
如果我 运行 直接连接 MicrosoftTeams 而不提供访问令牌和帐户 ID,我会看到登录屏幕,登录后一切正常,但 AadAccessToken 不会发生。
如果在 Web 应用程序和 powershell 编辑器中通过 Connect-AzureAD cmdlet 连接到 AzureAD 模块,相同的代码工作正常:
Connect-AzureAD -AadAccessToken $AccessToken -AccountId 'xxxxxxx@xxxxxxx.onmicrosoft.com'
如果有人遇到并成功解决了这个问题,或者有一些关于如何解决这个问题的提示,请提供帮助。
我已经尝试了很多事情,包括搜索特定的异常消息和任何可能的解决方案,但在这种特定情况下没有找到任何可以帮助的东西,安装了最新版本的 MSTeams 模块,以前的版本很旧并且没有没有我希望使用的所有 cmdlet。我实际上还安装了 MSTeams 模块的预览版,以查看此问题是否会在即将发布的版本中得到解决。卸载了已弃用的 SkypeForBuisnessOnline 连接器模块,更新了 windows 等。如果您查看 Connect-MicrosoftTeams 的 Microsoft 文档中的示例 4,这就是我所关注的内容。
你的实现有几个问题,下面我会一一说明。
answer in this post 生成 Microsoft Graph 访问令牌而不是 AAD Graph 访问令牌。但是你把它写成-AadAccessToken
。您应该在此处将其作为 -MsAccessToken
放置,因为 Get-Team
正在调用 Microsoft Graph。但是我们不能简单地使用 Connect-MicrosoftTeams -MsAccessToken $AadAccessToken-AccountId 'xxxxxxx@xxxxxx.onmicrosoft.com'
因为 -AadAccessToken
是必需的。因此为了测试目的,我们可以将其设置为与 -MsAccessToken
.
因此您可以使用此 cmd 连接到 Microsoft Teams:
Connect-MicrosoftTeams -AadAccessToken $AadAccessToken -MsAccessToken $AadAccessToken -AccountId 'xxxxxxx@xxxxxx.onmicrosoft.com'
那么就可以运行Get-Team -User xxxxxxx@xxxxxxx.onmicrosoft.com
成功了
但是这里还有一个问题。 Get-CsTeamsCallingPolicy
是 Skype For Business Powershell 模块下的一个命令。在 运行 宁 cmdlet 之前,我们必须 运行 Connect-MicrosoftTeams
(在 Teams 模块中)或 new-csonlinesession
(在 SFB 模块中)。
这意味着 Get-CsTeamsCallingPolicy
不是 调用 Microsoft Graph 或 AAD Graph。
所以使用 -AadAccessToken
和 -MsAccessToken
的连接方法 NOT 不足以让你从 SFB 模块 运行 这个命令。
我知道您不想在此处为 运行ning Powershell cmd 再次执行交互式登录。但是,由于您的帐户已经启用了 MFA,静态登录将不再适用。
接下来我尝试按照示例 3 here.
连接服务主体Connect-MicrosoftTeams -TenantId c3eac90d-eb4b-48ef-ac86-7acac472d3cd -CertificateThumbprint 9b6ac64bfb8b48dbb53cca75fb33ce2d -applicationid daaaf729-aaff-45ba-8055-a39dd618fe24
然后错误 Run either Connect-MicrosoftTeams or new-csonlinesession before running cmdlets.
被绕过 但是 我在 运行 `Get-CsTeamsCallingPolicy:
Exception calling "GetRemoteNewCsOnlineSession" with "1" argument(s): "Tenant Domain is empty"
但是我在使用服务主体登录时明确指定了租户id。
所以我认为Microsoft Teams 模块目前与SFB 模块没有很好地集成。
您的设计不能以这种方式实现。
希望我的所有发现对您有所帮助。