Azure凭据尚未设置或已过期,请运行Connect-AzAccount [英] Azure credentials have not been set up or have expired, please run Connect-AzAccount

查看:133
本文介绍了Azure凭据尚未设置或已过期,请运行Connect-AzAccount的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与以下问题有关( Azure DevOps-自定义任务-PowerShell使用Azure身份验证),我现在正在使用Connect-AzAccount通过Azure DevOps自定义任务登录.

在下一步中,我想并行运行多个作业以首先进行操作,然后通过模板部署某些Azure资源.使用AzureRM可以正常工作,但是切换到Az后我总是会收到错误消息

您的Azure凭据尚未设置或已过期,请 运行Connect-AzAccount来设置您的Azure凭据.

我已经将Az模块更新为最新版本.

这是我的方法:

身份验证

try {
    $endpoint = Get-VstsEndpoint -Name $serviceName -Require
    if (!$endpoint) {
        throw "Endpoint not found..."
    }
    $subscriptionId = $endpoint.Data.SubscriptionId
    $tenantId = $endpoint.Auth.Parameters.TenantId
    $servicePrincipalId = $endpoint.Auth.Parameters.servicePrincipalId
    $servicePrincipalKey = $endpoint.Auth.Parameters.servicePrincipalKey

    $spnKey = ConvertTo-SecureString $servicePrincipalKey -AsPlainText -Force
    $credentials = New-Object System.Management.Automation.PSCredential($servicePrincipalId,$spnKey)

    Connect-AzAccount -ServicePrincipal -TenantId $tenantId -Credential $credentials
    Select-AzSubscription -SubscriptionId $subscriptionId -Tenant $tenantId

    $ctx = Get-AzContext
    Write-Host "Connected to subscription '$($ctx.Subscription)' and tenant '$($ctx.Tenant)'..."
} catch {
    Write-Host "Authentication failed: $($_.Exception.Message)..." 
}

并行部署

foreach ($armTemplateFile in $armTemplateFiles) {
    $logic = {
        Param(
            [object] 
            [Parameter(Mandatory=$true)]
            $ctx,

            [object] 
            [Parameter(Mandatory=$true)]
            $armTemplateFile,

            [string] 
            [Parameter(Mandatory=$true)]
            $resourceGroupName
        )

        ####################################################################
        # Functions
        function Format-ValidationOutput {
            param ($ValidationOutput, [int] $Depth = 0)
            Set-StrictMode -Off
            return @($ValidationOutput | Where-Object { $_ -ne $null } | ForEach-Object { @('  ' * $Depth + ': ' + $_.Message) + @(Format-ValidationOutput @($_.Details) ($Depth + 1)) })
        }

        ####################################################################
        # Logic

        # Some template manipulation


        $paramFileContent | ConvertTo-Json -Depth 100 | Set-Content -Path $paramTemplateFile.FullName
        $templateFileContent | ConvertTo-Json -Depth 100 | Set-Content -Path $armTemplateFile.FullName

        ####################################################################
        # Test Deployment
        $ErrorMessages = Format-ValidationOutput (Test-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName `
                                                                                        -TemplateFile $armTemplateFile.FullName `
                                                                                        -TemplateParameterFile $paramTemplateFile.FullName `
                                                                                        -DefaultProfile $ctx)
        if ($ErrorMessages) {
            Write-Host '', 'Validation returned the following errors:', @($ErrorMessages), '', 'Template is invalid.'
        }
        else { # Deploy

            New-AzResourceGroupDeployment -Name (($armTemplateFile.Name).Split(".")[0] + ((Get-Date).ToUniversalTime()).ToString('MMddHHmm')) `
                                                -ResourceGroupName $resourceGroupName `
                                                -TemplateFile $armTemplateFile.FullName `
                                                -TemplateParameterFile $paramTemplateFile.FullName `
                                                -Force `
                                                -ErrorVariable ErrorMessages `
                                                -DefaultProfile $ctx
            if ($ErrorMessages) {
                Write-Host '', 'Template deployment returned the following errors:', @(@($ErrorMessages) | ForEach-Object { $_.Exception.Message.TrimEnd("`r`n") })
            }
        }
    }
    Start-Job $logic -ArgumentList (Get-AzContext), $armTemplateFile, $ResourceGroupName
}

While (Get-Job -State "Running")
{
    Start-Sleep 10
    Write-Host "Jobs still running..."
}

Get-Job | Receive-Job

解决方案

由于某种原因(我不知道),将上下文传递给后台作业不再有效,因为移至Az模块(也是最新的模块)版本(1.4.0)).我尝试使用Save-AzContextImport-AzContext或通过Get-AzContext获取上下文并将其传递到后台作业(使用Set-AzContext或直接使用-DefaultProfile(此方法与AzureRm模块一起使用)).

现在对我有用的解决方法是分别对每个后台作业进行身份验证.

有关职位定义:

foreach ($armTemplateFile in $armTemplateFiles) {
    $logic = {
        Param(
            [object] 
            [Parameter(Mandatory=$true)]
            $endpointInput,

            [object] 
            [Parameter(Mandatory=$true)]
            $armTemplateFile,

            [string] 
            [Parameter(Mandatory=$true)]
            $resourceGroupName
        )

        ###########################
        #Login
        Write-Host "Authenticating..."
        try {
            $endpoint = $endpointInput
            if (!$endpoint) {
                throw "Endpoint not found..."
            }
            $subscriptionId = $endpoint.Data.SubscriptionId
            $tenantId = $endpoint.Auth.Parameters.TenantId
            $servicePrincipalId = $endpoint.Auth.Parameters.servicePrincipalId
            $servicePrincipalKey = $endpoint.Auth.Parameters.servicePrincipalKey

            $spnKey = ConvertTo-SecureString $servicePrincipalKey -AsPlainText -Force
            $credentials = New-Object System.Management.Automation.PSCredential($servicePrincipalId,$spnKey)

            Connect-AzAccount -ServicePrincipal -TenantId $tenantId -Credential $credentials
            Select-AzSubscription -SubscriptionId $subscriptionId -Tenant $tenantId

            $ctx = Get-AzContext
            Write-Host "Connected to subscription '$($ctx.Subscription)' and tenant '$($ctx.Tenant)'..."
        } catch {
            Write-Host "Authentication failed: $($_.Exception.Message)..." 
        }

开始工作:

Start-Job $logic -Name $jobName -ArgumentList $endpoint, $armTemplateFile, $ResourceGroupName

Related to the following question (Azure DevOps - Custom Task - PowerShell with Azure Authentification) I am using now Connect-AzAccount to login by using a Azure DevOps Custom Task.

In the next step I want to run multiple jobs in parallel to first manipulate and then deploy certain Azure resources via templates. Working with AzureRM this worked without problems but after switching to Az I always get the error

Your Azure credentials have not been set up or have expired, please run Connect-AzAccount to set up your Azure credentials.

I already updated the Az modules to the most current version.

Here is how I do it:

Authenticate

try {
    $endpoint = Get-VstsEndpoint -Name $serviceName -Require
    if (!$endpoint) {
        throw "Endpoint not found..."
    }
    $subscriptionId = $endpoint.Data.SubscriptionId
    $tenantId = $endpoint.Auth.Parameters.TenantId
    $servicePrincipalId = $endpoint.Auth.Parameters.servicePrincipalId
    $servicePrincipalKey = $endpoint.Auth.Parameters.servicePrincipalKey

    $spnKey = ConvertTo-SecureString $servicePrincipalKey -AsPlainText -Force
    $credentials = New-Object System.Management.Automation.PSCredential($servicePrincipalId,$spnKey)

    Connect-AzAccount -ServicePrincipal -TenantId $tenantId -Credential $credentials
    Select-AzSubscription -SubscriptionId $subscriptionId -Tenant $tenantId

    $ctx = Get-AzContext
    Write-Host "Connected to subscription '$($ctx.Subscription)' and tenant '$($ctx.Tenant)'..."
} catch {
    Write-Host "Authentication failed: $($_.Exception.Message)..." 
}

Deploy in parallel

foreach ($armTemplateFile in $armTemplateFiles) {
    $logic = {
        Param(
            [object] 
            [Parameter(Mandatory=$true)]
            $ctx,

            [object] 
            [Parameter(Mandatory=$true)]
            $armTemplateFile,

            [string] 
            [Parameter(Mandatory=$true)]
            $resourceGroupName
        )

        ####################################################################
        # Functions
        function Format-ValidationOutput {
            param ($ValidationOutput, [int] $Depth = 0)
            Set-StrictMode -Off
            return @($ValidationOutput | Where-Object { $_ -ne $null } | ForEach-Object { @('  ' * $Depth + ': ' + $_.Message) + @(Format-ValidationOutput @($_.Details) ($Depth + 1)) })
        }

        ####################################################################
        # Logic

        # Some template manipulation


        $paramFileContent | ConvertTo-Json -Depth 100 | Set-Content -Path $paramTemplateFile.FullName
        $templateFileContent | ConvertTo-Json -Depth 100 | Set-Content -Path $armTemplateFile.FullName

        ####################################################################
        # Test Deployment
        $ErrorMessages = Format-ValidationOutput (Test-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName `
                                                                                        -TemplateFile $armTemplateFile.FullName `
                                                                                        -TemplateParameterFile $paramTemplateFile.FullName `
                                                                                        -DefaultProfile $ctx)
        if ($ErrorMessages) {
            Write-Host '', 'Validation returned the following errors:', @($ErrorMessages), '', 'Template is invalid.'
        }
        else { # Deploy

            New-AzResourceGroupDeployment -Name (($armTemplateFile.Name).Split(".")[0] + ((Get-Date).ToUniversalTime()).ToString('MMddHHmm')) `
                                                -ResourceGroupName $resourceGroupName `
                                                -TemplateFile $armTemplateFile.FullName `
                                                -TemplateParameterFile $paramTemplateFile.FullName `
                                                -Force `
                                                -ErrorVariable ErrorMessages `
                                                -DefaultProfile $ctx
            if ($ErrorMessages) {
                Write-Host '', 'Template deployment returned the following errors:', @(@($ErrorMessages) | ForEach-Object { $_.Exception.Message.TrimEnd("`r`n") })
            }
        }
    }
    Start-Job $logic -ArgumentList (Get-AzContext), $armTemplateFile, $ResourceGroupName
}

While (Get-Job -State "Running")
{
    Start-Sleep 10
    Write-Host "Jobs still running..."
}

Get-Job | Receive-Job

解决方案

For some reason (I don't know) passing the context to a background job does not work anymore since moving to the Az modules (also with the most current version (1.4.0)). I tried either using Save-AzContext with Import-AzContext or getting the context via Get-AzContext and passing it to the background job (with Set-AzContext or directly using -DefaultProfile (this approach worked with the AzureRm modules)).

A workaround that works for me now is to authenticate each background job individually.

For the job definition:

foreach ($armTemplateFile in $armTemplateFiles) {
    $logic = {
        Param(
            [object] 
            [Parameter(Mandatory=$true)]
            $endpointInput,

            [object] 
            [Parameter(Mandatory=$true)]
            $armTemplateFile,

            [string] 
            [Parameter(Mandatory=$true)]
            $resourceGroupName
        )

        ###########################
        #Login
        Write-Host "Authenticating..."
        try {
            $endpoint = $endpointInput
            if (!$endpoint) {
                throw "Endpoint not found..."
            }
            $subscriptionId = $endpoint.Data.SubscriptionId
            $tenantId = $endpoint.Auth.Parameters.TenantId
            $servicePrincipalId = $endpoint.Auth.Parameters.servicePrincipalId
            $servicePrincipalKey = $endpoint.Auth.Parameters.servicePrincipalKey

            $spnKey = ConvertTo-SecureString $servicePrincipalKey -AsPlainText -Force
            $credentials = New-Object System.Management.Automation.PSCredential($servicePrincipalId,$spnKey)

            Connect-AzAccount -ServicePrincipal -TenantId $tenantId -Credential $credentials
            Select-AzSubscription -SubscriptionId $subscriptionId -Tenant $tenantId

            $ctx = Get-AzContext
            Write-Host "Connected to subscription '$($ctx.Subscription)' and tenant '$($ctx.Tenant)'..."
        } catch {
            Write-Host "Authentication failed: $($_.Exception.Message)..." 
        }

For starting the job:

Start-Job $logic -Name $jobName -ArgumentList $endpoint, $armTemplateFile, $ResourceGroupName

这篇关于Azure凭据尚未设置或已过期,请运行Connect-AzAccount的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆