New-AzureRmKeyVault : 'vaultName' does not match expected pattern - azure

I am trying to set up Azure Key Vault for my application by following this tutorial: https://blogs.technet.microsoft.com/kv/2015/06/02/azure-key-vault-step-by-step/
In the Create and configure key vault section in the tutorial, Right after doing these two steps:
I am not able to do this step:
It shows error message in my PowerShell:
New-AzureRmKeyVault : 'vaultName' does not match expected pattern '^[a-zA-Z0-9-]{3,24}$'.
At line:1 char:1
+ New-AzureRmKeyVault -VaultName ProfileKeyVault -ResourceGro ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [New-AzureRmKeyVault], ValidationException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.KeyVault.NewAzureKeyVault

Try putting the vault name in quotes.
New-AzureRmKeyVault -VaultName 'Contoso03Vault' -ResourceGroupName 'Group14' -Location 'East US'

When I got the error
'vaultName' does not match expected pattern
I found using Powershell with raw Az CLI Commands you have to use Double Quotes to create the KeyVault.
az keyvault create --name "vault-Name-01" --resource-group $resourceGroupName --location $location --sku Standard --enabled-for-disk-encryption true
In a Powershell script you pass in the variable wrapped with double quotes
[string]$vaultName = "vault-Name-01"
az keyvault create --name $vaultName --resource-group $resourceGroupName --location $location -sku Standard --enabled-for-disk-encryption true
Then when you want to set a value you remove the double quotes:
az keyvault secret set --vault-name $vaultName.Replace("`"","") --name $_.name --value $_.value
Further investigation reveals the problem applies to listing and showing the vault secrets and I bumped into the infamous error:
Max retries exceeded attempting to connect to vault. The vault may not exist or you may need to flush your DNS cache and try again later.
The KeyVault exists, because I can list the vaults secrets using the VaultName without quotes:
$secretNames = az keyvault secret list --vault-name $sourceVaultName.Replace("`"","") -o json --query "[].name" | ConvertFrom-Json
However you'll get the Max Retires error if you don't include a quoted $sourceVaultName when trying to show the secrets:
$secrets = $secretNames | % {
$secret = az keyvault secret show --name $_ --vault-name $sourceVaultName -o json | ConvertFrom-Json
[PSCustomObject]#{
name = $_;
value = $secret.value;
}
}
If any of these calls timeout and the result is blank refer to this solution: https://stackoverflow.com/a/67472219/495455
It's almost like two developers worked on the code and had different opinions... https://github.com/Azure/azure-cli/issues/13952

Related

Copying contents of one vault to another

Somewhere I read that I can copy backups from one vault to another. I have been unable to find anything leading me in the right direction.
My intent is to do so, so that I can work around the fact that one cannot rename vaults, once they have been created.
I have been all over the different vault options, but have not come across anything suggesting that I was on the right path.
This answer have been copied from How To Copy All Secrets From One KeyVault To Another In Azure
There are two options to make it:
Copy Azure KeyVault using the Powershell script
Copy Azure KeyVault using Azure CLI
Here, we are copying 4 secrets from the source keyvault called myKeyVault2020 for the demonstrations.
Option 1: Copy Azure KeyVault using Powershell script
Now we want to copy secrets that are not already present in the destination keyvault called kv-myapps-2021 using Azure Powershell.
Param(
[Parameter(Mandatory)]
[string]$sourceKvName,
[Parameter(Mandatory)]
[string]$destKvName
)
Connect-AzAccount
$secretNames = (Get-AzKeyVaultSecret -VaultName $sourceKvName).Name
$secretNames.foreach{
Set-AzKeyVaultSecret -VaultName $destKvName -Name $_ `
-SecretValue (Get-AzKeyVaultSecret -VaultName $sourceKvName -Name $_).SecretValue
}
We can see that all secrets have been copied successfully to kv-myapps-2021.
Option 2: Copy Azure KeyVault using Azure CLI
We can also copy all secrets using the below Bash script to a new destination keyvault called kv-myapps-2023.
Source_Kv_Name="myKeyVault2020"
Dest_Kv_Name="kv-myapps-2023"
SECRETS+=($(az keyvault secret list --vault-name $Source_Kv_Name --query "[].id" -o tsv))
for SECRET in "${SECRETS[#]}"; do
SECRETNAME=$(echo "$SECRET" | sed 's|.*/||')
SECRET_CHECK=$(az keyvault secret list --vault-name $Dest_Kv_Name --query "[?name=='$SECRETNAME']" -o tsv)
if [ -n "$SECRET_CHECK" ]
then
echo "$SECRETNAME already exists in $Dest_Kv_Name"
else
echo "Copying $SECRETNAME from Source KeyVault: $Source_Kv_Name to Destination KeyVault: $Dest_Kv_Name"
SECRET=$(az keyvault secret show --vault-name $Source_Kv_Name -n $SECRETNAME --query "value" -o tsv)
az keyvault secret set --vault-name $Dest_Kv_Name -n $SECRETNAME --value "$SECRET" >/dev/null
fi
done
Let’s check the destination key vault. Awesome! All secrets are copied.

AZ CLI loop to download

I am looking for a method to loops through using specifically az cli, in order to download for example secrets/keys. I already have an ideea of what I am trying to achieve, but I would like to do it through az cli and I can't seem to understand how to loops through, like a for loop to go through all the keys/secrets and download them locally.
is there a way ? any sort of example would be useful. It must be in az cli.
Using Powershell or Bash you could always list all the secrets in a vault, iterate and backup.
Here is a Powershell sample:
$keyVaultName = "<key vault name>"
# list secrets in a vault
$secrets = az keyvault secret list `
--vault-name $keyVaultName `
| ConvertFrom-Json
foreach ($secret in $secrets) {
# backup each secret
$filename = "$($secret.name).txt"
az keyvault secret backup `
--vault-name $keyVaultName `
--name $secret.name `
--file $filename
}

How to use ForEach loop for enabling the encryption with customer-managed key stored in Managed HSM for multiple storage accounts?

I’m using the following PowerShell script, for to encrypt the Storage Account using Customer-Managed Keys stored in Azure Key Vault Managed HSM.
$resourceGroupName='XXXX'
$storageAccountName='XXXX'
$hsmName='XXXX'
$storageEncryptionKey='XXXXX'
#Assign an identity to the storage account
az storage account update `
--name $storageAccountName `
--resource-group $resourceGroupName `
--assign-identity
#Assign a role to the storage account for access to the managed HSM
storage_account_principal = $(az storage account show `
--name $storageAccountName `
--resource-group $resourceGroupName `
--query identity.principalId `
--output tsv)
az keyvault role assignment create `
--hsm-name $hsmName `
--role "Managed HSM Crypto Service Encryption User" `
--assignee $storage_account_principal `
--scope /keys/XXXX
#Configure encryption with a key in the managed HSM
hsmurl = $(az keyvault show `
--hsm-name $hsmName `
--query properties.hsmUri `
--output tsv)
az storage account update `
--name $storageAccountName `
--resource-group $resourceGroupName `
--encryption-key-name 'XXXX' `
--encryption-key-source Microsoft.Keyvault `
--encryption-key-vault $hsmurl
The above script will work for individual storage account. But I want to enable the encryption with customer-managed key stored in Azure Key Vault Managed HSM for multiple storage accounts in different resource groups using same PowerShell script.
If I understood your question correctly, all you need is a loop. (If they are all in the same subscription).
Either you enter your storages in a list yourself or you read them out with az cli.
# Setup
$HsmName='XXXX'
$StorageEncryptionKey='XXXXX'
$StorageNames = #('Storage1','Storage2','Storage3')
# -----------------------------------------------------------
# Alternative 1: List Storages by name with az command
$Storages = #()
foreach($StorageName in $StorageNames) {
$Storages += (az storage account show -n $StorageName) | ConvertFrom-Json
}
# -----------------------------------------------------------
# Alternative 2: List Storages with az command
$Storages = (az storage account list | ConvertFrom-Json)
# Optional: You may filter the result with
$Storages = $Storages | Where-Object { $_.Name -eq "..." }
# -----------------------------------------------------------
# Act
foreach($Storage in $Storages) {
#Assign variables
$resourceGroupName= $Storage.ResourceGroup
$storageAccountName= $Storage.Name
#Assign an identity to the storage account
az storage account update `
--name $storageAccountName `
--resource-group $resourceGroupName `
--assign-identity
#Assign a role to the storage account for access to the managed HSM
storage_account_principal = $(az storage account show `
--name $storageAccountName `
--resource-group $resourceGroupName `
--query identity.principalId `
--output tsv)
az keyvault role assignment create `
--hsm-name $hsmName `
--role "Managed HSM Crypto Service Encryption User" `
--assignee $storage_account_principal `
--scope /keys/XXXX
#Configure encryption with a key in the managed HSM
hsmurl = $(az keyvault show `
--hsm-name $hsmName `
--query properties.hsmUri `
--output tsv)
az storage account update `
--name $storageAccountName `
--resource-group $resourceGroupName `
--encryption-key-name 'XXXX' `
--encryption-key-source Microsoft.Keyvault `
--encryption-key-vault $hsmurl
}

Create Azure Key Vault secret from variable with Azure CLI drops caret ^ character in value

I am trying to create a new Azure Key Vault secret using the Azure Cli v2.9.0 (we use this version in our pipelines and upgrading would be difficult at the moment.) via the command below,
$myValue = "abc^def"
az keyvault secret set --vault-name $myKeyVaultName -n $mySecretName --value #myValue
The value for #myValue is actually passed in as a parameter to the script.
The command is accepted and a new secret is created but it drops the caret (^) from the string and results in a secret value of abcdef instead of the intended abc^def.
I previously raised the question here and Joy Wang correctly stated that forming a string literal as '"abc^def"' would allow the value to be added correctly via Powershell. As an extension to that question I would like to know how to pass the same value into the az keyvault secret set cmdlet from a variable.
Doing this as below still drops the caret (^)
$myValue = "abc^def"
az keyvault secret set --vault-name $myKeyVaultName -n $mySecretName --value #myValue
$myValue = "abc^def"
az keyvault secret set --vault-name $myKeyVaultName -n $mySecretName --value $(#myValue)
Posting the script snippet for clarification
param (
[Parameter(Mandatory=$True)]
[ValidateNotNullorEmpty()]
[string]$KeyVaultResourceGroup,
[Parameter(Mandatory=$True)]
[ValidateNotNullorEmpty()]
[string]$KeyVaultInstanceName,
[Parameter(Mandatory=$True)]
[ValidateNotNullorEmpty()]
[string]$CCnB_FileServer_Password_Value
)
#####################################
###########Initialsiing##############
#####################################
$ErrorActionPreference = "Stop"
$WarningPreference = 'SilentlyContinue'
Set-Location $PSScriptRoot
[Console]::ResetColor()
#############################################################
########### Create new Gasmap Key Vault secrets #############
#############################################################
#Create Secrets
if ($secrets.name -NotContains "CCnBFileServerPassword"){
Write-Output "INFO: Creating CCnBFileServerPassword secret in key vault $KeyVaultInstanceName"
az keyvault secret set --vault-name $KeyVaultInstanceName -n "CCnBFileServerPassword" --value $CCnB_FileServer_Password_Value | Out-Null
} else {
Write-Output "INFO: CCnBFileServerPassword secret already exists in key vault $KeyVaultInstanceName"
}
return 0
Any idea how I can pass this value correctly?
You can save the value like below using CLI:
It will be saved like you want:
Not sure what is the meaning of # expression, in powershell, we always use $ to define a variable.
After doing some tests, you could use the CLI in PowerShell environment like below.
$myvalue = 'abc"^"def'
az keyvault secret set --vault-name joykeyvault -n testkey12 --value $myvalue

powershell script for deleting all secrets from azure key vaults

Looking for a Powershell script which will delete all secretes present in an given azure key vault.
I don't want to delete entire key vault, just want to delete secretes present in it.
Use Remove-AzKeyVaultSecret, Remove-AzKeyVaultCertificate & Remove-AzKeyVaultKey
With some powershell and the Azure CLI you can achieve this
az keyvault secret list --vault-name ${keyVaultName} | ConvertFrom-Json | ForEach-Object { az keyvault secret delete --vault-name ${keyVaultName} --name $($_ | Select-Object -ExpandProperty Name) }
What it does is
Get all the secrets from the fault name
Transforms the response into objects
For each item take the name from the object and run the az keyvault secret delete command.
The answer by Danny van der Sluis tries to delete all secrets at once in one command, which doesn't seem to work. Putting this in a ps1 script worked for me:
$SECRETS = az keyvault secret list --vault-name "mysupersecretvault" | ConvertFrom-Json;
$SECRETS | Select-Object -Property Name | ForEach-Object { az keyvault secret delete --vault-name "mysupersecretvault" --name $_.Name }
After this, you might want to purge your vault in case you want to remake some secrets using the same name. I found it easy enough to do this through the Azure Portal, but you can also use this command:
az keyvault key purge --name "mykeyname"
Yesman's version worked well for me, however, the purge command should be for secrets, not keys so if you want to delete and purge all secrets this works:
$SECRETS = az keyvault secret list --vault-name "mysupersecretvault" | ConvertFrom-Json;
$SECRETS | Select-Object -Property Name | ForEach-Object { az keyvault secret delete --vault-name "mysupersecretvault" --name $_.Name }
$SECRETS | Select-Object -Property Name | ForEach-Object { az keyvault secret purge --vault-name "mysupersecretvault" --name $_.Name }

Resources