我在Azure Powershell(发布管道)中运行的Powershell脚本中根本没有我需要的东西吗?

时间:2019-07-16 23:21:33

标签: powershell azure-devops

我已经编写了一个在Azure管道中使用的PowerShell模块,该模块会将SSL证书绑定到自定义主机名。我能够使模块在本地工作,包括在管道中用于初始化模块的内联脚本。在本地运行脚本时,没有任何错误。当我在管道中使用相同的脚本时,收到以下错误:

2019-07-16T23:00:40.3007294Z ##[error]Parameter set cannot be resolved using the specified named parameters.

我没有使用参数集,所以不确定为什么会抱怨。我能够在本地而不是在发布管道中执行代码的原因是什么?参数设置错误确实是对其他问题的抱怨吗?

同样,我已经在本地测试过。我所有的参数都是必需的,所以我没有指定ParameterSet,但是我确实设置了一个以防万一,并且遇到了同样的错误。

这是我成功导入模块后在发布管道中使用Azure Powershell任务使用的脚本。我知道我的变量声明是正确的,因为我已经对其进行了测试,并且它们可以很好地输出(在本地和管道中):

当任务在脚本中单击此行时发生错误: Enable-SslStateOnWebapp -WebappName $webappName -customWebappHostname $webAppCustomHostname -existingKeyvaultName $existingVaultName -existingKeyvaultCertName $certName

$myVars = '$(armDeploymentOutput)' | ConvertFrom-Json
Write-Host "The following variables are available: $($myVars)" -Verbose
$existingVaultName = $myVars.existingKeyVaultName.value
$webappName=$myVars.webappName.value
$webAppCustomHostname=$myVars.webAppCustomHostname.value
$certName=$myVars.existingKeyVaultCertificateName.value

if ($webappName -and $webAppCustomHostname -and $existingVaultName -and $certName) {
    Write-Host "Attempting to enable SSL Binding for $($webappName) on the hostname $($webAppCustomHostname) using cert $($certName) from the existing keyvault of $($existingVaultName)." -Verbose
    Enable-SslStateOnWebapp -WebappName $webappName -customWebappHostname $webAppCustomHostname -existingKeyvaultName $existingVaultName -existingKeyvaultCertName $certName
}
else {
    Write-Host "Insufficient parameters have been provided to complete SSL Binding. To enable SSL binding, please provide a custom hostname, an existing keyvault where your certificate is stored, and the name of your certificate. Please visit the readme for more information." -Verbose
}

这是已初始化的PowerShell模块:

function Enable-SslStateOnWebapp {
    param (
        [Parameter(
            Mandatory = $true,
            HelpMessage = 'A webapp name is required.')]
        [ValidateNotNullOrEmpty()]
        [string] $WebappName,

        [PARAMETER(
            Mandatory = $true,            
            HelpMessage = 'The FQDN of the custom hostname you want to bind.')]
        [ValidateNotNullOrEmpty()]
        [string] $customWebappHostname,

        [Parameter(
            Mandatory = $true,
            HelpMessage = 'A name for an existing Keyvault is required.')]
        [ValidateNotNullOrEmpty()]
        [string] $existingKeyvaultName,

        [PARAMETER(
            Mandatory = $true,            
            HelpMessage = 'A name of the pfx certificate stored in the pre-existing keyvault')]
        [ValidateNotNullOrEmpty()]
        [string] $existingKeyVaultCertName
    )
    #getting webapp resources
    $webapp = Get-AzureRmResource -Name $webappName
    #obtaining resource group resources through the use of resource group name tied to webapp
    $rg = Get-AzureRmResource -ResourceGroupName $webapp.ResourceGroupName 

...

}

我的预期结果是构建管道将执行脚本而不会出错。相反,我在本地传递结果(这显然使得调试起来很困难,然后在管道中获得以下调试日志记录:

2019-07-16T23:00:39.1496157Z ##[debug]Caught exception from task script.
2019-07-16T23:00:39.1536232Z ##[debug]Error record:
2019-07-16T23:00:39.1993172Z ##[debug]Enable-SslStateOnWebapp : Parameter set cannot be resolved using the specified named parameters.
2019-07-16T23:00:40.2927954Z ##[debug]At D:\agent3\_work\_temp\7be280f0-5905-4e05-99e0-972c90739a12.ps1:13 char:5
2019-07-16T23:00:40.2930113Z ##[debug]+     Enable-SslStateOnWebapp -WebappName $webappName -customWebappHost ...
2019-07-16T23:00:40.2940404Z ##[debug]+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2019-07-16T23:00:40.2940886Z ##[debug]    + CategoryInfo          : InvalidArgument: (:) [Enable-SslStateOnWebapp],     ParameterBindingException
2019-07-16T23:00:40.2941287Z ##[debug]    + FullyQualifiedErrorId : AmbiguousParameterSet,Enable-SslStateOnWebapp
2019-07-16T23:00:40.2941647Z ##[debug] 
2019-07-16T23:00:40.2941968Z ##[debug]Script stack trace:
2019-07-16T23:00:40.2942368Z ##[debug]at Enable-SslStateOnWebapp, D:\agent3\_work\r6\a\_infra-grs-referenceapp\drop\pwsh-modules\grs-arm\enable-ssl_state_on_webapp\enable-ssl_state_on_webapp.ps1: line 64

我检查是否存在隐藏的Unix字符,因为我是在Mac上本地开发的,所以没有:

Unix-hidden character check

1 个答案:

答案 0 :(得分:0)

TLDR;此问题是由本地开发环境中使用的版本与AzureDevops构建代理使用的版本之间的不兼容引起的。检查构建代理版本,并确保它们与您开发的版本相同。

我从这个post的答案中得到启发。

该错误从脚本的第64行抛出(这是脚本的第一个可执行行):

2019-07-16T23:00:39.1496157Z ##[debug]Caught exception from task script.
2019-07-16T23:00:39.1536232Z ##[debug]Error record:
2019-07-16T23:00:39.1993172Z ##[debug]Enable-SslStateOnWebapp : Parameter set cannot be resolved using the specified named parameters.
2019-07-16T23:00:40.2927954Z ##[debug]At D:\agent3\_work\_temp\7be280f0-5905-4e05-99e0-972c90739a12.ps1:13 char:5
2019-07-16T23:00:40.2930113Z ##[debug]+     Enable-SslStateOnWebapp -WebappName $webappName -customWebappHost ...
2019-07-16T23:00:40.2940404Z ##[debug]+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2019-07-16T23:00:40.2940886Z ##[debug]    + CategoryInfo          : InvalidArgument: (:) [Enable-SslStateOnWebapp],     ParameterBindingException
2019-07-16T23:00:40.2941287Z ##[debug]    + FullyQualifiedErrorId : AmbiguousParameterSet,Enable-SslStateOnWebapp
2019-07-16T23:00:40.2941647Z ##[debug] 
2019-07-16T23:00:40.2941968Z ##[debug]Script stack trace:
2019-07-16T23:00:40.2942368Z ##[debug]at Enable-SslStateOnWebapp, D:\agent3\_work\r6\a\_infra-grs-referenceapp\drop\pwsh-modules\grs-arm\enable-ssl_state_on_webapp\enable-ssl_state_on_webapp.ps1: line 64

鉴于它是脚本的第一行可执行代码,因此我认为错误是由于函数上的参数绑定错误地导致的,尤其是因为第63行未写入主机。

Write-Host "Attempting to get webapp resource..." -Verbose

我发现事实并非如此。我观察到,如果下一行失败,有时可能不会调用Write-Host。

在本地开发,我正在使用AzureRM v6.13.1。如果我看我在第64行调用的函数,则此函数为:

$webapp = Get-AzureRmResource -Name $webappName

查看此cmdlet的documentation (v6.13.1)

Get-AzureRmResource
   [[-Name] <String>]
   [-ResourceType <String>]
   [-ODataQuery <String>]
   [-ResourceGroupName <String>]
   [-TagName <String>]
   [-TagValue <String>]
   [-ExpandProperties]
   [-ApiVersion <String>]
   [-Pre]
   [-DefaultProfile <IAzureContextContainer>]
   [<CommonParameters>]

和我的构建代理(〜v4.6)上的版本的文档:

Get-AzureRmResource
   [-ResourceName <String>]
   [-ResourceType <String>]
   [-ExtensionResourceName <String>]
   [-ExtensionResourceType <String>]
   [-ExpandProperties]
   [-IsCollection]
   [-Top <Int32>]
   [-ODataQuery <String>]
   [-TenantLevel]
   [-ApiVersion <String>]
   [-Pre]
   [-DefaultProfile <IAzureContextContainer>]
   [<CommonParameters>]

我们可以看到-Name-ResourceName参数是不同的。这将导致AmbiguousParameterSet错误。

解决方案: 我们特定的构建代理是本地的,不会像Microsoft托管的代理那样定期更新。

我使用标准的powershell任务强制更新了构建代理的AzureRM版本:

- task: PowerShell@2
 inputs:
 targetType: 'inline'
 script: 'Install-PackageProvider -Name NuGet -Force -Scope CurrentUser;
 Install-Module -Name AzureRM -RequiredVersion 6.13.1 -Force -Scope CurrentUser -AllowClobber;'

然后在后续任务中使用我的脚本调用Get-Module,并在任务的preferredAzurePowerShellVersion部分中指定了版本6.13.1(如果所需的版本在代理上不可用,则会导致错误version not available,因此为什么要运行上一个PowerShell任务。

- task: AzurePowerShell@3
 inputs:
 azureSubscription: '<subscription>'
 ScriptType: 'InlineScript'
 Inline: 'Get-Module AzureRm;
 Import-Module $(System.DefaultWorkingDirectory)\drop\pwsh-modules\grs-arm;
 $myVars = '$(armDeploymentOutput)' | ConvertFrom-Json
 Write-Host "The following variables are available: $($myVars)" -Verbose

 $existingVaultName = $myVars.existingKeyVaultName.value
 $webappName=$myVars.webappName.value
 $webAppCustomHostname=$myVars.webAppCustomHostname.value
 $certName=$myVars.existingKeyVaultCertificateName.value

 Write-Host "Setting an access policy for the SPN to $($existingVaultName)" -Verbose
 Set-AzureRmKeyVaultAccessPolicy -VaultName $existingVaultName -ServicePrincipalName <spnClientId> -PermissionsToCertificates get -PermissionsToSecrets get

 if ($webappName -and $webAppCustomHostname -and $existingVaultName -and $certName) 
 {Write-Host "Attempting to enable SSL Binding for $($webappName) on the hostname 
 $($webAppCustomHostname) using cert $($certName) from the existing keyvault of 
 $($existingVaultName)." -Verbose
 Enable-SslStateOnWebapp -WebappName $webappName -customWebappHostname 
 $webAppCustomHostname -existingKeyvaultName $existingVaultName - 
 existingKeyvaultCertName $certName -Verbose}
 else {Write-Host "Insufficient parameters have been provided to complete SSL 
 Binding. To enable SSL binding, please provide a custom hostname, an existing 
 keyvault where your certificate is stored, and the name of your certificate. 
 Please visit the readme for more information." -Verbose}

 Write-Host "Removing SPN access to $($existingVaultName)" -Verbose
 Remove-AzureRmKeyVaultAccessPolicy -VaultName $existingVaultName - 
 ServicePrincipalName <spnClientId>
 preferredAzurePowerShellVersion: '6.13.1'

这完全解决了我的问题。