无法将证书导入Keyvault

时间:2018-11-15 12:48:16

标签: powershell import certificate azure-keyvault

我具有以下用于将证书导入到密钥库中的powershell代码:

###############################################################################

<#
.SYNOPSIS
    Import-KeyVaultCertificate

.DESCRIPTION

    Import-KeyVaultCertificate

.PARAMETER VaultName

.PARAMETER Name

.PARAMETER Password

.PARAMETER Version

.PARAMETER DisableVersions

.NOTES
    This template allows to write secrets into the KeyVault if they are not present. If they are present, the script will ignore it.

.EXAMPLE
    Import-KeyVaultCertificate.ps1 -VaultName 'vaultname' -Name 'certificatename' -Password 'certificatepassword' -Thumbprint 'certificatethumbprint' -FilePath 'certificate.pfx'

.EXAMPLE
    Import-KeyVaultCertificate.ps1 -VaultName 'vaultname' -Name 'certificatename' -SecurePassword (ConvertTo-SecureString -String 'certificatepassword' -AsPlainText -Force) -Thumbprint 'certificatethumbprint' -FilePath 'certificate.pfx'

#>

# ' char inc as Notepad++ language recognition does not like get-help contents
##############################################################################

[CmdletBinding(DefaultParametersetname = "String")]
param (
    [Parameter(Mandatory = $true)]
    [string] $VaultName,
    [Parameter(Mandatory = $true)]
    [string] $Name,
    [Parameter(Mandatory = $true)]
    [string] $Thumbprint,
    [Parameter(Mandatory = $true)]
    [string] $FilePath,
    [Parameter(Mandatory = $true, ParameterSetName = "String")]
    [string] $Password,
    [Parameter(Mandatory = $true, ParameterSetName = "SecureString")]
    [securestring] $SecurePassword,
    [Parameter(Mandatory = $false)]
    [string] $Version,
    [Parameter(Mandatory = $false)]
    [switch] $DisableVersions
)
begin {
    $Verbose = ($PSBoundParameters['Verbose'] -eq $true) -or ($VerbosePreference -eq 'Continue')
    $KeyVaultParams = @{}
    if ($Version -ne $null) {
        $KeyVaultParams.Add('Version', $Version)
    }
}
process {
    try {
        $KeyVault = @(Get-AzureRmResource -ErrorAction Stop | Where-Object {($_.Name -eq $VaultName) -and ($_.ResourceType -eq 'Microsoft.KeyVault/vaults')})
        if ($KeyVault.count -ne 1) {
            Write-Error -Message ('KeyVault "{0}" not found - Internal Error.' -F $VaultName) -ErrorAction Stop
        }
    }
    catch {
        Write-Error -Message ('KeyVault "{0}" not found - Internal Error.' -F $VaultName) -ErrorAction Stop
    }
    $GetKeyVaultCertificate = Get-AzureKeyVaultCertificate -VaultName $VaultName -Name $Name @KeyVaultParams
    if (($GetKeyVaultCertificate -ne $null) -and ($GetKeyVaultCertificate.Name -eq $Name) -and ($GetKeyVaultCertificate.Thumbprint -eq $Thumbprint)) {
        Write-Warning -Message ('Certificate "{0}" with Thumbprint "{1}" is present in KeyVault "{2}"' -F $GetKeyVaultCertificate.Name, $GetKeyVaultCertificate.Thumbprint, $KeyVault.Name)
    }
    elseif (($GetKeyVaultCertificate -eq $null) -or (($GetKeyVaultCertificate -eq $null) -and ($GetKeyVaultCertificate.Thumbprint -ne $Thumbprint))) {
        try {
            $CatchMessage = 'Failed to upload the certificate "{0}" in key vault "{1}".'
            if ($PSCmdlet.ParameterSetName -eq 'String') {
                $SecurePassword = ConvertTo-SecureString -String $Password -AsPlainText -Force
            }
            Write-Output ($NewCertValue = Import-AzureKeyVaultCertificate -VaultName $VaultName -Name $Name -Password $SecurePassword -FilePath $FilePath -Verbose:$Verbose -ErrorAction Stop)
            if ($DisableVersions) {
                $CatchMessage = 'Unable to retrieve certificate "{0}" in key vault "{1}".'
                (Get-AzureKeyVaultCertificate -VaultName $VaultName -Name $Name -IncludeVersions | Where-Object {$_.Enabled })  | ForEach-Object {
                    if ($_.Version -ne $NewCertValue.Version) {
                        $CatchMessage = 'Failed to disable version for certificate "{0}" in key vault "{1}" [Version: ' + $_.Version + '].'
                        Set-AzureKeyVaultCertificateAttribute -VaultName $VaultName -Name $Name -Version $_.Version -Enable $false -Verbose:$Verbose -ErrorAction Stop
                    }
                }
            }
        }
        catch {
            Write-Error -Message ($CatchMessage -F $Name, $VaultName) -ErrorAction Stop
        }
    }
}

如果我尝试使用它,它会要求我提供一个版本,尽管我指定该参数不是必需的。如果删除@KeyVaultParams,我将到达catch消息中的脚本所在的位置:

'Failed to upload the certificate "{0}" in key vault "{1}".'

Get-AzureKeyVaultCertificate上进行了调试,并且它指出未找到证书,这是正确的,但是它没有转到导入它的行。 如果我使用Import-AzureKeyVaultCertificate -VaultName $VaultName -Name $Name -Password (ConvertTo-SecureString -AsPlainText -Force:$true 'xxxxxx') -FilePath 'cert.pfx' cmdlet并导入证书,则下次我使用脚本时会收到警告-这就是我想要的。表示证书在密钥库中,并且指纹匹配。

所以有2个问题: 1.版本似乎是强制性的-我该如何解决? 2.如果证书在密钥库中不存在,则不会导入-为什么?

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

好的。 同时,我发现了问题:

  1. @KeyVaultParams-我从-eq $null移除了$Version -ne $null
  2. 此处的逻辑有误:(($GetKeyVaultCertificate -eq $null) -or (($GetKeyVaultCertificate -eq $null)。应该是(($GetKeyVaultCertificate -eq $null) -or (($GetKeyVaultCertificate -ne $null)
  3. 当脚本要求输入明文密码时,我将密码解析为安全字符串。
  4. 在最后一个Write-error $_.Exception.Message之前添加了catch来查看错误,该错误是:The specified network password is not correct.

我希望这对希望以更多..幻想的方式导入证书的人们有所帮助:)