在.NET7后台工作者中调用PowerShell进行Azure服务主体认证遇异常
问题:.NET7后台工作者调用PowerShell执行Azure服务主体认证时抛出EntryPointNotFoundException
场景与代码
.NET7后台工作者调用PowerShell代码
using PowerShell ps = PowerShell.Create(); ps.AddScript("auth.ps1"); var pipelineObjects = await ps.InvokeAsync();
PowerShell认证脚本(依赖Az.Accounts 2.2.3)
Import-Module Az.Accounts Clear-AzContext -Force $tenantID = " " $subscriptionID = " " $azureAplicationId = " "; $azurePassword = ConvertTo-SecureString "" -AsPlainText -Force; $credentials = New-Object System.Management.Automation.PSCredential($azureAplicationId, $azurePassword); try { Connect-AzAccount -Credential $credentials -TenantId $tenantID -ServicePrincipal -ErrorAction Stop } catch { Write-Error $Exception ; }
抛出的异常信息
PSMessageDetails : Exception : System.EntryPointNotFoundException: 未找到入口点。 at System.Threading.Tasks.Sources.IValueTaskSource`1.GetStatus(Int16 token) at Microsoft.Azure.PowerShell.Authenticators.MsalAccessToken.GetAccessTokenAsync(String callerClassName, String parametersLog, TokenCredential tokenCredential, TokenRequestContext requestContext, CancellationToken cancellationToken, String tenantId, String userId, String homeAccountId) at Microsoft.Azure.Commands.Common.Authentication.Factories.AuthenticationFactory.Authenticate(IAzureAccount account, IAzureEnvironment environment, String tenant, SecureString password, String promptBehavior, Action`1 promptAction, IAzureTokenCache tokenCache, String resourceId) at Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient.AcquireAccessToken(IAzureAccount account, IAzureEnvironment environment, String tenantId, SecureString password, String promptBehavior, Action`1 promptAction, String resourceId) at Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient.Login(IAzureAccount account, IAzureEnvironment environment, String tenantIdOrName, String subscriptionId, String subscriptionName, SecureString password, Boolean skipValidation, Action`1 promptAction, String name, Boolean shouldPopulateContextList, Int32 maxContextPopulation, String authScope) at Microsoft.Azure.Commands.Profile.ConnectAzureRmAccountCommand.<>c__DisplayClass127_2.<ExecuteCmdlet>b__5() at System.Threading.Tasks.Task`1.InnerInvoke() at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) --- 上一位置的堆栈跟踪结束 --- at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread) --- 上一位置的堆栈跟踪结束 --- at Microsoft.Azure.Commands.Profile.ConnectAzureRmAccountCommand.<>c__DisplayClass127_0.<ExecuteCmdlet>b__1(AzureRmProfile localProfile, RMProfileClient profileClient, String name) at Microsoft.Azure.Commands.Profile.ConnectAzureRmAccountCommand.<>c__DisplayClass136_0.<SetContextWithOverwritePrompt>b__0(AzureRmProfile prof, RMProfileClient client) at Microsoft.Azure.Commands.Profile.Common.AzureContextModificationCmdlet.ModifyContext(Action`2 contextAction) at Microsoft.Azure.Commands.Profile.ConnectAzureRmAccountCommand.SetContextWithOverwritePrompt(Action`3 setContextAction) at Microsoft.Azure.Commands.Profile.ConnectAzureRmAccountCommand.ExecuteCmdlet() at Microsoft.WindowsAzure.Commands.Utilities.Common.CmdletExtensions.<>c__3`1.<ExecuteSynchronouslyOrAsJob>b__3_0(T c) at Microsoft.WindowsAzure.Commands.Utilities.Common.CmdletExtensions.ExecuteSynchronouslyOrAsJob[T](T cmdlet, Action`1 executor) at Microsoft.WindowsAzure.Commands.Utilities.Common.CmdletExtensions.ExecuteSynchronouslyOrAsJob[T](T cmdlet) at Microsoft.WindowsAzure.Commands.Utilities.Common.AzurePSCmdlet.ProcessRecord() TargetObject : CategoryInfo : CloseError: (:) [Connect-AzAccount], EntryPointNotFoundException FullyQualifiedErrorId : Microsoft.Azure.Commands.Profile.ConnectAzureRmAccountCommand ErrorDetails : InvocationInfo : System.Management.Automation.InvocationInfo ScriptStackTrace : at <ScriptBlock>, <No file>: line 15 PipelineIterationInfo : {} MyCommand : Connect-AzAccount BoundParameters : {} UnboundArguments : {} ScriptLineNumber : 15 OffsetInLine : 6 HistoryId : 1 ScriptName : Line : Connect-AzAccount -Credential $credentials -TenantId $tenantID -ServicePrincipal -ErrorAction Stop PositionMessage : 在第15行第6字符处 + Connect-AzAccount -Credential $credentials -TenantId $tenantID - . + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PSScriptRoot : PSCommandPath : InvocationName : Connect-AzAccount PipelineLength : 0 PipelinePosition : 0 ExpectingInput : False CommandOrigin : Internal DisplayScriptPosition :
解决方案
- 修复版本兼容性:Az.Accounts 2.2.3与.NET7的PowerShell SDK存在Task API依赖冲突,升级Az.Accounts至2.13.0及以上版本(该版本已适配.NET7的IValueTaskSource接口)。若需保留旧模块,可降级PowerShell SDK至兼容.NET5的版本,但不推荐。
- 优化PowerShell执行环境:在.NET代码中显式设置执行策略与模块路径,避免加载冲突:
using var ps = PowerShell.Create(); // 设置进程级执行策略 ps.AddCommand("Set-ExecutionPolicy").AddArgument("RemoteSigned").AddParameter("Scope", "Process").Invoke(); // 指定模块路径,优先加载系统安装的模块 ps.AddScript(@"$env:PSModulePath = ""$env:ProgramFiles\WindowsPowerShell\Modules;$env:SystemRoot\system32\WindowsPowerShell\v1.0\Modules"""); ps.AddScript("auth.ps1"); var pipelineObjects = await ps.InvokeAsync(); - 脚本安全与上下文优化:改用环境变量传递敏感凭证,添加订阅上下文设置确保后续命令生效:
Import-Module Az.Accounts -RequiredVersion 2.13.0 Clear-AzContext -Force $tenantID = $env:AZURE_TENANT_ID $subscriptionID = $env:AZURE_SUBSCRIPTION_ID $azureAplicationId = $env:AZURE_CLIENT_ID $azurePassword = ConvertTo-SecureString $env:AZURE_CLIENT_SECRET -AsPlainText -Force $credentials = New-Object System.Management.Automation.PSCredential($azureAplicationId, $azurePassword) try { Connect-AzAccount -Credential $credentials -TenantId $tenantID -ServicePrincipal -ErrorAction Stop # 切换到目标订阅 Set-AzContext -Subscription $subscriptionID -ErrorAction Stop # 示例:执行后续Azure操作 Get-AzResourceGroup } catch { Write-Error $_.Exception.Message exit 1 } - 容器化实现:基于.NET7官方镜像构建,安装PowerShell与指定版本的Az.Accounts模块,Dockerfile示例:
FROM mcr.microsoft.com/dotnet/runtime:7.0 # 安装PowerShell(Ubuntu环境) RUN apt-get update && apt-get install -y --no-install-recommends \ wget \ apt-transport-https \ software-properties-common && \ wget -q https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb && \ dpkg -i packages-microsoft-prod.deb && \ apt-get update && \ apt-get install -y --no-install-recommends powershell && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* # 安装Az.Accounts模块 RUN pwsh -Command "Install-Module -Name Az.Accounts -RequiredVersion 2.13.0 -Force -Scope AllUsers -Repository PSGallery" # 复制发布后的应用程序 WORKDIR /app COPY ./publish . # 环境变量(生产环境建议通过K8s Secrets或Docker Secrets传递) ENV AZURE_TENANT_ID="" ENV AZURE_SUBSCRIPTION_ID="" ENV AZURE_CLIENT_ID="" ENV AZURE_CLIENT_SECRET="" ENTRYPOINT ["dotnet", "YourWorkerService.dll"]
内容的提问来源于stack exchange,提问作者jacknova
相关产品推荐
相关产品推荐

