Skip to content

Commit 4f94e7b

Browse files
isra-felYeming Liu
andauthored
Get-AzKeyVaultSecret can -AsPlainText (#13730)
Co-authored-by: Yeming Liu <[email protected]>
1 parent 83d920a commit 4f94e7b

File tree

7 files changed

+85
-43
lines changed

7 files changed

+85
-43
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
$vaultName = 'yemingkv23'
2+
3+
4+
. ../Scripts/Common.ps1
5+
$secretName = Get-SecretName
6+
$secretText = 'dummy text'
7+
$secretTextV2 = 'dummy text 2'
8+
Set-AzKeyVaultSecret -VaultName $vaultName -Name $secretName -SecretValue (ConvertTo-SecureString $secretText -AsPlainText -Force)
9+
Set-AzKeyVaultSecret -VaultName $vaultName -Name $secretName -SecretValue (ConvertTo-SecureString $secretTextV2 -AsPlainText -Force)
10+
11+
Describe "Get secret" {
12+
It "should write secrets in plain text if -AsPlainText" {
13+
Get-AzKeyVaultSecret -VaultName $vaultName -Name $secretName -AsPlainText | Should -BeExactly $secretTextV2
14+
15+
$versions = Get-AzKeyVaultSecret -VaultName $vaultName -Name $secretName -IncludeVersions
16+
Get-AzKeyVaultSecret -VaultName $vaultName -Name $secretName -Version $versions[0].Version -AsPlainText | Should -BeExactly $secretTextV2
17+
Get-AzKeyVaultSecret -VaultName $vaultName -Name $secretName -Version $versions[1].Version -AsPlainText | Should -BeExactly $secretText
18+
}
19+
}

src/KeyVault/KeyVault/ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
- Additional information about change #1
1919
-->
2020
## Upcoming Release
21+
* Added a new parameter `-AsPlainText` to `Get-AzKeyVaultSecret` to directly return the secret in plain text
2122
* Supported selective restore a key from a managed HSM full backup [#13526]
2223
* Added missing return objects of `Get-Secret` in SecretManagement module
2324

src/KeyVault/KeyVault/Commands/GetAzureKeyVaultSecret.cs

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020
using System.Collections.Generic;
2121
using System.Linq;
2222
using System.Management.Automation;
23+
using System.Runtime.InteropServices;
24+
using System.Security;
2325

2426
namespace Microsoft.Azure.Commands.KeyVault
2527
{
2628
[Cmdlet("Get", ResourceManager.Common.AzureRMConstants.AzurePrefix + "KeyVaultSecret", DefaultParameterSetName = ByVaultNameParameterSet)]
27-
[OutputType(typeof(PSKeyVaultSecretIdentityItem), typeof(PSKeyVaultSecret), typeof(PSDeletedKeyVaultSecretIdentityItem), typeof(PSDeletedKeyVaultSecret))]
29+
[OutputType(typeof(PSKeyVaultSecretIdentityItem), typeof(PSKeyVaultSecret), typeof(PSDeletedKeyVaultSecretIdentityItem), typeof(PSDeletedKeyVaultSecret), typeof(string))]
2830
public class GetAzureKeyVaultSecret : KeyVaultCmdletBase
2931
{
3032
#region Parameter Set Names
@@ -190,6 +192,13 @@ public class GetAzureKeyVaultSecret : KeyVaultCmdletBase
190192
HelpMessage = "Specifies whether to show the previously deleted secrets in the output.")]
191193
public SwitchParameter InRemovedState { get; set; }
192194

195+
[Parameter(Mandatory = false, ParameterSetName = BySecretNameParameterSet, HelpMessage = "When set, the cmdlet will convert secret in secure string to the decrypted plaintext string as output.")]
196+
[Parameter(Mandatory = false, ParameterSetName = ByVaultNameParameterSet)]
197+
[Parameter(Mandatory = false, ParameterSetName = InputObjectBySecretNameParameterSet)]
198+
[Parameter(Mandatory = false, ParameterSetName = InputObjectByVaultNameParameterSet)]
199+
[Parameter(Mandatory = false, ParameterSetName = ResourceIdBySecretNameParameterSet)]
200+
[Parameter(Mandatory = false, ParameterSetName = ResourceIdByVaultNameParameterSet)]
201+
public SwitchParameter AsPlainText { get; set; }
193202
#endregion
194203

195204
public override void ExecuteCmdlet()
@@ -209,7 +218,7 @@ public override void ExecuteCmdlet()
209218
if (!string.IsNullOrEmpty(Version))
210219
{
211220
secret = DataServiceClient.GetSecret(VaultName, Name, Version);
212-
WriteObject(secret);
221+
WriteSecret(secret);
213222
}
214223
else if (IncludeVersions)
215224
{
@@ -241,7 +250,7 @@ public override void ExecuteCmdlet()
241250
else
242251
{
243252
secret = DataServiceClient.GetSecret(VaultName, Name, string.Empty);
244-
WriteObject(secret);
253+
WriteSecret(secret);
245254
}
246255
}
247256
}
@@ -259,7 +268,7 @@ private void GetAndWriteSecrets(string vaultName, string name) =>
259268
{
260269
VaultName = vaultName,
261270
NextLink = null
262-
},
271+
},
263272
(options) => KVSubResourceWildcardFilter(name, DataServiceClient.GetSecrets(options)));
264273

265274
private void GetAndWriteSecretVersions(string vaultName, string name, string currentSecretVersion) =>
@@ -268,7 +277,32 @@ private void GetAndWriteSecretVersions(string vaultName, string name, string cur
268277
VaultName = vaultName,
269278
Name = name,
270279
NextLink = null
271-
},
280+
},
272281
(options) => DataServiceClient.GetSecretVersions(options).Where(s => s.Version != currentSecretVersion));
282+
283+
private void WriteSecret(PSKeyVaultSecret secret)
284+
{
285+
if (AsPlainText)
286+
{
287+
WriteObject(ConvertFromSecureString(secret.SecretValue));
288+
}
289+
else
290+
{
291+
WriteObject(secret);
292+
}
293+
}
294+
295+
private string ConvertFromSecureString(SecureString secretValue)
296+
{
297+
var ssPtr = Marshal.SecureStringToBSTR(secretValue);
298+
try
299+
{
300+
return Marshal.PtrToStringBSTR(ssPtr);
301+
}
302+
finally
303+
{
304+
Marshal.ZeroFreeBSTR(ssPtr);
305+
}
306+
}
273307
}
274308
}

src/KeyVault/KeyVault/Commands/RemoveAzureKeyVaultSecret.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@
2222

2323
namespace Microsoft.Azure.Commands.KeyVault
2424
{
25-
[GenericBreakingChange("If you have soft-delete protection enabled on this key vault, this secret will be moved to the soft deleted state. " +
26-
"You will not be able to create a secret with the same name within this key vault until the secret has been purged from the soft-deleted state. Please see the following documentation for additional guidance. " +
27-
"https://docs.microsoft.com/en-us/azure/key-vault/general/soft-delete-overview")]
2825
[Cmdlet("Remove", ResourceManager.Common.AzureRMConstants.AzurePrefix + "KeyVaultSecret",SupportsShouldProcess = true,DefaultParameterSetName = ByVaultNameParameterSet)]
2926
[OutputType(typeof(PSDeletedKeyVaultSecret))]
3027
public class RemoveAzureKeyVaultSecret : KeyVaultCmdletBase

src/KeyVault/KeyVault/help/Backup-AzKeyVault.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ Aliases:
9696
Required: True
9797
Position: Named
9898
Default value: None
99-
Accept pipeline input: False
99+
Accept pipeline input: True (ByValue)
100100
Accept wildcard characters: False
101101
```
102102

src/KeyVault/KeyVault/help/Get-AzKeyVaultCertificate.md

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,8 @@ This command gets the certificate named TestCert01 from the key vault named Cont
108108

109109
```powershell
110110
$cert = Get-AzKeyVaultCertificate -VaultName "ContosoKV01" -Name "TestCert01"
111-
$secret = Get-AzKeyVaultSecret -VaultName $vaultName -Name $cert.Name
112-
$secretValueText = '';
113-
$ssPtr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secret.SecretValue)
114-
try {
115-
$secretValueText = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ssPtr)
116-
} finally {
117-
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ssPtr)
118-
}
119-
$secretByte = [Convert]::FromBase64String($secretValueText)
111+
$secret = Get-AzKeyVaultSecret -VaultName $vaultName -Name $cert.Name -AsPlainText
112+
$secretByte = [Convert]::FromBase64String($secret)
120113
$x509Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($secretByte, "", "Exportable,PersistKeySet")
121114
$type = [System.Security.Cryptography.X509Certificates.X509ContentType]::Pfx
122115
$pfxFileByte = $x509Cert.Export($type, $password)

src/KeyVault/KeyVault/help/Get-AzKeyVaultSecret.md

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ Gets the secrets in a key vault.
1515

1616
### ByVaultName (Default)
1717
```
18-
Get-AzKeyVaultSecret [-VaultName] <String> [[-Name] <String>] [-InRemovedState]
18+
Get-AzKeyVaultSecret [-VaultName] <String> [[-Name] <String>] [-InRemovedState] [-AsPlainText]
1919
[-DefaultProfile <IAzureContextContainer>] [<CommonParameters>]
2020
```
2121

2222
### BySecretName
2323
```
24-
Get-AzKeyVaultSecret [-VaultName] <String> [-Name] <String> [-Version] <String>
24+
Get-AzKeyVaultSecret [-VaultName] <String> [-Name] <String> [-Version] <String> [-AsPlainText]
2525
[-DefaultProfile <IAzureContextContainer>] [<CommonParameters>]
2626
```
2727

@@ -33,13 +33,13 @@ Get-AzKeyVaultSecret [-VaultName] <String> [-Name] <String> [-IncludeVersions]
3333

3434
### ByInputObjectVaultName
3535
```
36-
Get-AzKeyVaultSecret [-InputObject] <PSKeyVault> [[-Name] <String>] [-InRemovedState]
36+
Get-AzKeyVaultSecret [-InputObject] <PSKeyVault> [[-Name] <String>] [-InRemovedState] [-AsPlainText]
3737
[-DefaultProfile <IAzureContextContainer>] [<CommonParameters>]
3838
```
3939

4040
### ByInputObjectSecretName
4141
```
42-
Get-AzKeyVaultSecret [-InputObject] <PSKeyVault> [-Name] <String> [-Version] <String>
42+
Get-AzKeyVaultSecret [-InputObject] <PSKeyVault> [-Name] <String> [-Version] <String> [-AsPlainText]
4343
[-DefaultProfile <IAzureContextContainer>] [<CommonParameters>]
4444
```
4545

@@ -51,13 +51,13 @@ Get-AzKeyVaultSecret [-InputObject] <PSKeyVault> [-Name] <String> [-IncludeVersi
5151

5252
### ByResourceIdVaultName
5353
```
54-
Get-AzKeyVaultSecret [-ResourceId] <String> [[-Name] <String>] [-InRemovedState]
54+
Get-AzKeyVaultSecret [-ResourceId] <String> [[-Name] <String>] [-InRemovedState] [-AsPlainText]
5555
[-DefaultProfile <IAzureContextContainer>] [<CommonParameters>]
5656
```
5757

5858
### ByResourceIdSecretName
5959
```
60-
Get-AzKeyVaultSecret [-ResourceId] <String> [-Name] <String> [-Version] <String>
60+
Get-AzKeyVaultSecret [-ResourceId] <String> [-Name] <String> [-Version] <String> [-AsPlainText]
6161
[-DefaultProfile <IAzureContextContainer>] [<CommonParameters>]
6262
```
6363

@@ -175,27 +175,10 @@ This command gets a specific version of the secret named secret1 in the key vaul
175175

176176
### Example 5: Get the plain text value of the current version of a specific secret
177177
```powershell
178-
PS C:\> $secret = Get-AzKeyVaultSecret -VaultName 'Contoso' -Name 'ITSecret'
179-
180-
# Method 1: requires PowerShell >= 7.0
181-
PS C:\> $secretInPlainText = $secret.SecretValue | ConvertFrom-SecureString -AsPlainText
182-
183-
# Method 2: works on older PowerShell versions
184-
PS C:\> $secretValueText = '';
185-
PS C:\> $ssPtr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secret.SecretValue)
186-
PS C:\> try {
187-
$secretInPlainText = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ssPtr)
188-
} finally {
189-
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ssPtr)
190-
}
191-
192-
# Method 3: works in ConstrainedLanguage mode
193-
$secretInPlainText = [pscredential]::new("DoesntMatter", $secret.SecretValue).GetNetworkCredential().Password
178+
PS C:\> $secretText = Get-AzKeyVaultSecret -VaultName 'Contoso' -Name 'ITSecret' -AsPlainText
194179
```
195180

196-
These commands get the current version of a secret named ITSecret, and then displays the plain text value of that secret.
197-
198-
(Note: use method 3 if you are working in PowerShell [ConstrainedLanguage mode](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_language_modes?view=powershell-7.1#constrained-language-constrained-language), for example, on secure/privileged access workstations.)
181+
The cmdlet returns the secret as a string when `-AsPlainText` is applied.
199182

200183
### Example 6: Get all the secrets that have been deleted but not purged for this key vault.
201184
```powershell
@@ -285,6 +268,21 @@ This command gets the current versions of all secrets in the key vault named Con
285268

286269
## PARAMETERS
287270

271+
### -AsPlainText
272+
When set, the cmdlet will convert secret in secure string to the decrypted plaintext string as output.
273+
274+
```yaml
275+
Type: System.Management.Automation.SwitchParameter
276+
Parameter Sets: ByVaultName, BySecretName, ByInputObjectVaultName, ByInputObjectSecretName, ByResourceIdVaultName, ByResourceIdSecretName
277+
Aliases:
278+
279+
Required: False
280+
Position: Named
281+
Default value: None
282+
Accept pipeline input: False
283+
Accept wildcard characters: False
284+
```
285+
288286
### -DefaultProfile
289287
The credentials, account, tenant, and subscription used for communication with azure
290288

0 commit comments

Comments
 (0)