Migrating Secrets Between Azure Key Vaults with PowerShell
When managing secrets in Azure, you might find yourself needing to copy secrets from one Key Vault to another. This could be due to various reasons such as migrating to a new environment, creating backups, or setting up replication for disaster recovery. While Azure doesn’t provide a built-in way to do this, we can accomplish it using PowerShell.
In this post, we’ll walk through a PowerShell script that copies secrets from one Azure Key Vault to another. This script is flexible and allows you to copy all secrets or a subset of secrets.
The script is available at this GitHub repository
Please note: While I’ve put a lot of effort into this script, it’s possible that there might be some bugs. I strongly recommend trying it out in a test environment first. If you encounter any issues, I’d be more than happy to hear from you and work on resolving them. Your feedback is invaluable in making this tool better! 🛠️
Acknowledgements
The foundation of this script was inspired by the following resources:
and especially
These resources provided an excellent starting point for developing a script to copy secrets between Azure Key Vaults.
Additional Features
The script discussed in this blog post has been enhanced with additional features:
- Selective Copying of Secrets: This feature allows users to specify an array of secret names to copy, giving users more control over what secrets are copied.
- Default Secret Value Placeholder: The $defaultSecretValue parameter allows setting a default value for the secrets that are not copied from the source Key Vault. If not provided, it defaults to ‘Needs Configuration’.
- Force Override: The Force switch, if present, allows secrets in the source Key Vault to override those in the destination Key Vault with the same name.
- Improved Secret Tags Management: The script handles secret tags in a more precise and effective way. It allows adding the following tags:
- Migrated=’true’
- SourceVault=SourceKeyVaultName
- sourceSecretVersionMigrated=secret.Version or “N/A” if a default secret placeholder is used
- ValueMigrated=’true’ if a default secret placeholder is used, ‘false’ otherwise.
These enhancements make the script more flexible and powerful, providing users with more options and control when copying secrets between Azure Key Vaults.
Script Overview
The script connects to Azure and retrieves the secrets from the source Key Vault. It then copies these secrets to the destination Key Vault. You can specify a subset of secrets to copy using the -SecretArrayInput parameter, or copy all secrets using the -AllKeyVaultSecrets switch.
Here are the parameters used in the script:
- SourceSubscriptionName: The name of the source subscription.
- SourceResourceGroupName: The name of the resource group of the source Key Vault.
- SourceKeyVaultName: The name of the source Key Vault.
- DestSubscriptionName: The name of the destination subscription. If not set or blank then same subscription given in SourceSubscriptionName assumed.
- DestResourceGroupName: The name of the resource group of the destination Key Vault. If not set or blank then same resource group given in SourceResourceGroupName is assumed.
- DestKeyVaultName: The name of the destination Key Vault. If not set or blank then same subscription is assumed.
- SecretArrayInput: An array of secret names to copy. Cannot be used with -AllKeyVaultSecrets.
- AllKeyVaultSecrets: If this switch is present, all secrets will be copied. Cannot be used with -SecretArrayInput.
- NameOnly: If this switch is present, the secret value will be set to the value present in DefaultSecretValue parameter. sourceSecretVersionMigrated will be assigned value “N/A”
- DefaultSecretValue: The default value for secrets when NameOnly is present. Defaults to ‘Needs Configuration’ if not provided.
- DoNotEnhanceSecretTag: If this switch is NOT present, to the source secret tag will be added the following tags: -Migrated=’true’, -SourceVault=SourceKeyVaultName, -sourceSecretVersionMigrated=secret.Version or “N/A” if NameOnly is present, -ValueMigrated to ‘true’ if NameOnly is not present and to ‘false’ vice versa.
- Force: If this switch is present, secrets in SourceKeyVaultName will override those in DestKeyVaultName with the same name.
Next, it connects to Azure using Connect-AzAccount.
Finally, it loops over each secret in the source list. For each secret, it retrieves the secret value from the source Key Vault and sets it in the destination Key Vault.
Running the Script
To run the script, save it as a .ps1 file and run it from your PowerShell command line. Be sure to replace $SourceVaultName, $DestVaultName, and $SecretArrayInput with your actual values.
Here’s an example command:
.\CopyKeyVaultSecrets.ps1 -SourceSubscriptionName ‘source-suscriptionName’ -SourceResourceGroupName ‘source-groupName’ -SourceKeyVaultName ‘source-vault’ -DestKeyVaultName ‘dest-vault’ -SecretArrayInput ‘secret1’, ‘secret2’
This command copies the secrets named ‘secret1’ and ‘secret2’ from ‘source-vault’ to ‘dest-vault’. If they exists in destKeyVaultName they will be skipped because Force parameter is not present.
Conclusion
This PowerShell script provides a flexible way to copy secrets between Azure Key Vaults. Whether you need to copy all secrets or just a subset, this script has you covered.
I hope you find this blog post helpful! Let me know if you have any questions or feedback.