Piero Negri
4 min readOct 26, 2023

Migrating Secrets Between Azure Key Vaults with PowerShell

The image represents the process of migrating secrets between Azure Key Vaults using PowerShell. It’s a conceptual image that symbolizes the transfer of data, represented by glowing lines or streams of light, moving from one point (symbolizing the source Azure Key Vault) to another (symbolizing the destination Azure Key Vault). The use of PowerShell is symbolized by a command prompt icon or similar imagery. Overall, the image conveys a sense of movement and secure data transfer.
This image was generated with the help of an AI developed by OpenAI (Bing Image Creator)

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.

Piero Negri

storyteller, performer and geek. Not always in that order.