Get-AzKeyVaultSecret can't read secret value in Powershell - azure

I'm not able to read the value of one of my secrets in Key Vault. I'm logged in with my Azure account and I have full permission to the selected Key Vault.
I'm able to retrieve a list of available secrets using the following command:
$keyVaultValue = (Get-AzKeyVaultSecret -VaultName 'name-of-key-vault')
And then see the content when I write:
Write-Output $keyVaultValue
But when I ask for a specific key it just returns null:
$keyVaultValue = (Get-AzKeyVaultSecret -VaultName 'name-of-key-vault' -Name 'my-secret-name').SecretValueText
I've checked the name and subscription ID and everything is correct. I can easily read the value from the portal, but no from powershell on my Windows PC.
Any suggestions?

SecretValueText is deprecated, You can use the following syntax the retrieve the value as plain text:
$keyVaultValue = Get-AzKeyVaultSecret -VaultName 'name-of-key-vault' -Name 'my-secret-name'
$keyVaultValue.SecretValue | ConvertFrom-SecureString -AsPlainText
More information and examples can be found here.

If you want to show all key-vault secrets name and their key values then you can use this in powershell
$secrets=Get-AzKeyVaultSecret -VaultName 'key-vault-name'
$secrets | % {Write-Output "$($_.name) $($(Get-AzKeyVaultSecret -VaultName $_.VaultName -Name $_.Name).SecretValue | ConvertFrom-SecureString -AsPlainText)" }

Try using this function:
function GetSecretValue
{
param(
[String]$keyvaultName,
[String]$secretName
)
Write-Host "Retrieving secret $secretName from $keyvaultName... " -NoNewline
if ((Get-Command Get-AzKeyVaultSecret).ParameterSets.Parameters.Name -contains "AsPlainText")
{
# Newer Get-AzKeyVaultSecret version requires -AsPlainText parameter
$secretValue = Get-AzKeyVaultSecret -VaultName $keyvaultName -Name $secretName -AsPlainText
}
else
{
$secretValue = (Get-AzKeyVaultSecret -VaultName $keyvaultName -Name $secretName).SecretValueText
}
Write-Host "ok"
return $secretValue
}
Usage example:
$keyVaultValue = GetSecretValue "name-of-key-vault" "my-secret-name"

Related

Store alias_primary_connection_string in keyvault under service bus queue SAS policy

I want to store "alias_primary_connection_string" from each queue SAS policy of a defined service bus namespace in Keyvault secret using PowerShell in azure. Tried using Get-AzServiceBusNamespace & Get-AzServiceBusAuthorizationRule with for loop but not able to achieve it. I am getting name of all queues name but not alias_primary_connection_string. Need help on the code.
Tried below and got all the queue in namespace.
I want to store each queue's alias_primary_connection_string one by one in the keyvault secret with name like ("each queue name" append with string "alias_primary_string" ) and if entry already present in keyvault then override it or delete and recreate the secret.
#Code for getting queue names of namespace:
Get-AzServiceBusNamespace -ResourceGroupName mygroup -NamespaceName mybus |
ForEach-Object {
Get-AzServiceBusQueue -ResourceGroupName $_.ResourceGroup -Namespace $_.Name |
ForEach-Object {
[PsCustomObject\]#{
Queue = $\_.Name
}}}
I tried and got the script at last. This code will truncate entity path from alias connection string and send it to the keyvault.
$ResourceGroup = ******* define yours as per requirement
$rg = $ResourceGroup
$ns = ($ResourceGroup, "bus", "abc" -join '-').ToLower()
$kv = ("ABC", $EnvironmentName, $EnvironmentInstance, "key" -join '-').ToLower()
Get-AzServiceBusQueue -ResourceGroup $rg -NamespaceName $ns |
ForEach-Object {
Foreach ($i in $_.Name) {
Get-AzServiceBusAuthorizationRule -ResourceGroupName $rg -NamespaceName $ns -QueueName $_.Name |
ForEach-Object {
Get-AzServiceBusKey -ResourceGroupName $rg -NamespaceName $ns -QueueName $i -Name $_.name |
ForEach-Object {
$secretname = $_.KeyName + '-alias'
$secretvalue = $_.PrimaryConnectionString -replace ";EntityPath.*",""
Write-Host "adding latest secret value for $secretname"
$vaultsecret = ConvertTo-SecureString $secretvalue -AsPlainText -Force
Set-AzKeyVaultSecret -VaultName $kv -Name $secretname -SecretValue $vaultsecret
Write-Host "$secretname added to keyvault $kv"
}
}
}
}

Powershell script won't list expired key vault certificates

I have a powershell script that is attempting to list all the expired secrets of my Azure Key Vault. Unfortunately I'm struggling to do this.
This is how I retrieve sercrets. But what do I need to add to get the expiration of all secrets? Then delete those that are expired? I'm guessing I'll need to set an access policy.
Select-AzSubscription -Subscription "My subscriptsion"
Set-AzKeyVaultAccessPolicy -VaultName "testKeyVaultPwsh" -UserPrincipalName "mystuff#domain.com" -PermissionsToSecrets get,set,delete
#Retrieve secret
$secret = Get-AzKeyVaultSecret -VaultName "testKeyVaultPwsh" -Name "ExamplePassword" -AsPlainText
You can delete the expired secrets using below commands .(Make sure
you have get,set,delete access policies set and given proper
permissions )
I have tried in my environment and able to delete expired secrets sussessfully.
After checking expiry using
$exp =Get-AzKeyVaultSecret -VaultName $vaultname -Name $secretname | Select-Object Name,Expires
$exp
I created secrets and have secrets expired.
Commands:
$vaultname= “<keyvaultname>”
$secrets= Get-AzKeyVaultSecret -VaultName $vaultname
$secretnames =$secrets.Name
$current_date=Get-Date
Foreach($secretname in $secretnames)
{
$exp =Get-AzKeyVaultSecret -VaultName $vaultname -Name $secretname | Select-Object Expires
$keyvaultsecretvexpirydate =[datetime]($exp.Expires)
$timediff=NEW-TIMESPAN -Start $current_date -End $keyvaultsecretvexpirydate
$days_until_expiration=$timediff.Days
Write-Output “days_until_expiration of secret named $secretname is :$days_until_expiration”
Write-Output “ ”
if ($days_until_expiration -eq 0)
{
Write-Output "Secret named $secretname got expired “
Write-Output “removing expired secret : $secretname”
Write-Output “ ”
Remove-AzKeyVaultSecret -VaultName $vaultname -Name $secretname
}
}
Confirm to delete by typing Y and refresh the secrets page to see the expired secret being removed/deleted.
References:
KeyVaultSecretExpirationAlerts |github
remove-azkeyvaultsecret | microsoftdocs

How to check if azure resource exists in PowerShell?

I am trying to check if an azure key vault already exists in a resource group using PowerShell. If the vault with the same name already exists even in the deleted state I only want to receive a user friendly message saying Key Vault already exists or catch the exception if there is any. I don't want the terminal to blow up with errors. If the key vault does not exist I want to create a new keyvault.
I have the following code:
$KeyVaultName = "Key Vault Name"
$ResourceGroupName = "Resource group name"
$KeyVault = Get-AzKeyVault -VaultName $KeyVaultName -ResourceGroupName $ResourceGroupName -ErrorAction SilentlyContinue
if($null -eq $KeyVault){
New-AzKeyVault -ResourceGroupName $ResourceGroupName -VaultName $KeyVaultName -Location "Switzerland North"
}
else{
Write-Host "$KeyVaultName already exists"
}
After executing the code I am getting this error message on the terminal:
New-AzKeyVault : A vault with the same name already exists in deleted state. You need to either recover or purge existing key vault.
I also tried using the following code as well:
if (!(Test-AzureName -Service $KeyVaultName))
{
New-AzKeyVault -ResourceGroupName $ResourceGroupName -VaultName $KeyVaultName -Location "Switzerland North"
}
It gives me the following error after execution:
Test-AzureName : No default subscription has been designated. Use Select-AzureSubscription -Default to set the default subscription.
Though I only have one subscription being used.
Can someone please tell me if I am doing something wrong here ? Can you please provide me with an efficient way to achieve this ?
You can try something like the following:
$KeyVaultName = "keyvaultname"
$ResourceGroupName = "resourcegroupname"
$KeyVaultLocation = "keyvaultlocation"
$KeyVault = Get-AzKeyVault -VaultName $KeyVaultName -ResourceGroupName $ResourceGroupName -ErrorAction SilentlyContinue
if($null -eq $KeyVault){
$KeyVault = Get-AzKeyVault -VaultName $KeyVaultName -Location $KeyVaultLocation -InRemovedState -ErrorAction SilentlyContinue
if ($null -eq $KeyVault) {
New-AzKeyVault -ResourceGroupName $ResourceGroupName -VaultName $KeyVaultName -Location $KeyVaultLocation
} else {
Write-Host "$KeyVaultName exists but is in soft-deleted state"
}
}
else{
Write-Host "$KeyVaultName already exists"
}
Essentially what we are doing here is first checking if the Key Vault exists and is in active state. If we do not find any Key Vault, then we are checking if the Key Vault is in soft deleted state. If no results are found, then we are proceeding with creation of new Key Vault.
However, please note that Key Vault name is globally unique so it is quite possible that your New-AzKeyVault Cmdlet fails.

PowerShell Export Pfx from Azure Key Vault using Az.KeyVault

I am creating a certificate inside Azure Key Vault and then attempting to export it with private key as a PFX.
# Create new Certificate in Key Vault
$policy = New-AzKeyVaultCertificatePolicy -SecretContentType "application/x-pkcs12" -SubjectName "CN=contoso" -IssuerName "Self" -ValidityInMonths 12 -ReuseKeyOnRenewal -KeySize 4096 -KeyType 'RSA-HSM';
Add-AzKeyVaultCertificate -VaultName $VaultName -Name $ADServicePrincipalCertificateName -CertificatePolicy $policy;
# From https://learn.microsoft.com/en-us/powershell/module/az.keyvault/get-azkeyvaultcertificate?view=azps-5.8.0
# Export new Key Vault Certificate as PFX
$securePassword = "fBoFXYD%dg^Q" | ConvertTo-SecureString -AsPlainText -Force; # This is a throwaway password
$certificate = Get-AzKeyVaultCertificate -VaultName $VaultName -Name $ADServicePrincipalCertificateName;
$secret = Get-AzKeyVaultSecret -VaultName $vaultName -Name $certificate.Name -AsPlainText;
$secretByte = [Convert]::FromBase64String($secret)
$x509Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($secretByte, "", "Exportable,PersistKeySet")
$type = [System.Security.Cryptography.X509Certificates.X509ContentType]::Pfx
$pfxFileByte = $x509Cert.Export($type, $securePassword);
[System.IO.File]::WriteAllBytes("C:\Repos\Certificate.pfx", $pfxFileByte)
Get-PnPAzureCertificate -Path "C:\Repos\Certificate.pfx" -Password $securePassword
However, the PFX file is not valid
Error with Get-PnPAzureCertificate
Error with Certificate Import
Any ideas? Using Import-AzKeyVaultCertificate is not an option because there's a bug with it in environments that have policies that forces key lengths
Also, might be worth mentioning that I am using PowerShell 7
According to my test, we need to change keytype as RSA when we create cert policy.
For example
$VaultName=""
$ADServicePrincipalCertificateName=""
$policy = New-AzKeyVaultCertificatePolicy -SecretContentType "application/x-pkcs12" `
-SubjectName "CN=contoso.com" -IssuerName "Self" `
-ValidityInMonths 12 -ReuseKeyOnRenewal `
-KeySize 4096 -KeyType 'RSA';
Add-AzKeyVaultCertificate -VaultName $VaultName -Name $ADServicePrincipalCertificateName -CertificatePolicy $policy;
Start-Sleep -Seconds 30
# From https://learn.microsoft.com/en-us/powershell/module/az.keyvault/get-azkeyvaultcertificate?view=azps-5.8.0
# Export new Key Vault Certificate as PFX
$securePassword = "fBoFXYD%dg^Q" | ConvertTo-SecureString -AsPlainText -Force; # This is a throwaway password
$certificate = Get-AzKeyVaultCertificate -VaultName $VaultName -Name $ADServicePrincipalCertificateName;
$secret = Get-AzKeyVaultSecret -VaultName $vaultName -Name $certificate.Name -AsPlainText;
$secretByte = [Convert]::FromBase64String($secret)
$x509Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($secretByte, "", "Exportable,PersistKeySet")
$type = [System.Security.Cryptography.X509Certificates.X509ContentType]::Pfx
$pfxFileByte = $x509Cert.Export($type, $securePassword);
[System.IO.File]::WriteAllBytes("E:\Certificate.pfx", $pfxFileByte)
Get-PnPAzureCertificate -Path "E:\Certificate.pfx" -Password $securePassword

Warning about Breaking changes in the cmdlet 'Get-AzKeyVaultSecret' SecretValueText deprecated Az4.6.1

I upgraded Az Powershell to 4.6.1 today and started seeing the below warning. The question I have is what I am supposed to do about this warning? I could mute the warning but that wouldn't help me prepare for this breaking change at all. I checked the Az 4.6.1 Microsoft docs and they tell me I should still be using SecretValueText and provide no similar warning about deprecation or any alternative ways to get the secret value. So what is my update path for powershell that reads KeyVault secrets using SecretValueText?
WARNING: Breaking changes in the cmdlet 'Get-AzKeyVaultSecret' :
WARNING: - "The output type 'Microsoft.Azure.Commands.KeyVault.Models.PSKeyVaultSecret' is changing"
- The following properties in the output type are being deprecated :
'SecretValueText'
WARNING: Note :The change is expected to take effect from the version : '3.0.0'
WARNING: - "The output type 'Microsoft.Azure.Commands.KeyVault.Models.PSDeletedKeyVaultSecret' is changing"
- The following properties in the output type are being deprecated :
'SecretValueText'
WARNING: Note :The change is expected to take effect from the version : '3.0.0'
WARNING: NOTE : Go to https://aka.ms/azps-changewarnings for steps to suppress this breaking change warning, and other information on breaking changes in Azure PowerShell.
Here is the current example in the Microsoft docs:
$secret = Get-AzKeyVaultSecret -VaultName 'Contoso' -Name 'ITSecret'
Write-Host "Secret Value is:" $secret.SecretValueText
Secret Value is: P#ssw0rd
This can be done with:
Get the secret with:
$secret = Get-AzKeyVaultSecret -VaultName {YourVaultName} -Name {YourSecret}
$pass = $secret.SecretValue | ConvertFrom-SecureString -AsPlainText
This is the same as
$secret.SecretValueText
Microsoft documentation has now been updated
This example is taken from the latest docs
$secret = Get-AzKeyVaultSecret -VaultName 'Contoso' -Name 'ITSecret'
$secretValueText = '';
$ssPtr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secret.SecretValue)
try {
$secretValueText = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ssPtr)
} finally {
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ssPtr)
}
Write-Host "Secret Value is:" $secretValueText
Secret Value is: P#ssw0rd
Well, even if the SecretValueText will be deprecated, there is a way that will always work.
Just use $secret.SecretValue, it is a System.Security.SecureString, we just need to convert it to String, the $Password below is what you want.
$secret = Get-AzKeyVaultSecret -VaultName joykeyvault -Name mySecret123
$SecurePassword = $secret.SecretValue
$Password = [System.Net.NetworkCredential]::new("", $SecurePassword).Password
ConvertFrom-SecureString -AsPlainText is supported on in PowerShell 7. dont try it on lower version
You can use the -AsPlainText switch on Get-AzKeyVaultSecret.
$secretText = Get-AzKeyVaultSecret -VaultName 'Contoso' -Name 'ITSecret' -AsPlainText
Another option is to add SecretValueText property back to the Microsoft.Azure.Commands.KeyVault.Models.PSKeyVaultSecretIdentityItem objects.
# Update PSKeyVaultSecretIdentityItem object type to include scriptproperty secretvaluetext
$Script = { Get-AzKeyVaultSecret -VaultName $this.VaultName -Name $this.Name -AsPlainText }
Update-TypeData -TypeName 'Microsoft.Azure.Commands.KeyVault.Models.PSKeyVaultSecretIdentityItem' -MemberName 'SecretValueText' -MemberType ScriptProperty -Value $Script
# SecretValueText property will contain decrypted secret text for the session
$secret = Get-AzKeyVaultSecret -VaultName 'Contoso' -Name 'ITSecret'
$secret.SecretValueText

Resources