Azure / azure-powershell

Microsoft Azure PowerShell
Other
4.25k stars 3.85k forks source link

Get-AzKeyVaultSecret not returning SecretValueText for certificate #14457

Closed allan-stewart closed 3 years ago

allan-stewart commented 3 years ago

Description

I am attempting to export an App Service Certificate based on the instructions here which is linked to from portal.azure.com in the "Export Certificate" > "Export App Service Certificate" instructions.

I am on MacOS, so I converted the script to use the Az module some time ago. It worked great. But then I needed to run it again, and now it is failing, apparently because SecretValueText is not getting set after a call like:

$secret = Get-AzKeyVaultSecret -VaultName $keyVaultName -Name $keyVaultSecretName

When I run that command by itself, it gives me back data about the certificate. So I know it found the certificate correctly, but the SecretValueText is always empty.

Steps to reproduce

Insert your own values into the following script and try to run it.


$subscriptionId = "****"
$resourceGroupName = "****"
$name = "****"

###########################################################

#Connect-AzAccount
Set-AzContext -SubscriptionId $subscriptionId

## Get the KeyVault Resource Url and KeyVault Secret Name were the certificate is stored
$ascResource= Get-AzResource -ResourceId "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.CertificateRegistration/certificateOrders/$name"
$certProps = Get-Member -InputObject $ascResource.Properties.certificates[0] -MemberType NoteProperty
$certificateName = $certProps[0].Name
$keyVaultId = $ascResource.Properties.certificates[0].$certificateName.KeyVaultId
$keyVaultSecretName = $ascResource.Properties.certificates[0].$certificateName.KeyVaultSecretName

## Split the resource URL of KeyVault and get KeyVaultName and KeyVaultResourceGroupName
$keyVaultIdParts = $keyVaultId.Split("/")
$keyVaultName = $keyVaultIdParts[$keyVaultIdParts.Length - 1]

## Getting the secret from the KeyVault
$secret = Get-AzKeyVaultSecret -VaultName $keyVaultName -Name $keyVaultSecretName
$pfxCertObject= New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList @([Convert]::FromBase64String($secret.SecretValueText),"",[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
$pfxPassword = -join ((65..90) + (97..122) + (48..57) | Get-Random -Count 50 | ForEach-Object {[char]$_})
$currentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath
[Environment]::CurrentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath
[io.file]::WriteAllBytes("appservicecertificate.pfx",$pfxCertObject.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12,$pfxPassword))

# Print the password for the exported certificate
Write-Host "Created an App Service Certificate copy at: $currentDirectory\appservicecertificate.pfx"
Write-Warning "For security reasons, do not store the PFX password. Use it directly from the console as required."
Write-Host "PFX password: $pfxPassword"

Environment data

Name                           Value
----                           -----
PSVersion                      7.1.2
PSEdition                      Core
GitCommitId                    7.1.2
OS                             Darwin 19.6.0 Darwin Kernel Version 19.6.0: Thu Oct 29 22:56:45 PDT 2020; root:xnu-6153.141…
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Module versions

    Directory: /Users/allanstewart/.local/share/powershell/Modules

ModuleType Version    PreRelease Name                                PSEdition ExportedCommands
---------- -------    ---------- ----                                --------- ----------------
Script     5.6.0                 Az                                  Core,Desk 
Script     2.2.6                 Az.Accounts                         Core,Desk {Disable-AzDataCollection, Disable-AzContex…
Script     1.1.1                 Az.Advisor                          Core,Desk {Get-AzAdvisorRecommendation, Enable-AzAdvi…
Script     2.0.2                 Az.Aks                              Core,Desk {Get-AzAksCluster, New-AzAksCluster, Remove…
Script     1.1.4                 Az.AnalysisServices                 Core,Desk {Resume-AzAnalysisServicesServer, Suspend-A…
Script     2.2.0                 Az.ApiManagement                    Core,Desk {Add-AzApiManagementApiToGateway, Add-AzApi…
Script     1.0.0                 Az.AppConfiguration                 Core,Desk {Get-AzAppConfigurationStore, Get-AzAppConf…
Script     1.1.0                 Az.ApplicationInsights              Core,Desk {Get-AzApplicationInsights, New-AzApplicati…
Script     1.5.0                 Az.Automation                       Core,Desk {Get-AzAutomationHybridWorkerGroup, Remove-…
Script     3.1.0                 Az.Batch                            Core,Desk {Remove-AzBatchAccount, Get-AzBatchAccount,…
Script     2.0.0                 Az.Billing                          Core,Desk {Get-AzBillingInvoice, Get-AzBillingPeriod,…
Script     1.6.0                 Az.Cdn                              Core,Desk {Get-AzCdnProfile, Get-AzCdnProfileSsoUrl, …
Script     1.8.0                 Az.CognitiveServices                Core,Desk {Get-AzCognitiveServicesAccount, Get-AzCogn…
Script     4.10.0                Az.Compute                          Core,Desk {Remove-AzAvailabilitySet, Get-AzAvailabili…
Script     1.0.3                 Az.ContainerInstance                Core,Desk {New-AzContainerGroup, Get-AzContainerGroup…
Script     2.2.1                 Az.ContainerRegistry                Core,Desk {New-AzContainerRegistry, Get-AzContainerRe…
Script     1.1.0                 Az.CosmosDB                         Core,Desk {Get-AzCosmosDBSqlContainer, Get-AzCosmosDB…
Script     1.1.0                 Az.DataBoxEdge                      Core,Desk {Get-AzDataBoxEdgeJob, Get-AzDataBoxEdgeDev…
Script     1.1.0                 Az.Databricks                       Core,Desk {Get-AzDatabricksVNetPeering, Get-AzDatabri…
Script     1.11.4                Az.DataFactory                      Core,Desk {Set-AzDataFactoryV2, Update-AzDataFactoryV…
Script     1.0.2                 Az.DataLakeAnalytics                Core,Desk {Get-AzDataLakeAnalyticsDataSource, New-AzD…
Script     1.3.0                 Az.DataLakeStore                    Core,Desk {Get-AzDataLakeStoreTrustedIdProvider, Remo…
Script     1.0.0                 Az.DataShare                        Core,Desk {New-AzDataShareAccount, Get-AzDataShareAcc…
Script     1.1.0                 Az.DeploymentManager                Core,Desk {Get-AzDeploymentManagerArtifactSource, New…
Script     2.1.1                 Az.DesktopVirtualization            Core,Desk {Disconnect-AzWvdUserSession, Expand-AzWvdM…
Script     1.0.2                 Az.DevTestLabs                      Core,Desk {Get-AzDtlAllowedVMSizesPolicy, Get-AzDtlAu…
Script     1.1.2                 Az.Dns                              Core,Desk {Get-AzDnsRecordSet, New-AzDnsRecordConfig,…
Script     1.3.0                 Az.EventGrid                        Core,Desk {New-AzEventGridTopic, Get-AzEventGridTopic…
Script     1.7.1                 Az.EventHub                         Core,Desk {New-AzEventHubNamespace, Get-AzEventHubNam…
Script     1.7.0                 Az.FrontDoor                        Core,Desk {New-AzFrontDoor, Get-AzFrontDoor, Set-AzFr…
Script     2.0.0                 Az.Functions                        Core,Desk {Get-AzFunctionApp, Get-AzFunctionAppAvaila…
Script     4.2.0                 Az.HDInsight                        Core,Desk {Get-AzHDInsightJob, New-AzHDInsightSqoopJo…
Script     1.2.0                 Az.HealthcareApis                   Core,Desk {New-AzHealthcareApisService, Remove-AzHeal…
Script     2.7.2                 Az.IotHub                           Core,Desk {Add-AzIotHubKey, Get-AzIotHubEventHubConsu…
Script     3.4.0                 Az.KeyVault                         Core,Desk {Add-AzKeyVaultCertificate, Update-AzKeyVau…
Script     1.0.1                 Az.Kusto                            Core,Desk {Add-AzKustoClusterLanguageExtension, Add-A…
Script     1.5.0                 Az.LogicApp                         Core,Desk {Get-AzIntegrationAccountAgreement, Get-AzI…
Script     1.1.3                 Az.MachineLearning                  Core,Desk {Move-AzMlCommitmentAssociation, Get-AzMlCo…
Script     1.1.0                 Az.Maintenance                      Core,Desk {Get-AzApplyUpdate, Get-AzConfigurationAssi…
Script     2.0.0                 Az.ManagedServices                  Core,Desk {Get-AzManagedServicesAssignment, New-AzMan…
Script     1.0.2                 Az.MarketplaceOrdering              Core,Desk {Get-AzMarketplaceTerms, Set-AzMarketplaceT…
Script     1.1.1                 Az.Media                            Core,Desk {Sync-AzMediaServiceStorageKey, Set-AzMedia…
Script     1.0.0                 Az.Migrate                          Core,Desk {Get-AzMigrateDiscoveredServer, Get-AzMigra…
Script     2.4.0                 Az.Monitor                          Core,Desk {Get-AzMetricDefinition, Get-AzMetric, Remo…
Script     4.6.0                 Az.Network                          Core,Desk {Add-AzApplicationGatewayAuthenticationCert…
Script     1.1.1                 Az.NotificationHubs                 Core,Desk {Get-AzNotificationHub, Get-AzNotificationH…
Script     2.3.0                 Az.OperationalInsights              Core,Desk {New-AzOperationalInsightsAzureActivityLogD…
Script     1.4.1                 Az.PolicyInsights                   Core,Desk {Get-AzPolicyEvent, Get-AzPolicyState, Get-…
Script     1.1.2                 Az.PowerBIEmbedded                  Core,Desk {Remove-AzPowerBIWorkspaceCollection, Get-A…
Script     1.0.3                 Az.PrivateDns                       Core,Desk {Get-AzPrivateDnsZone, Remove-AzPrivateDnsZ…
Script     3.4.1                 Az.RecoveryServices                 Core,Desk {Get-AzRecoveryServicesBackupProperty, Get-…
Script     1.4.0                 Az.RedisCache                       Core,Desk {Remove-AzRedisCachePatchSchedule, New-AzRe…
Script     1.0.3                 Az.Relay                            Core,Desk {New-AzRelayNamespace, Get-AzRelayNamespace…
Script     3.3.0                 Az.Resources                        Core,Desk {Get-AzProviderOperation, Remove-AzRoleAssi…
Script     1.4.1                 Az.ServiceBus                       Core,Desk {New-AzServiceBusNamespace, Get-AzServiceBu…
Script     2.2.2                 Az.ServiceFabric                    Core,Desk {Add-AzServiceFabricClientCertificate, Add-…
Script     1.2.0                 Az.SignalR                          Core,Desk {New-AzSignalR, Get-AzSignalR, Get-AzSignal…
Script     2.16.0                Az.Sql                              Core,Desk {Get-AzSqlDatabaseTransparentDataEncryption…
Script     1.1.0                 Az.SqlVirtualMachine                Core,Desk {New-AzSqlVM, Get-AzSqlVM, Update-AzSqlVM, …
Script     3.4.0                 Az.Storage                          Core,Desk {Get-AzStorageAccount, Get-AzStorageAccount…
Script     1.4.0                 Az.StorageSync                      Core,Desk {Invoke-AzStorageSyncCompatibilityCheck, Ne…
Script     1.0.1                 Az.StreamAnalytics                  Core,Desk {Get-AzStreamAnalyticsFunction, Get-AzStrea…
Script     1.0.0                 Az.Support                          Core,Desk {Get-AzSupportService, Get-AzSupportProblem…
Script     1.0.4                 Az.TrafficManager                   Core,Desk {Add-AzTrafficManagerCustomHeaderToEndpoint…
Script     2.4.0                 Az.Websites                         Core,Desk {Get-AzAppServicePlan, Set-AzAppServicePlan…

    Directory: /usr/local/microsoft/powershell/7/Modules

ModuleType Version    PreRelease Name                                PSEdition ExportedCommands
---------- -------    ---------- ----                                --------- ----------------
Manifest   1.2.5                 Microsoft.PowerShell.Archive        Desk      {Compress-Archive, Expand-Archive}
Manifest   7.0.0.0               Microsoft.PowerShell.Host           Core      {Start-Transcript, Stop-Transcript}
Manifest   7.0.0.0               Microsoft.PowerShell.Management     Core      {Add-Content, Clear-Content, Clear-ItemProp…
Manifest   7.0.0.0               Microsoft.PowerShell.Security       Core      {Get-Credential, Get-ExecutionPolicy, Set-E…
Manifest   7.0.0.0               Microsoft.PowerShell.Utility        Core      {Export-Alias, Get-Alias, Import-Alias, New…
Script     1.4.7                 PackageManagement                   Desk      {Find-Package, Get-Package, Get-PackageProv…
Script     2.2.5                 PowerShellGet                       Desk      {Find-Command, Find-DSCResource, Find-Modul…
Script     2.0.5                 PSDesiredStateConfiguration         Core      {Configuration, New-DscChecksum, Get-DscRes…
Script     2.1.0                 PSReadLine                          Desk      {Get-PSReadLineKeyHandler, Set-PSReadLineKe…
Binary     2.0.3                 ThreadJob                           Desk      Start-ThreadJob

Error output

New-Object: /Users/allanstewart/example/export-certificate.ps1:23
Line |
  23 |  … CertObject= New-Object System.Security.Cryptography.X509Certificates. …
     |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Exception calling ".ctor" with "3" argument(s): "Array may not be empty or null. (Parameter 'rawData')"

InvalidOperation: /Users/allanstewart/example/export-certificate.ps1:27
Line |
  27 |  [io.file]::WriteAllBytes("appservicecertificate.pfx",$pfxCertObject.E …
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | You cannot call a method on a null-valued expression.
ghost commented 3 years ago

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @Wmengmsft, @MehaKaushik, @shurd, @anfeldma-ms

dingmeng-xue commented 3 years ago

@allan-stewart , thanks for reporting. Do you remember which version of Az.keyvault works?

As far as I know, Get-AzKeyVaultSecret has a breaking change in the last major release. It returns secure string by default instead of string in previous version. Please try to append -AsPlainText to get the value in plain text. https://docs.microsoft.com/en-us/powershell/module/az.keyvault/get-azkeyvaultsecret?view=azps-5.6.0#parameters

allan-stewart commented 3 years ago

Adding -AsPlainText worked (once I also removed the .SecretValueText from the script). I must have been on the wrong version of the docs somehow, because I didn't see that option to try. Thanks for pointing it out.

As for the older version that worked, I'm not sure. I created it on my old machine before its hard drive died. But the commit for my script was Aug 14, 2020 and I'm quite sure that I installed powershell on my Mac in order to build that script, so it would have been whatever version was most recent at that time (if that even helps).

I understand there are a bunch of different teams involved, but it would be nice if an updated script could be linked from Azure to prevent others from having to figure out the upgrades from AzureRm to Az. But this at least solves my issue, so thank you!

dingmeng-xue commented 3 years ago

@allan-stewart , thanks for the verification. This breaking change was introduced in the second half of last year because users complained it's not secure if secret shows in plain text. For documentation, we will report it if we find docs are not updated.

Close this issue now.