簡體   English   中英

使用 Connect-AzAccount 服務主體通過身份驗證從 dotnet 中調用 PowerShell 腳本

[英]Invoking PowerShell script from within dotnet with authentication using Connect-AzAccount service principal

使用 dotnet7 后台工作者,調用 PowerShell

 using PowerShell ps = PowerShell.Create();
 ps.AddScript("auth.ps1"); 
 var pipelineObjects = await ps.InvokeAsync();

使用 Az.Accounts verison 2.2.3 的最小 PowerShell 代碼

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: Entry point was not found.
                           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)
                        --- End of stack trace from previous location ---
                           at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
                           at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
                        --- End of stack trace from previous location ---
                           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       : At line:15 char:6
                        +      Connect-AzAccount -Credential $credentials -TenantId $tenantID - .
                        +      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PSScriptRoot          :
PSCommandPath         :
InvocationName        : Connect-AzAccount
PipelineLength        : 0
PipelinePosition      : 0
ExpectingInput        : False
CommandOrigin         : Internal
DisplayScriptPosition :

需要執行 PowerShell 腳本,以便我可以在同一個 PowerShell 腳本中執行經過身份驗證的 PowerShell 命令。 它是一個 dotnet worker,它監聽服務總線,然后執行 PowerShell。 最終會被容器化

我創建了一個控制台應用程序:-

在此處輸入圖像描述

從 Azure 門戶復制 SubscriptionID。

在訂閱級別分配我的服務主要貢獻者角色,以便它在訂閱級別執行任務並讀取、寫入訂閱。

在我的訂閱 > 訪問控制 (IAM) -> 角色分配 > 授予 SP 的貢獻者訪問權限中。

在此處輸入圖像描述

您可以通過單擊訪問控制 (IAM) 頁面中的“添加角色分配”>“選擇角色貢獻者”>“選擇成員”>“您的 SP”>“選擇”>“審核 + 創建”來提供對您的 SP 的貢獻者訪問權限。

在此處輸入圖像描述

從這里獲取 SP 租戶 ID 和應用程序 ID:-

在此處輸入圖像描述

在 Powershell 命令中添加這些參數。

在 VisualStudio 中創建了一個簡單的控制台應用程序。

在此處輸入圖像描述

安裝了 Microsoft.Powershell.SDK NuGet 包 7.21.1 版本。

在此處輸入圖像描述

在 VS studio 的調試 > 常規設置中禁用啟用僅我的代碼。

在此處輸入圖像描述

從 Program.cs 中的 .net 控制台應用程序運行 Powershell 的簡單程序:

using System.Diagnostics;
using System.Management.Automation.Runspaces;
using System.Management.Automation;
using System.Xml.Linq;
using System;

var initialState = InitialSessionState.CreateDefault2();
initialState.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.Unrestricted;

using  var ps = PowerShell.Create(initialState);

var results = ps.AddScript("\r\nInstall-Module Az.Accounts\r\nInstall-Module Az.esources\r\nImport-Module Az.Accounts\r\nImport-Module Az.Resources\r\n\r\nClear-AzContext -Force \r\n\r\n$tenantID = \"83331f4e-7f45-4ce4-99ed-af9038592395\" \r\n$subscriptionID = \"0151c365-f598-44d6-b4fd-e2b6e97cb2a7\"\r\n\r\n $azureAplicationId = \"c0c952e9-5254-45b5-b838-6d26a31435cb\";\r\n $azurePassword = ConvertTo-SecureString \"Mom8Q~AX1xc9OlrUislxBJvTvbfUKuWtpO9gadfE\" -AsPlainText -Force; \r\n $credentials = New-Object System.Management.Automation.PSCredential($azureAplicationId, $azurePassword); \r\n\r\ntry \r\n{ \r\n Connect-AzAccount -Credential $credentials -TenantId $tenantID -ServicePrincipal -ErrorAction Stop\r\n New-AzResourceGroup -Name RG05 -Location \"South Central US\"\r\n}\r\ncatch \r\n{ \r\n Write-Error $Exception ; \r\n}\r\n").Invoke();

通過上面的代碼,我能夠使用服務主體成功連接到我的 Azure 帳戶,我還添加了一個命令來使用服務主體創建資源組,並且資源組是在構建成功后在 Azure 門戶上創建的。

在 PowerShell 中添加了這些代碼行,以便在導入它們之前先安裝 PowerShell 模塊。


Install-Module  Az.Accounts
Install-Module  Az.Resources
Import-Module  Az.Accounts
Import-Module  Az.Resources

添加了一個在 Azure 門戶中創建新資源組的命令,以驗證服務主體是否在 Azure 中驗證和創建資源。

在此處輸入圖像描述

在此處輸入圖像描述

PowerShell 命令在本地成功運行,並在 Azure 門戶上創建了資源組 RG03。

在此處輸入圖像描述

現在,我通過 .NET 控制台應用程序運行了相同的命令,構建成功地向 Azure 進行了身份驗證並創建了一個 RG。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM