From dec47364f42fe528c74f2ee07171a337d932b8b7 Mon Sep 17 00:00:00 2001 From: Dragos Avadanei Date: Wed, 12 Apr 2017 12:34:05 -0700 Subject: [PATCH] adding support for backing up and restoring of KeyVault secrets revising KeyVault backup/restore cmdlets: adding support for pipelining allowing overwriting of dest file using session data store for file operations --- .../KeyVault/AzureRM.KeyVault.psd1 | 4 +- .../ControlPlane/KeyVaultManagementTests.ps1 | 4 +- .../Scripts/RunKeyVaultTests.ps1 | 21 +- .../Scripts/VaultKeyTests.ps1 | 34 ++- .../Scripts/VaultSecretTests.ps1 | 103 ++++++++++ .../Commands.KeyVault.csproj | 6 + .../Commands/BackupAzureKeyVaultKey.cs | 125 ++++++++---- .../Commands/BackupAzureKeyVaultSecret.cs | 153 ++++++++++++++ .../Commands/RestoreAzureKeyVaultSecret.cs | 72 +++++++ .../Models/IKeyVaultDataServiceClient.cs | 4 + .../Models/KeyVaultCmdletBase.cs | 13 +- .../Models/KeyVaultDataServiceClient.cs | 50 +++++ .../Properties/Resources.Designer.cs | 53 +++++ .../Properties/Resources.resx | 18 ++ .../help/AzureRM.KeyVault.md | 6 + .../help/Backup-AzureKeyVaultKey.md | 36 +++- .../help/Backup-AzureKeyVaultSecret.md | 193 ++++++++++++++++++ .../help/Restore-AzureKeyVaultSecret.md | 120 +++++++++++ 18 files changed, 957 insertions(+), 58 deletions(-) create mode 100644 src/ResourceManager/KeyVault/Commands.KeyVault/Commands/BackupAzureKeyVaultSecret.cs create mode 100644 src/ResourceManager/KeyVault/Commands.KeyVault/Commands/RestoreAzureKeyVaultSecret.cs create mode 100644 src/ResourceManager/KeyVault/Commands.KeyVault/help/Backup-AzureKeyVaultSecret.md create mode 100644 src/ResourceManager/KeyVault/Commands.KeyVault/help/Restore-AzureKeyVaultSecret.md diff --git a/src/ResourceManager/KeyVault/AzureRM.KeyVault.psd1 b/src/ResourceManager/KeyVault/AzureRM.KeyVault.psd1 index 727e34e49a08..3005c3d26c95 100644 --- a/src/ResourceManager/KeyVault/AzureRM.KeyVault.psd1 +++ b/src/ResourceManager/KeyVault/AzureRM.KeyVault.psd1 @@ -100,7 +100,9 @@ CmdletsToExport = 'Add-AzureKeyVaultCertificate', 'Set-AzureKeyVaultSecretAttribute', 'Get-AzureKeyVaultCertificatePolicy', 'New-AzureKeyVaultCertificateAdministratorDetails', - 'New-AzureKeyVaultCertificateOrganizationDetails' + 'New-AzureKeyVaultCertificateOrganizationDetails', + 'Backup-AzureKeyVaultSecret', + 'Restore-AzureKeyVaultSecret' # Variables to export from this module # VariablesToExport = @() diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault.Test/Scripts/ControlPlane/KeyVaultManagementTests.ps1 b/src/ResourceManager/KeyVault/Commands.KeyVault.Test/Scripts/ControlPlane/KeyVaultManagementTests.ps1 index e6936f79f75c..dae91c927319 100644 --- a/src/ResourceManager/KeyVault/Commands.KeyVault.Test/Scripts/ControlPlane/KeyVaultManagementTests.ps1 +++ b/src/ResourceManager/KeyVault/Commands.KeyVault.Test/Scripts/ControlPlane/KeyVaultManagementTests.ps1 @@ -408,7 +408,7 @@ function Test-SetRemoveAccessPolicyByUPN Param($existingVaultName, $rgName, $upn) $PermToKeys = @("encrypt", "decrypt", "unwrapKey", "wrapKey", "verify", "sign", "get", "list", "update", "create", "import", "delete", "backup", "restore") - $PermToSecrets = @("get", "list", "set", "delete") + $PermToSecrets = @("get", "list", "set", "delete", "backup", "restore") $PermToCertificates = @("get", "list", "create", "delete") $vault = Set-AzureRmKeyVaultAccessPolicy -VaultName $existingVaultName -ResourceGroupName $rgName -UserPrincipalName $upn -PermissionsToKeys $PermToKeys -PermissionsToSecrets $PermToSecrets -PermissionsToCertificates $PermToCertificates -PassThru @@ -566,7 +566,7 @@ function Test-ModifyAccessPolicy # Add some perms now $PermToKeys = @("encrypt", "decrypt", "unwrapKey", "wrapKey", "verify", "sign", "get", "list", "update", "create", "import", "delete", "backup", "restore") - $PermToSecrets = @("get", "list", "set", "delete") + $PermToSecrets = @("get", "list", "set", "delete", "backup", "restore") $PermToCertificates = @("list", "delete") $vault = Set-AzureRmKeyVaultAccessPolicy -VaultName $existingVaultName -ResourceGroupName $rgName -ObjectId $objId -PermissionsToKeys $PermToKeys -PermissionsToSecrets $PermToSecrets -PermissionsToCertificates $PermToCertificates -PassThru diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault.Test/Scripts/RunKeyVaultTests.ps1 b/src/ResourceManager/KeyVault/Commands.KeyVault.Test/Scripts/RunKeyVaultTests.ps1 index ab8ac09b3931..e7f145342620 100644 --- a/src/ResourceManager/KeyVault/Commands.KeyVault.Test/Scripts/RunKeyVaultTests.ps1 +++ b/src/ResourceManager/KeyVault/Commands.KeyVault.Test/Scripts/RunKeyVaultTests.ps1 @@ -323,11 +323,12 @@ function Run-AllDataPlaneTests Run-TestProtected { Run-KeyTest {Test_RemoveKeyInNoPermissionVault} "Test_RemoveKeyInNoPermissionVault" } "Test_RemoveKeyInNoPermissionVault" # Backup-AzureKeyVaultKey and Restore-AzureKeyVaultKey tests. - Run-TestProtected { Run-KeyTest {Test_BackupRestoreKey} "Test_BackupRestoreKey" } "Test_BackupRestoreKey" - Run-TestProtected { Run-KeyTest {Test_BackupNonExisitingKey} "Test_BackupNonExisitingKey" } "Test_BackupNonExisitingKey" - Run-TestProtected { Run-KeyTest {Test_BackupToANamedFile} "Test_BackupToANamedFile" } "Test_BackupToANamedFile" - Run-TestProtected { Run-KeyTest {Test_BackupToExistingFile} "Test_BackupToExistingFile" } "Test_BackupToExistingFile" - Run-TestProtected { Run-KeyTest {Test_RestoreFromNonExistingFile} "Test_RestoreFromNonExistingFile" } "Test_RestoreFromNonExistingFile" + Run-TestProtected { Run-KeyTest {Test_BackupRestoreKeyByName} "Test_BackupRestoreKeyByName" } "Test_BackupRestoreKeyByName" + Run-TestProtected { Run-KeyTest {Test_BackupRestoreKeyByRef} "Test_BackupRestoreKeyByRef" } "Test_BackupRestoreKeyByRef" + Run-TestProtected { Run-KeyTest {Test_BackupNonExistingKey} "Test_BackupNonExistingKey" } "Test_BackupNonExistingKey" + Run-TestProtected { Run-KeyTest {Test_BackupKeyToANamedFile} "Test_BackupKeyToANamedFile" } "Test_BackupKeyToANamedFile" + Run-TestProtected { Run-KeyTest {Test_BackupKeyToExistingFile} "Test_BackupKeyToExistingFile" } "Test_BackupKeyToExistingFile" + Run-TestProtected { Run-KeyTest {Test_RestoreKeyFromNonExistingFile} "Test_RestoreKeyFromNonExistingFile" } "Test_RestoreKeyFromNonExistingFile" # *-AzureRmKeyVaultKey pipeline tests. Run-TestProtected { Run-KeyTest {Test_PipelineUpdateKeys} "Test_PipelineUpdateKeys" } "Test_PipelineUpdateKeys" @@ -376,7 +377,15 @@ function Run-AllDataPlaneTests Run-TestProtected { Run-SecretTest {Test_RemoveNonExistSecret} "Test_RemoveNonExistSecret" } "Test_RemoveNonExistSecret" Run-TestProtected { Run-SecretTest {Test_RemoveSecretInNoPermissionVault} "Test_RemoveSecretInNoPermissionVault" } "Test_RemoveSecretInNoPermissionVault" - # *-AzureRmKeyVaultKey pipeline tests. + # Backup-AzureKeyVaultSecret and Restore-AzureKeyVaultSecret tests. + Run-TestProtected { Run-SecretTest {Test_BackupRestoreSecretByName} "Test_BackupRestoreSecretByName" } "Test_BackupRestoreSecretByName" + Run-TestProtected { Run-SecretTest {Test_BackupRestoreSecretByRef} "Test_BackupRestoreSecretByRef" } "Test_BackupRestoreSecretByRef" + Run-TestProtected { Run-SecretTest {Test_BackupNonExistingSecret} "Test_BackupNonExistingSecret" } "Test_BackupNonExistingSecret" + Run-TestProtected { Run-SecretTest {Test_BackupSecretToANamedFile} "Test_BackupSecretToANamedFile" } "Test_BackupSecretToANamedFile" + Run-TestProtected { Run-SecretTest {Test_BackupSecretToExistingFile} "Test_BackupSecretToExistingFile" } "Test_BackupSecretToExistingFile" + Run-TestProtected { Run-SecretTest {Test_RestoreSecretFromNonExistingFile} "Test_RestoreSecretFromNonExistingFile" } "Test_RestoreSecretFromNonExistingFile" + + # *-AzureRmKeyVaultSecret pipeline tests. Run-TestProtected { Run-SecretTest {Test_PipelineUpdateSecrets} "Test_PipelineUpdateSecrets" } "Test_PipelineUpdateSecrets" Run-TestProtected { Run-SecretTest {Test_PipelineUpdateSecretAttributes} "Test_PipelineUpdateSecretAttributes" } "Test_PipelineUpdateSecretAttributes" Run-TestProtected { Run-SecretTest {Test_PipelineUpdateSecretVersions} "Test_PipelineUpdateSecretVersions" } "Test_PipelineUpdateSecretVersions" diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault.Test/Scripts/VaultKeyTests.ps1 b/src/ResourceManager/KeyVault/Commands.KeyVault.Test/Scripts/VaultKeyTests.ps1 index 160cc7a6f8ca..fca46add3eda 100644 --- a/src/ResourceManager/KeyVault/Commands.KeyVault.Test/Scripts/VaultKeyTests.ps1 +++ b/src/ResourceManager/KeyVault/Commands.KeyVault.Test/Scripts/VaultKeyTests.ps1 @@ -838,9 +838,9 @@ function Test_RemoveKeyInNoPermissionVault <# .SYNOPSIS -Tests backup and restore a key +Tests backup and restore a key by name #> -function Test_BackupRestoreKey +function Test_BackupRestoreKeyByName { $keyVault = Get-KeyVault $keyname=Get-KeyName 'backuprestore' @@ -858,9 +858,27 @@ function Test_BackupRestoreKey <# .SYNOPSIS -Tests backup a none existing key +Tests backup and restore a key by object #> -function Test_BackupNonExisitingKey +function Test_BackupRestoreKeyByRef +{ + $keyVault = Get-KeyVault + $keyname=Get-KeyName 'backuprestore' + $key=Add-AzureKeyVaultKey -VaultName $keyVault -Name $keyname -Destination 'Software' + Assert-NotNull $key + $global:createdKeys += $keyname + + $backupblob = Backup-AzureKeyVaultKey -Key $key + Remove-AzureKeyVaultKey -VaultName $keyVault -Name $keyname -Force -Confirm:$false + $restoredKey = Restore-AzureKeyVaultKey -VaultName $keyVault -InputFile $backupblob + Assert-KeyAttributes $restoredKey.Attributes 'RSA' $true $null $null $null +} + +<# +.SYNOPSIS +Tests backup a non-existing key +#> +function Test_BackupNonExistingKey { $keyVault = Get-KeyVault $keyname=Get-KeyName 'backupnonexisting' @@ -872,7 +890,7 @@ function Test_BackupNonExisitingKey .SYNOPSIS Tests backup a key to a specific file and be able to restore #> -function Test_BackupToANamedFile +function Test_BackupKeyToANamedFile { $keyVault = Get-KeyVault $keyname=Get-KeyName 'backupnamedfile' @@ -894,7 +912,7 @@ function Test_BackupToANamedFile .SYNOPSIS Tests backup a key to a specific file which exists #> -function Test_BackupToExistingFile +function Test_BackupKeyToExistingFile { $keyVault = Get-KeyVault $keyname=Get-KeyName 'backupexistingfile' @@ -905,7 +923,7 @@ function Test_BackupToExistingFile $backupfile='.\backup' + ([GUID]::NewGuid()).GUID.ToString() + '.blob' Backup-AzureKeyVaultKey -VaultName $keyVault -KeyName $keyname -OutputFile $backupfile - Assert-Throws { Backup-AzureKeyVaultKey -VaultName $keyVault -KeyName $keyname -OutputFile $backupfile } + Backup-AzureKeyVaultKey -VaultName $keyVault -KeyName $keyname -OutputFile $backupfile -Force -Confirm:$false } @@ -913,7 +931,7 @@ function Test_BackupToExistingFile .SYNOPSIS Tests restore a key from a none existing file #> -function Test_RestoreFromNonExistingFile +function Test_RestoreKeyFromNonExistingFile { $keyVault = Get-KeyVault diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault.Test/Scripts/VaultSecretTests.ps1 b/src/ResourceManager/KeyVault/Commands.KeyVault.Test/Scripts/VaultSecretTests.ps1 index 81847234b9da..4a56a775378a 100644 --- a/src/ResourceManager/KeyVault/Commands.KeyVault.Test/Scripts/VaultSecretTests.ps1 +++ b/src/ResourceManager/KeyVault/Commands.KeyVault.Test/Scripts/VaultSecretTests.ps1 @@ -656,6 +656,109 @@ function Test_RemoveSecretInNoPermissionVault Assert-Throws {Remove-AzureKeyVaultSecret -VaultName $keyVault -Name $secretname -Force -Confirm:$false} } +<# +.SYNOPSIS +Tests backup and restoring of a secret by name +#> +function Test_BackupRestoreSecretByName +{ + $keyVault = Get-KeyVault + $name=Get-SecretName 'backuprestore' + $secret=Set-AzureKeyVaultSecret -VaultName $keyVault -Name $name -SecretValue $securedata + Assert-NotNull $secret + $global:createdSecrets += $name + + $backupblob = Backup-AzureKeyVaultSecret -VaultName $keyVault -SecretName $name + Remove-AzureKeyVaultSecret -VaultName $keyVault -Name $name -Force -Confirm:$false + $restoredSecret = Restore-AzureKeyVaultSecret -VaultName $keyVault -InputFile $backupblob + + $retrievedSecret = Get-AzureKeyVaultSecret -VaultName $keyVault -SecretName $name + Assert-AreEqual $retrievedSecret.SecretValueText $data +} + +<# +.SYNOPSIS +Tests backup and restoring of a secret by object +#> +function Test_BackupRestoreSecretByRef +{ + $keyVault = Get-KeyVault + $name=Get-SecretName 'backuprestore' + $secret=Set-AzureKeyVaultSecret -VaultName $keyVault -Name $name -SecretValue $securedata + Assert-NotNull $secret + $global:createdSecrets += $name + + $backupblob = Backup-AzureKeyVaultSecret -Secret $secret + Remove-AzureKeyVaultSecret -VaultName $keyVault -Name $name -Force -Confirm:$false + $restoredSecret = Restore-AzureKeyVaultSecret -VaultName $keyVault -InputFile $backupblob + + $retrievedSecret = Get-AzureKeyVaultSecret -VaultName $keyVault -SecretName $name + Assert-AreEqual $retrievedSecret.SecretValueText $data +} + +<# +.SYNOPSIS +Tests backup of a non-existing secret +#> +function Test_BackupNonExistingSecret +{ + $keyVault = Get-KeyVault + $name=Get-SecretName 'backupnonexisting' + + Assert-Throws { Backup-AzureKeyVaultSecret -VaultName $keyVault -SecretName $name } +} + +<# +.SYNOPSIS +Tests backup of a secret to a specific file and ability to restore +#> +function Test_BackupSecretToANamedFile +{ + $keyVault = Get-KeyVault + $name=Get-SecretName 'backupnamedfile' + $secret=Set-AzureKeyVaultSecret -VaultName $keyVault -Name $name -SecretValue $securedata + Assert-NotNull $secret + $global:createdSecrets += $name + + $backupfile='.\backup' + ([GUID]::NewGuid()).GUID.ToString() + '.blob' + + Backup-AzureKeyVaultSecret -VaultName $keyVault -SecretName $name -OutputFile $backupfile + Remove-AzureKeyVaultSecret -VaultName $keyVault -Name $name -Force -Confirm:$false + $restoredSecret = Restore-AzureKeyVaultSecret -VaultName $keyVault -InputFile $backupfile + + $retrievedSecret = Get-AzureKeyVaultSecret -VaultName $keyVault -SecretName $name + Assert-AreEqual $retrievedSecret.SecretValueText $data +} + +<# +.SYNOPSIS +Tests backup of a key to a specific, existing file +#> +function Test_BackupSecretToExistingFile +{ + $keyVault = Get-KeyVault + $name=Get-SecretName 'backupexistingfile' + $secret=Set-AzureKeyVaultSecret -VaultName $keyVault -Name $name -SecretValue $securedata + Assert-NotNull $secret + $global:createdSecrets += $name + + $backupfile='.\backup' + ([GUID]::NewGuid()).GUID.ToString() + '.blob' + Backup-AzureKeyVaultSecret -VaultName $keyVault -SecretName $name -OutputFile $backupfile + Backup-AzureKeyVaultSecret -VaultName $keyVault -SecretName $name -OutputFile $backupfile -Force -Confirm:$false +} + + +<# +.SYNOPSIS +Tests restoring a secret from a non-existing file +#> +function Test_RestoreSecretFromNonExistingFile +{ + $keyVault = Get-KeyVault + + Assert-Throws { Restore-AzureKeyVaultSecret -VaultName $keyVault -InputFile c:\nonexisting.blob } +} + <# .SYNOPSIS Tests pipeline commands to update values of multiple secrets diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault/Commands.KeyVault.csproj b/src/ResourceManager/KeyVault/Commands.KeyVault/Commands.KeyVault.csproj index f24670cb00bb..4acd90f22366 100644 --- a/src/ResourceManager/KeyVault/Commands.KeyVault/Commands.KeyVault.csproj +++ b/src/ResourceManager/KeyVault/Commands.KeyVault/Commands.KeyVault.csproj @@ -52,6 +52,8 @@ + + @@ -261,6 +263,10 @@ {3819d8a7-c62c-4c47-8ddd-0332d9ce1252} Commands.ResourceManager.Common + + {142d7b0b-388a-4ceb-a228-7f6d423c5c2e} + Commands.Profile + {e1f5201d-6067-430e-b303-4e367652991b} Commands.Resources diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault/Commands/BackupAzureKeyVaultKey.cs b/src/ResourceManager/KeyVault/Commands.KeyVault/Commands/BackupAzureKeyVaultKey.cs index e22173e016aa..293872589865 100644 --- a/src/ResourceManager/KeyVault/Commands.KeyVault/Commands/BackupAzureKeyVaultKey.cs +++ b/src/ResourceManager/KeyVault/Commands.KeyVault/Commands/BackupAzureKeyVaultKey.cs @@ -12,10 +12,10 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using Microsoft.Azure.Commands.KeyVault.Models; using System; -using System.IO; using System.Management.Automation; +using Microsoft.Azure.Commands.Common.Authentication; +using Microsoft.Azure.Commands.KeyVault.Models; using KeyVaultProperties = Microsoft.Azure.Commands.KeyVault.Properties; namespace Microsoft.Azure.Commands.KeyVault @@ -23,33 +23,58 @@ namespace Microsoft.Azure.Commands.KeyVault /// /// Requests that a backup of the specified key be downloaded and stored to a file /// + /// + /// The cmdlet returns the path of the newly created backup file. + /// [Cmdlet(VerbsData.Backup, "AzureKeyVaultKey", SupportsShouldProcess = true, HelpUri = Constants.KeyVaultHelpUri)] [OutputType(typeof(String))] public class BackupAzureKeyVaultKey : KeyVaultCmdletBase { - public static readonly DateTime EpochDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + #region parameter sets + + private const string ByKeyNameParameterSet = "ByKeyName"; + private const string ByKeyObjectParameterSet = "ByKey"; + + #endregion #region Input Parameter Definitions /// /// Vault name /// - [Parameter(Mandatory = true, - Position = 0, - ValueFromPipelineByPropertyName = true, - HelpMessage = "Vault name. Cmdlet constructs the FQDN of a vault based on the name and currently selected environment.")] + [Parameter( Mandatory = true, + Position = 0, + ValueFromPipelineByPropertyName = true, + ParameterSetName = ByKeyNameParameterSet, + HelpMessage = "Vault name. Cmdlet constructs the FQDN of a vault based on the name and currently selected environment.")] [ValidateNotNullOrEmpty] public string VaultName { get; set; } + /// + /// KeyBundle object to be backed up. + /// + /// + /// Note that the backup applies to the entire family of a key (current and all its versions); + /// since a key bundle represents a single version, the intent of this parameter is to allow pipelining. + /// The backup cmdlet will use the Name and VaultName properties of the KeyBundle parameter. + /// + [Parameter( Mandatory = true, + Position = 0, + ValueFromPipelineByPropertyName = true, + ParameterSetName = ByKeyObjectParameterSet, + HelpMessage = "Key bundle to back up, pipelined in from the output of a retrieval call." )] + public KeyBundle Key { get; set; } + /// /// Key name /// - [Parameter(Mandatory = true, - Position = 1, - ValueFromPipelineByPropertyName = true, - HelpMessage = "Key name. Cmdlet constructs the FQDN of a key from vault name, currently selected environment and key name.")] + [Parameter( Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true, + ParameterSetName = ByKeyNameParameterSet, + HelpMessage = "Key name. Cmdlet constructs the FQDN of a key from vault name, currently selected environment and key name.")] [ValidateNotNullOrEmpty] [Alias(Constants.KeyName)] public string Name { get; set; } @@ -57,47 +82,71 @@ public class BackupAzureKeyVaultKey : KeyVaultCmdletBase /// /// The output file in which the backup blob is to be stored /// - [Parameter(Mandatory = false, - Position = 2, - ValueFromPipelineByPropertyName = true, - HelpMessage = "Output file. The output file to store the backed up key blob in. If not present, a default filename is chosen.")] + [Parameter( Mandatory = false, + Position = 2, + ValueFromPipelineByPropertyName = true, + ParameterSetName = ByKeyNameParameterSet, + HelpMessage = "Output file. The output file to store the backed up key blob in. If not present, a default filename is chosen.")] + [Parameter( Mandatory = false, + Position = 2, + ValueFromPipelineByPropertyName = true, + ParameterSetName = ByKeyObjectParameterSet, + HelpMessage = "Output file. The output file to store the backed up key blob in. If not present, a default filename is chosen." )] [ValidateNotNullOrEmpty] public string OutputFile { get; set; } + /// + /// Instructs the cmdlet to overwrite the destination file, if it exists. + /// + [Parameter( Mandatory = false, + Position = 3, + ValueFromPipelineByPropertyName = true, + ParameterSetName = ByKeyNameParameterSet, + HelpMessage = "Overwrite the given file if it exists" )] + [Parameter( Mandatory = false, + Position = 3, + ValueFromPipelineByPropertyName = true, + ParameterSetName = ByKeyObjectParameterSet, + HelpMessage = "Overwrite the given file if it exists" )] + public SwitchParameter Force { get; set; } + #endregion Input Parameter Definition public override void ExecuteCmdlet() { - if (ShouldProcess(Name, Properties.Resources.BackupKey)) + switch ( ParameterSetName ) { - if (string.IsNullOrEmpty(OutputFile)) - { - OutputFile = GetDefaultFile(); - } + case ByKeyNameParameterSet: + // no op + break; - var filePath = ResolvePath(OutputFile); + case ByKeyObjectParameterSet: + Name = Key.Name; + VaultName = Key.VaultName; + break; - var backupBlobPath = this.DataServiceClient.BackupKey(VaultName, Name, filePath); - - this.WriteObject(backupBlobPath); + default: + throw new ArgumentException( KeyVaultProperties.Resources.BadParameterSetName ); } - } - private string GetDefaultFile() - { - var currentPath = CurrentPath(); - var filename = string.Format("{0}\\backup-{1}-{2}-{3}", currentPath, VaultName, Name, DateTime.UtcNow.Subtract(EpochDate).TotalSeconds); - return filename; - } - - private string ResolvePath(string filePath) - { - FileInfo keyFile = new FileInfo(this.GetUnresolvedProviderPathFromPSPath(filePath)); - if (keyFile.Exists) + if ( ShouldProcess(Name, Properties.Resources.BackupKey)) { - throw new IOException(string.Format(KeyVaultProperties.Resources.BackupKeyFileAlreadyExists, filePath)); + if (string.IsNullOrEmpty(OutputFile)) + { + OutputFile = GetDefaultFileForOperation("backup", VaultName, Name); + } + + var filePath = this.GetUnresolvedProviderPathFromPSPath(OutputFile); + + // deny request if the file exists and overwrite is not authorized + if ( !AzureSession.DataStore.FileExists( filePath ) + || Force.IsPresent + || ShouldContinue( string.Format( KeyVaultProperties.Resources.FileOverwriteMessage, filePath ), KeyVaultProperties.Resources.FileOverwriteCaption ) ) + { + var backupBlobPath = this.DataServiceClient.BackupKey(VaultName, Name, filePath); + this.WriteObject( backupBlobPath ); + } } - return keyFile.FullName; } } } diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault/Commands/BackupAzureKeyVaultSecret.cs b/src/ResourceManager/KeyVault/Commands.KeyVault/Commands/BackupAzureKeyVaultSecret.cs new file mode 100644 index 000000000000..79ee36fda151 --- /dev/null +++ b/src/ResourceManager/KeyVault/Commands.KeyVault/Commands/BackupAzureKeyVaultSecret.cs @@ -0,0 +1,153 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System; +using System.Management.Automation; +using Microsoft.Azure.Commands.Common.Authentication; +using Microsoft.Azure.Commands.KeyVault.Models; +using KeyVaultProperties = Microsoft.Azure.Commands.KeyVault.Properties; + +namespace Microsoft.Azure.Commands.KeyVault +{ + /// + /// Requests that a backup of the specified key be downloaded and stored to a file + /// + /// + /// The cmdlet returns the path of the newly created backup file. + /// + [Cmdlet( VerbsData.Backup, "AzureKeyVaultSecret", + SupportsShouldProcess = true, + HelpUri = Constants.KeyVaultHelpUri )] + [OutputType( typeof( String ) )] + public class BackupAzureKeyVaultSecret : KeyVaultCmdletBase + { + #region parameter sets + + private const string BySecretNameParameterSet = "BySecretName"; + private const string BySecretObjectParameterSet = "BySecret"; + + #endregion + + #region Input Parameter Definitions + + /// + /// Vault name + /// + [Parameter( Mandatory = true, + Position = 0, + ValueFromPipelineByPropertyName = true, + ParameterSetName = BySecretNameParameterSet, + HelpMessage = "Vault name. Cmdlet constructs the FQDN of a vault based on the name and currently selected environment." )] + [ValidateNotNullOrEmpty] + public string VaultName { get; set; } + + /// + /// The secret object to be backed up. + /// + /// + /// Note that the backup applies to the entire family of a secret (current and all its versions); + /// since a key bundle represents a single version, the intent of this parameter is to allow pipelining. + /// The backup cmdlet will use the Name and VaultName properties of the KeyBundle parameter. + /// + [Parameter( Mandatory = true, + Position = 0, + ValueFromPipelineByPropertyName = true, + ParameterSetName = BySecretObjectParameterSet, + HelpMessage = "Secret to be backed up, pipelined in from the output of a retrieval call." )] + [ValidateNotNullOrEmpty] + public Secret Secret { get; set; } + + /// + /// Secret name + /// + [Parameter( Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true, + ParameterSetName = BySecretNameParameterSet, + HelpMessage = "Secret name. Cmdlet constructs the FQDN of a secret from vault name, currently selected environment and secret name." )] + [ValidateNotNullOrEmpty] + [Alias( Constants.SecretName )] + public string Name { get; set; } + + /// + /// The output file in which the backup blob is to be stored + /// + [Parameter( Mandatory = false, + Position = 2, + ValueFromPipelineByPropertyName = true, + ParameterSetName = BySecretNameParameterSet, + HelpMessage = "Output file. The output file to store the backed up secret blob in. If not present, a default filename is chosen." )] + [Parameter( Mandatory = false, + Position = 2, + ValueFromPipelineByPropertyName = true, + ParameterSetName = BySecretObjectParameterSet, + HelpMessage = "Output file. The output file to store the backed up secret blob in. If not present, a default filename is chosen." )] + [ValidateNotNullOrEmpty] + public string OutputFile { get; set; } + + /// + /// Instructs the cmdlet to overwrite the destination file, if it exists. + /// + [Parameter( Mandatory = false, + Position = 3, + ValueFromPipelineByPropertyName = true, + ParameterSetName = BySecretNameParameterSet, + HelpMessage = "Overwrite the given file if it exists" )] + [Parameter( Mandatory = false, + Position = 3, + ValueFromPipelineByPropertyName = true, + ParameterSetName = BySecretObjectParameterSet, + HelpMessage = "Overwrite the given file if it exists" )] + public SwitchParameter Force { get; set; } + + #endregion Input Parameter Definition + + public override void ExecuteCmdlet( ) + { + switch ( ParameterSetName ) + { + case BySecretNameParameterSet: + // no op + break; + + case BySecretObjectParameterSet: + Name = Secret.Name; + VaultName = Secret.VaultName; + break; + + default: + throw new ArgumentException( KeyVaultProperties.Resources.BadParameterSetName ); + } + + if ( ShouldProcess( Name, Properties.Resources.BackupSecret ) ) + { + if ( string.IsNullOrEmpty( OutputFile ) ) + { + OutputFile = GetDefaultFileForOperation( "backup", VaultName, Name ); + } + + var filePath = this.GetUnresolvedProviderPathFromPSPath(OutputFile); + + // deny request if the file exists and overwrite is not authorized + if ( !AzureSession.DataStore.FileExists( filePath ) + || Force.IsPresent + || ShouldContinue( string.Format( KeyVaultProperties.Resources.FileOverwriteMessage, filePath ), KeyVaultProperties.Resources.FileOverwriteCaption ) ) + { + var backupBlobPath = this.DataServiceClient.BackupSecret(VaultName, Name, filePath); + this.WriteObject( backupBlobPath ); + } + } + } + } +} diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault/Commands/RestoreAzureKeyVaultSecret.cs b/src/ResourceManager/KeyVault/Commands.KeyVault/Commands/RestoreAzureKeyVaultSecret.cs new file mode 100644 index 000000000000..9a549190f0c4 --- /dev/null +++ b/src/ResourceManager/KeyVault/Commands.KeyVault/Commands/RestoreAzureKeyVaultSecret.cs @@ -0,0 +1,72 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.KeyVault.Models; +using System.IO; +using System.Management.Automation; +using KeyVaultProperties = Microsoft.Azure.Commands.KeyVault.Properties; +using Microsoft.Azure.Commands.Common.Authentication; + +namespace Microsoft.Azure.Commands.KeyVault +{ + /// + /// Restores the backup secret into a vault + /// + [Cmdlet( VerbsData.Restore, "AzureKeyVaultSecret", + SupportsShouldProcess = true, + HelpUri = Constants.KeyVaultHelpUri )] + [OutputType( typeof( Secret ) )] + public class RestoreAzureKeyVaultSecret : KeyVaultCmdletBase + { + #region Input Parameter Definitions + + /// + /// Vault name + /// + [Parameter( Mandatory = true, + Position = 0, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Vault name. Cmdlet constructs the FQDN of a vault based on the name and currently selected environment." )] + [ValidateNotNullOrEmpty] + public string VaultName { get; set; } + + /// + /// The input file in which the backup blob is stored + /// + [Parameter( Mandatory = true, + Position = 1, + HelpMessage = "Input file. The input file containing the backed-up blob" )] + [ValidateNotNullOrEmpty] + public string InputFile { get; set; } + + #endregion Input Parameter Definitions + + public override void ExecuteCmdlet( ) + { + if ( ShouldProcess( VaultName, Properties.Resources.RestoreSecret ) ) + { + var resolvedFilePath = this.GetUnresolvedProviderPathFromPSPath( InputFile ); + + if ( !AzureSession.DataStore.FileExists( resolvedFilePath ) ) + { + throw new FileNotFoundException( string.Format( KeyVaultProperties.Resources.BackupSecretFileNotFound, resolvedFilePath ) ); + } + + var restoredSecret = this.DataServiceClient.RestoreSecret(VaultName, resolvedFilePath); + + this.WriteObject( restoredSecret ); + } + } + } +} diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault/Models/IKeyVaultDataServiceClient.cs b/src/ResourceManager/KeyVault/Commands.KeyVault/Models/IKeyVaultDataServiceClient.cs index 49ee0eb8e836..e74dc9660eaf 100644 --- a/src/ResourceManager/KeyVault/Commands.KeyVault/Models/IKeyVaultDataServiceClient.cs +++ b/src/ResourceManager/KeyVault/Commands.KeyVault/Models/IKeyVaultDataServiceClient.cs @@ -68,6 +68,10 @@ public interface IKeyVaultDataServiceClient KeyBundle RestoreKey(string vaultName, string inputBlobPath); + string BackupSecret(string vaultName, string secretName, string outputBlobPath); + + Secret RestoreSecret(string vaultName, string inputBlobPath); + #region Certificate actions Contacts SetCertificateContacts(string vaultName, Contacts contacts); diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault/Models/KeyVaultCmdletBase.cs b/src/ResourceManager/KeyVault/Commands.KeyVault/Models/KeyVaultCmdletBase.cs index ac1c19c337a8..cefaaa93f1b0 100644 --- a/src/ResourceManager/KeyVault/Commands.KeyVault/Models/KeyVaultCmdletBase.cs +++ b/src/ResourceManager/KeyVault/Commands.KeyVault/Models/KeyVaultCmdletBase.cs @@ -12,9 +12,10 @@ // limitations under the License. // ---------------------------------------------------------------------------------- +using System; +using System.IO; using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.ResourceManager.Common; -using System; using System.Collections.Generic; using System.Net.Http; @@ -22,6 +23,8 @@ namespace Microsoft.Azure.Commands.KeyVault.Models { public class KeyVaultCmdletBase : AzureRMCmdlet { + public static readonly DateTime EpochDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + internal IKeyVaultDataServiceClient DataServiceClient { get @@ -41,6 +44,14 @@ internal IKeyVaultDataServiceClient DataServiceClient } } + protected string GetDefaultFileForOperation( string operationName, string vaultName, string entityName ) + { + // caller is responsible for parameter validation + var currentPath = CurrentPath(); + var filename = string.Format("{0}\\{1}-{2}-{3}", currentPath, vaultName, entityName, DateTime.UtcNow.Subtract(EpochDate).TotalSeconds); + + return filename; + } private IKeyVaultDataServiceClient dataServiceClient; diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault/Models/KeyVaultDataServiceClient.cs b/src/ResourceManager/KeyVault/Commands.KeyVault/Models/KeyVaultDataServiceClient.cs index 55a2ca9f606f..9e6a94f57efe 100644 --- a/src/ResourceManager/KeyVault/Commands.KeyVault/Models/KeyVaultDataServiceClient.cs +++ b/src/ResourceManager/KeyVault/Commands.KeyVault/Models/KeyVaultDataServiceClient.cs @@ -847,6 +847,56 @@ public KeyBundle RestoreKey(string vaultName, string inputBlobPath) return new KeyBundle(keyBundle, this.vaultUriHelper); } + public string BackupSecret( string vaultName, string secretName, string outputBlobPath ) + { + if ( string.IsNullOrEmpty( vaultName ) ) + throw new ArgumentNullException( "vaultName" ); + if ( string.IsNullOrEmpty( secretName ) ) + throw new ArgumentNullException( "secretName" ); + if ( string.IsNullOrEmpty( outputBlobPath ) ) + throw new ArgumentNullException( "outputBlobPath" ); + + string vaultAddress = this.vaultUriHelper.CreateVaultAddress(vaultName); + + BackupSecretResult backupSecretResult; + try + { + backupSecretResult = this.keyVaultClient.BackupSecretAsync( vaultAddress, secretName ).GetAwaiter( ).GetResult( ); + } + catch ( Exception ex ) + { + throw GetInnerException( ex ); + } + + File.WriteAllBytes( outputBlobPath, backupSecretResult.Value ); + + return outputBlobPath; + } + + public Secret RestoreSecret( string vaultName, string inputBlobPath ) + { + if ( string.IsNullOrEmpty( vaultName ) ) + throw new ArgumentNullException( "vaultName" ); + if ( string.IsNullOrEmpty( inputBlobPath ) ) + throw new ArgumentNullException( "inputBlobPath" ); + + var backupBlob = File.ReadAllBytes(inputBlobPath); + + string vaultAddress = this.vaultUriHelper.CreateVaultAddress(vaultName); + + Azure.KeyVault.Models.SecretBundle secretBundle; + try + { + secretBundle = this.keyVaultClient.RestoreSecretAsync( vaultAddress, backupBlob ).GetAwaiter( ).GetResult( ); + } + catch ( Exception ex ) + { + throw GetInnerException( ex ); + } + + return new Secret( secretBundle, this.vaultUriHelper ); + } + public CertificatePolicy GetCertificatePolicy(string vaultName, string certificateName) { if (string.IsNullOrEmpty(vaultName)) diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault/Properties/Resources.Designer.cs b/src/ResourceManager/KeyVault/Commands.KeyVault/Properties/Resources.Designer.cs index 940d256987aa..ff63cf4038df 100644 --- a/src/ResourceManager/KeyVault/Commands.KeyVault/Properties/Resources.Designer.cs +++ b/src/ResourceManager/KeyVault/Commands.KeyVault/Properties/Resources.Designer.cs @@ -153,6 +153,33 @@ internal static string BackupKeyFileNotFound { } } + /// + /// Looks up a localized string similar to Backup secret. + /// + internal static string BackupSecret { + get { + return ResourceManager.GetString("BackupSecret", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The backup secret file '{0}' already exists.. + /// + internal static string BackupSecretFileAlreadyExists { + get { + return ResourceManager.GetString("BackupSecretFileAlreadyExists", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cannot find backup secret file '{0}'. + /// + internal static string BackupSecretFileNotFound { + get { + return ResourceManager.GetString("BackupSecretFileNotFound", resourceCulture); + } + } + /// /// Looks up a localized string similar to Bad Parameter Set Name. /// @@ -216,6 +243,23 @@ internal static string DeletedVaultNotFound { } } + /// Looks up a localized string similar to Overwrite File ?. + /// + internal static string FileOverwriteCaption { + get { + return ResourceManager.GetString("FileOverwriteCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Overwrite existing file at '{0}' ?. + /// + internal static string FileOverwriteMessage { + get { + return ResourceManager.GetString("FileOverwriteMessage", resourceCulture); + } + } + /// /// Looks up a localized string similar to BYOK key can not be imported as software key. /// @@ -666,6 +710,15 @@ internal static string RestoreKey { } } + /// + /// Looks up a localized string similar to Restore secret. + /// + internal static string RestoreSecret { + get { + return ResourceManager.GetString("RestoreSecret", resourceCulture); + } + } + /// /// Looks up a localized string similar to Set certificate attribute. /// diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault/Properties/Resources.resx b/src/ResourceManager/KeyVault/Commands.KeyVault/Properties/Resources.resx index c496391facc4..c3c3c4c885bb 100644 --- a/src/ResourceManager/KeyVault/Commands.KeyVault/Properties/Resources.resx +++ b/src/ResourceManager/KeyVault/Commands.KeyVault/Properties/Resources.resx @@ -135,6 +135,12 @@ You can find the object ID using Azure Active Directory Module for Windows Power Cannot find backup key file '{0}' + + The backup secret file '{0}' already exists. + + + Cannot find backup secret file '{0}' + Bad Parameter Set Name @@ -276,6 +282,9 @@ You can find the object ID using Azure Active Directory Module for Windows Power Backup key + + Backup secret + Create certificate administrator @@ -324,6 +333,9 @@ You can find the object ID using Azure Active Directory Module for Windows Power Restore key + + Restore secret + Set vault access policy @@ -363,4 +375,10 @@ You can find the object ID using Azure Active Directory Module for Windows Power Cannot find deleted vault '{0}' in location '{1}' + + Overwrite File ? + + + Overwrite existing file at '{0}' ? + \ No newline at end of file diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault/help/AzureRM.KeyVault.md b/src/ResourceManager/KeyVault/Commands.KeyVault/help/AzureRM.KeyVault.md index 26046d68da88..166c9978c11e 100644 --- a/src/ResourceManager/KeyVault/Commands.KeyVault/help/AzureRM.KeyVault.md +++ b/src/ResourceManager/KeyVault/Commands.KeyVault/help/AzureRM.KeyVault.md @@ -23,6 +23,9 @@ Creates a key in a key vault or imports a key into a key vault. ### [Backup-AzureKeyVaultKey](Backup-AzureKeyVaultKey.md) Backs up a key in a key vault. +### [Backup-AzureKeyVaultSecret](Backup-AzureKeyVaultSecret.md) +Backs up a secret in a key vault. + ### [Get-AzureKeyVaultCertificate](Get-AzureKeyVaultCertificate.md) Gets a certificate from a key vault. @@ -89,6 +92,9 @@ Removes all permissions for a user or application from a key vault. ### [Restore-AzureKeyVaultKey](Restore-AzureKeyVaultKey.md) Creates a key in a key vault from a backed-up key. +### [Restore-AzureKeyVaultSecret](Restore-AzureKeyVaultSecret.md) +Creates a secret in a key vault from a backed-up secret. + ### [Set-AzureKeyVaultCertificateAttribute](Set-AzureKeyVaultCertificateAttribute.md) Modifies editable attributes of a certificate. diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault/help/Backup-AzureKeyVaultKey.md b/src/ResourceManager/KeyVault/Commands.KeyVault/help/Backup-AzureKeyVaultKey.md index 30f059493b5d..0ab0f46b36f9 100644 --- a/src/ResourceManager/KeyVault/Commands.KeyVault/help/Backup-AzureKeyVaultKey.md +++ b/src/ResourceManager/KeyVault/Commands.KeyVault/help/Backup-AzureKeyVaultKey.md @@ -12,11 +12,17 @@ Backs up a key in a key vault. ## SYNTAX +### ByKeyName ``` Backup-AzureKeyVaultKey [-VaultName] [-Name] [[-OutputFile] ] [-WhatIf] [-Confirm] [] ``` +### ByKey +``` +Backup-AzureKeyVaultKey -Key [[-OutputFile] ] [-WhatIf] [-Confirm] [] +``` + ## DESCRIPTION The **Backup-AzureKeyVaultKey** cmdlet backs up a specified key in a key vault by downloading it and storing it in a file. If there are multiple versions of the key, all versions are included in the backup. @@ -46,14 +52,37 @@ PS C:\>Backup-AzureKeyVaultKey -VaultName 'MyKeyVault' -Name 'MyKey' -OutputFile This command retrieves the key named MyKey from the key vaultnamed MyKeyVault and saves a backup of that key to a file named Backup.blob. +### Example 3: Back up a previously retrieved key to a specified file name, overwriting the destination file without prompting. +``` +PS C:\>$key = Get-AzureKeyVaultKey -VaultName 'MyKeyVault' -Name 'MyKey' +PS C:\>Backup-AzureKeyVaultKey -Key $key -OutputFile 'C:\Backup.blob' -Force +``` + +This command creates a backup of the key named $key.Name in the vault named $key.VaultName to a file named Backup.blob, silently overwriting the file if it exists already. + ## PARAMETERS +### -Key +Specifies a previously retrieved key which is to be backed up. + +```yaml +Type: KeyBundle +Parameter Sets: ByKey +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + ### -Name Specifies the name of the key to back up. ```yaml Type: String -Parameter Sets: (All) +Parameter Sets: ByKeyName Aliases: KeyName Required: True @@ -85,7 +114,7 @@ Specifies the name of the key vault that contains the key to back up. ```yaml Type: String -Parameter Sets: (All) +Parameter Sets: ByKeyName Aliases: Required: True @@ -133,6 +162,9 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable ## OUTPUTS +### String +The cmdlet returns the path of the output file containing the backup of the key. + ## NOTES ## RELATED LINKS diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault/help/Backup-AzureKeyVaultSecret.md b/src/ResourceManager/KeyVault/Commands.KeyVault/help/Backup-AzureKeyVaultSecret.md new file mode 100644 index 000000000000..a596346c138a --- /dev/null +++ b/src/ResourceManager/KeyVault/Commands.KeyVault/help/Backup-AzureKeyVaultSecret.md @@ -0,0 +1,193 @@ +--- +external help file: Microsoft.Azure.Commands.KeyVault.dll-Help.xml +ms.assetid: 80AAA327-77C6-4372-9461-FFED5A15E678 +online version: http://go.microsoft.com/fwlink/?LinkId=690296 +schema: 2.0.0 +--- + +# Backup-AzureKeyVaultSecret + +## SYNOPSIS +Backs up a secret in a key vault. + +## SYNTAX + +### BySecretName +``` +Backup-AzureKeyVaultSecret [-VaultName] [-Name] [[-OutputFile] ] [-Force] [-WhatIf] + [-Confirm] [] +``` + +### BySecret +``` +Backup-AzureKeyVaultSecret -Secret [[-OutputFile] ] [-Force] [-WhatIf] [-Confirm] + [] +``` + +## DESCRIPTION +The **Backup-AzureKeyVaultSecret** cmdlet backs up a specified secret in a key vault by downloading it and storing it in a file. +If there are multiple versions of the secret, all versions are included in the backup. +Because the downloaded content is encrypted, it cannot be used outside of Azure Key Vault. +You can restore a backed-up secret to any key vault in the subscription that it was backed up from. + +Typical reasons to use this cmdlet are: + +- You want to escrow a copy of your secret, so that you have an offline copy in case you accidentally delete your secret in your key vault. +- You added a secret to a key vault and now want to clone the secret into a different Azure region, so that you can use it from all instances of your distributed application. Use the Backup-AzureKeyVaultSecret cmdlet to retrieve the secret in encrypted format and then use the Restore-AzureKeyVaultSecret cmdlet and specify a key vault in the second region. (Note that the regions must belong to the same geography.) + +## EXAMPLES + +### Example 1: Back up a secret with an automatically generated file name +``` +PS C:\>Backup-AzureKeyVaultSecret -VaultName 'MyKeyVault' -Name 'MySecret' +``` + +This command retrieves the secret named MySecret from the key vault named MyKeyVault and saves a backup of that secret to a file that is automatically named for you, and displays the file name. + +### Example 2: Back up a secret to a specified file name, overwriting the existing file without prompting +``` +PS C:\>Backup-AzureKeyVaultSecret -VaultName 'MyKeyVault' -Name 'MySecret' -OutputFile 'C:\Backup.blob' -Force +``` + +This command retrieves the secret named MySecret from the key vaultnamed MyKeyVault and saves a backup of that secret to a file named Backup.blob. + +### Example 3: Back up a secret previously retrieved to a specified file name +``` +PS C:\>$secret = Get-AzureKeyVaultSecret -VaultName 'MyKeyVault' -Name 'MySecret' +PS C:\>Backup-AzureKeyVaultSecret -Secret $secret -OutputFile 'C:\Backup.blob' +``` + +This command uses the $secret object's vault name and name to retrieves the secret and saves its backup to a file named Backup.blob. + +## PARAMETERS + +### -Force +Prompts you for confirmation before overwriting the output file, if that exists. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: False +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Name +Specifies the name of the secret to back up. + +```yaml +Type: String +Parameter Sets: BySecretName +Aliases: SecretName + +Required: True +Position: 2 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -OutputFile +Specifies the output file in which the backup blob is stored. +If you do not specify this parameter, this cmdlet generates a file name for you. +If you specify the name of an existing output file, the operation will not complete and returns an error message that the backup file already exists. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: 3 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Secret +Specifies the object whose name and vault should be used for the backup operation. + +```yaml +Type: Secret +Parameter Sets: BySecret +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -VaultName +Specifies the name of the key vault that contains the secret to back up. + +```yaml +Type: String +Parameter Sets: BySecretName +Aliases: + +Required: True +Position: 1 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Confirm +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf +Shows what would happen if the cmdlet runs. +The cmdlet is not run. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +## OUTPUTS + +### String +The cmdlet returns the path of the output file containing the backup of the key. + +## NOTES + +## RELATED LINKS + +[Set-AzureKeyVaultSecret](./Set-AzureKeyVaultSecret.md) + +[Get-AzureKeyVaultSecret](./Get-AzureKeyVaultSecret.md) + +[Remove-AzureKeyVaultSecret](./Remove-AzureKeyVaultSecret.md) + +[Restore-AzureKeyVaultSecret](./Restore-AzureKeyVaultSecret.md) + diff --git a/src/ResourceManager/KeyVault/Commands.KeyVault/help/Restore-AzureKeyVaultSecret.md b/src/ResourceManager/KeyVault/Commands.KeyVault/help/Restore-AzureKeyVaultSecret.md new file mode 100644 index 000000000000..649180686a09 --- /dev/null +++ b/src/ResourceManager/KeyVault/Commands.KeyVault/help/Restore-AzureKeyVaultSecret.md @@ -0,0 +1,120 @@ +--- +external help file: Microsoft.Azure.Commands.KeyVault.dll-Help.xml +ms.assetid: 70DB088D-4AF5-406B-8D66-118A0F766041 +online version: http://go.microsoft.com/fwlink/?LinkId=690301 +schema: 2.0.0 +--- + +# Restore-AzureKeyVaultSecret + +## SYNOPSIS +Creates a secret in a key vault from a backed-up secret. + +## SYNTAX + +``` +Restore-AzureKeyVaultSecret [-VaultName] [-InputFile] [-WhatIf] [-Confirm] + [] +``` + +## DESCRIPTION +The **Restore-AzureKeyVaultSecret** cmdlet creates a secret in the specified key vault. +This secret is a replica of the backed-up secret in the input file and has the same name as the original secret. +If the key vault already has a secret by the same name, this cmdlet fails instead of overwriting the original secret. +If the backup contains multiple versions of a secret, all versions are restored. + +The key vault that you restore the secret into can be different from the key vault that you backed up the secret from. +However, the key vault must use the same subscription and be in an Azure region in the same geography (for example, North America). +See the Microsoft Azure Trust Center (https://azure.microsoft.com/support/trust-center/) for the mapping of Azure regions to geographies. + +## EXAMPLES + +### Example 1: Restore a backed-up secret +``` +PS C:\>Restore-AzureKeyVaultSecret -VaultName 'MyKeyVault' -InputFile "C:\Backup.blob" +``` + +This command restores a secret, including all of its versions, from the backup file named Backup.blob into the key vault named MyKeyVault. + +## PARAMETERS + +### -InputFile +Specifies the input file that contains the backup of the secret to restore. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: True +Position: 2 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -VaultName +Specifies the name of the key vault into which to restore the secret. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: True +Position: 1 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Confirm +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf +Shows what would happen if the cmdlet runs. +The cmdlet is not run. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +## OUTPUTS + +## NOTES + +## RELATED LINKS + +[Set-AzureKeyVaultSecret](./Set-AzureKeyVaultSecret.md) + +[Backup-AzureKeyVaultSecret](./Backup-AzureKeyVaultSecret.md) + +[Get-AzureKeyVaultSecret](./Get-AzureKeyVaultSecret.md) + +[Remove-AzureKeyVaultSecret](./Remove-AzureKeyVaultSecret.md) +