VSTS Build and PowerShell and AzureAD Authenticati

2020-03-03 07:12发布

I have a VSTS project connected via a Service Principal to an Azure subscription through an Azure Resource Manager endpoint. This works fine for my builds that configure ARM resources via templated, parameter driven deployments.

I have an additional requirement to set up Azure AD groups as part of the build. I have a script that works fine from my local machine. When I deployed it via the build and it executed on the hosted build controller, the script could initially not find the AzureAD module. I got around this by including the script in git Repo and accessing it through:

$adModulePath = $PSScriptRoot + "\PsModules\AzureAD\2.0.0.131\AzureAD.psd1"
Import-Module $adModulePath 

However, I now have another problem when it comes to running New-AzureADGroup. The script requires Connect-AzureAD to be run before the command is issued. This works fine by hardcoding a credential but I don't want to do this, I want it to run under the context of the SPN created, which is running the scripts on the hosted build controller.

So, the question is, can I get the current context of the Azure PowerShell execution SPN and pass that to Connect-AzureAD to avoid storing credential in plain text? Am I missing a trick? Are there any alternatives?

My current code is as below, the commented connection works fine from the command like with hard coded values. The call with no parameters presents the login UI which terminates the build since it is obviously not interactive.

## Login to Azure
#$SecurePassword = ConvertTo-SecureString $AdminPassword -AsPlainText -Force
#$AdminCredential = New-Object System.Management.Automation.PSCredential ($AdminUserEmailAddress, $SecurePassword)
#Connect-AzureAD -Credential $AdminCredential

Connect-AzureAD

Write-Output "------------------ Start: Group Creation ------------------"

$TestForAdminGroup = Get-AzureADGroup -SearchString $AdminGroup
$TestForContributorGroup = Get-AzureADGroup -SearchString $ContributorGroup
$TestForReaderGroup = Get-AzureADGroup -SearchString $ReaderGroup

Thanks

3条回答
祖国的老花朵
2楼-- · 2020-03-03 07:53

To conclude, the Powershell module can’t share the same context and you need to store the credential in secret variable in VSTS.

查看更多
何必那么认真
3楼-- · 2020-03-03 08:01

To take this further, it is possible to use the Service Principal by following example 3 here:

https://docs.microsoft.com/en-us/powershell/module/azuread/connect-azuread?view=azureadps-2.0

Once you have created a self-signed cert and attached it, you can connect to the Azure AD by passing in the thumbprint of the cert along with a couple of other parameters:

Connect-AzureAD -TenantId $tenantId -ApplicationId $sp.AppId -CertificateThumbprint $thumb

查看更多
时光不老,我们不散
4楼-- · 2020-03-03 08:06

This is possible. Got it working today for my own VSTS extension that I released a while ago. My extension is using a Azure Resource Manager endpoint as input.

Running it now on a Microsoft Hosted Visual Studio 2017 agent pool using the below code. See for more information my post on how to use AzureAD PowerShell cmdlets on VSTS agent.

Write-Verbose "Import AzureAD module because is not on default VSTS agent"
$azureAdModulePath = $PSScriptRoot + "\AzureAD\2.0.1.16\AzureAD.psd1"
Import-Module $azureAdModulePath 

# Workaround to use AzureAD in this task. Get an access token and call Connect-AzureAD
$serviceNameInput = Get-VstsInput -Name ConnectedServiceNameSelector -Require
$serviceName = Get-VstsInput -Name $serviceNameInput -Require
$endPointRM = Get-VstsEndpoint -Name $serviceName -Require

$clientId = $endPointRM.Auth.Parameters.ServicePrincipalId
$clientSecret = $endPointRM.Auth.Parameters.ServicePrincipalKey
$tenantId = $endPointRM.Auth.Parameters.TenantId

$adTokenUrl = "https://login.microsoftonline.com/$tenantId/oauth2/token"
$resource = "https://graph.windows.net/"

$body = @{
    grant_type    = "client_credentials"
    client_id     = $clientId
    client_secret = $clientSecret
    resource      = $resource
}

$response = Invoke-RestMethod -Method 'Post' -Uri $adTokenUrl -ContentType "application/x-www-form-urlencoded" -Body $body
$token = $response.access_token

Write-Verbose "Login to AzureAD with same application as endpoint"
Connect-AzureAD -AadAccessToken $token -AccountId $clientId -TenantId $tenantId
查看更多
登录 后发表回答