使用筛选规则跨可用区迁移Azure Key Vault机密
结论
完全可以实现仅迁移指定列表内机密的筛选功能。你找到的参考Bash脚本本身就已经带了基础的白名单筛选逻辑——开头定义的SECRETS变量就是要迁移的机密列表,脚本只会遍历这个列表里的条目做迁移,不会操作源Key Vault里的其他机密。
我对原Bash脚本做了容错优化,同时补了同功能的PowerShell版本,你可以按需选用。
优化版Bash脚本(支持机密白名单筛选)
这个版本修复了原脚本临时文件残留、特殊字符转义异常、机密不存在时直接中断的问题,你只需要修改开头配置块的三个参数即可:
SECRETS:填入需要迁移的机密名,用空格分隔,不在列表内的机密完全不会被处理SOURCE_KEYVAULT:源Key Vault名称DESTINATION_KEYVAULT:目标Key Vault名称
#!/bin/bash set -euo pipefail # -------------------------- 配置项开始 -------------------------- SECRETS="enkrs-secret-0e enkrs-secret-0a enkrs-secret-0b" SOURCE_KEYVAULT="enkrs-kv01" DESTINATION_KEYVAULT="enkrs-kv02" # -------------------------- 配置项结束 -------------------------- # 依赖预检查 if ! command -v az &> /dev/null; then echo "错误:未安装Azure CLI,请先完成安装并执行az login登录账号" exit 1 fi if ! command -v jq &> /dev/null; then echo "错误:未安装jq工具,请先安装jq用于解析接口返回的JSON数据" exit 1 fi for SECRET in $SECRETS; do echo "正在处理机密: $SECRET" # 直接读取机密信息,不生成本地临时文件避免敏感信息残留 SECRET_JSON=$(az keyvault secret show --vault-name "$SOURCE_KEYVAULT" --name "$SECRET" --output json 2>/dev/null || (echo "警告:源Key Vault中不存在机密 $SECRET,跳过" && continue)) NAME=$(echo "$SECRET_JSON" | jq --raw-output '.name') VALUE=$(echo "$SECRET_JSON" | jq --raw-output '.value') EXPIRES=$(echo "$SECRET_JSON" | jq --raw-output '.attributes.expires') DESCRIPTION=$(echo "$SECRET_JSON" | jq --raw-output '.contentType') # 动态拼接命令参数 SET_ARGS=(--vault-name "$DESTINATION_KEYVAULT" --name "$NAME" --value "$VALUE") if [ "$DESCRIPTION" != "null" ]; then SET_ARGS+=(--description "$DESCRIPTION") fi if [ "$EXPIRES" != "null" ]; then EXPIRES_FMT=$(echo "$EXPIRES" | cut -c-10) SET_ARGS+=(--expires "$EXPIRES_FMT") fi az keyvault secret set "${SET_ARGS[@]}" --output none echo "机密 $SECRET 迁移完成" done echo "所有指定列表内的机密迁移完成"
PowerShell版本(支持机密白名单筛选)
如果你习惯使用PowerShell环境,可以用下面这个版本,前置要求是已安装Az.KeyVault模块并完成Connect-AzAccount登录,同样只迁移配置列表内的机密:
# -------------------------- 配置项开始 -------------------------- $secrets = @("enkrs-secret-0e", "enkrs-secret-0a", "enkrs-secret-0b") $sourceKv = "enkrs-kv01" $destKv = "enkrs-kv02" # -------------------------- 配置项结束 -------------------------- # 依赖预检查 if (-not (Get-Module -ListAvailable Az.KeyVault)) { Write-Error "错误:未安装Az.KeyVault模块,请先执行Install-Module Az.KeyVault完成安装" exit 1 } foreach ($secretName in $secrets) { Write-Host "正在处理机密: $secretName" try { $sourceSecret = Get-AzKeyVaultSecret -VaultName $sourceKv -Name $secretName -ErrorAction Stop } catch { Write-Warning "警告:源Key Vault中不存在机密 $secretName,跳过" continue } # 解析机密属性 $secretValue = $sourceSecret.SecretValue $contentType = $sourceSecret.ContentType $expires = $sourceSecret.Expires # 写入目标Key Vault $setParams = @{ VaultName = $destKv Name = $secretName SecretValue = $secretValue } if ($contentType) { $setParams["ContentType"] = $contentType } if ($expires) { $setParams["Expires"] = $expires } Set-AzKeyVaultSecret @setParams | Out-Null Write-Host "机密 $secretName 迁移完成" } Write-Host "所有指定列表内的机密迁移完成"
使用注意事项
- 两个版本均采用白名单筛选逻辑,只有你写在配置列表里的机密才会被读取和迁移,列表外的机密不会有任何操作
- 运行脚本前请先选中正确的Azure订阅:Bash环境执行
az account set --subscription "你的订阅名/订阅ID",PowerShell环境执行Set-AzContext -Subscription "你的订阅名/订阅ID" - 脚本自带异常跳过逻辑,如果列表内填写的机密在源Key Vault不存在,会输出警告后继续处理下一个条目,不会中断整个迁移流程
- 两个版本都不会在本地生成临时文件存储机密值,避免敏感信息在磁盘残留
内容的提问来源于stack exchange,提问作者Freek Brouwer
相关产品推荐
相关产品推荐

