Skip to content

Commit

Permalink
Backup-DbaDbMasterKey, add FileBaseName
Browse files Browse the repository at this point in the history
  • Loading branch information
niphlod committed Feb 22, 2025
1 parent a99229c commit 0c15cc6
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 20 deletions.
39 changes: 24 additions & 15 deletions public/Backup-DbaDbMasterKey.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,24 @@ function Backup-DbaDbMasterKey {
For MFA support, please use Connect-DbaInstance.
.PARAMETER Credential
Pass a credential object for the password
.PARAMETER Database
Backup master key from specific database(s).
.PARAMETER ExcludeDatabase
The database(s) to exclude - this list is auto-populated from the server.
.PARAMETER SecurePassword
The password to encrypt the exported key. This must be a SecureString.
.PARAMETER Path
The directory to export the key. If no path is specified, the default backup directory for the instance will be used.
.PARAMETER Credential
Pass a credential object for the password
.PARAMETER SecurePassword
The password to encrypt the exported key. This must be a SecureString.
.PARAMETER FileBaseName
Override the default naming convention with a fixed name for the database master key, useful when exporting a single one.
".key" will be appended to the filename.
.PARAMETER InputObject
Database object piped in from Get-DbaDatabase
Expand Down Expand Up @@ -82,6 +86,7 @@ function Backup-DbaDbMasterKey {
[Alias("Password")]
[Security.SecureString]$SecurePassword,
[string]$Path,
[string]$FileBaseName,
[parameter(ValueFromPipeline)]
[Microsoft.SqlServer.Management.Smo.Database[]]$InputObject,
[switch]$EnableException
Expand All @@ -90,7 +95,6 @@ function Backup-DbaDbMasterKey {
if ($Credential) {
$SecurePassword = $Credential.Password
}
$time = Get-Date -Format yyyMMddHHmmss
}
process {
foreach ($instance in $SqlInstance) {
Expand Down Expand Up @@ -144,31 +148,36 @@ function Backup-DbaDbMasterKey {
}

$fileinstance = $instance.ToString().Replace('\', '$')
$filename = Join-DbaPath -SqlInstance $server -Path $actualPath -ChildPath "$fileinstance-$dbname-masterkey.key"
$targetBaseName = "$fileinstance-$dbname-masterkey"
if ($FileBaseName) {
$targetBaseName = $FileBaseName
}

$exportFileName = Join-DbaPath -SqlInstance $server -Path $actualPath -ChildPath "$targetBaseName.key"

# if the base file name exists, then default to old style of appending a timestamp
if (Test-DbaPath -SqlInstance $server -Path $filename) {
$filename = Join-DbaPath -SqlInstance $server -Path $actualPath -ChildPath "$fileinstance-$dbname-masterkey-$time.key"
if (Test-DbaPath -SqlInstance $server -Path $exportFileName) {
$time = Get-Date -Format yyyMMddHHmmss
$exportFileName = Join-DbaPath -SqlInstance $server -Path $actualPath -ChildPath "$targetBaseName-$time.key"
# Sleep for a second to avoid another export in the same second
Start-Sleep -Seconds 1
}

if ($Pscmdlet.ShouldProcess($instance, "Backing up master key to $filename")) {
if ($Pscmdlet.ShouldProcess($instance, "Backing up master key to $exportFileName")) {
try {
$masterkey.Export($filename, ($SecurePassword | ConvertFrom-SecurePass))
$masterkey.Export($exportFileName, ($SecurePassword | ConvertFrom-SecurePass))
$status = "Success"
} catch {
$status = "Failure"
Write-Message -Level Warning -Message "Backup failure: $($_.Exception.InnerException)"
}

# Sleep for a second to avoid another export in the same second
Start-Sleep -Seconds 1

Add-Member -Force -InputObject $masterkey -MemberType NoteProperty -Name ComputerName -value $server.ComputerName
Add-Member -Force -InputObject $masterkey -MemberType NoteProperty -Name InstanceName -value $server.ServiceName
Add-Member -Force -InputObject $masterkey -MemberType NoteProperty -Name SqlInstance -value $server.DomainInstanceName
Add-Member -Force -InputObject $masterkey -MemberType NoteProperty -Name Database -value $dbName
Add-Member -Force -InputObject $masterkey -MemberType NoteProperty -Name DatabaseID -value $db.ID
Add-Member -Force -InputObject $masterkey -MemberType NoteProperty -Name Filename -value $filename
Add-Member -Force -InputObject $masterkey -MemberType NoteProperty -Name Filename -value $exportFileName
Add-Member -Force -InputObject $masterkey -MemberType NoteProperty -Name Status -value $status

Select-DefaultView -InputObject $masterkey -Property ComputerName, InstanceName, SqlInstance, Database, 'Filename as Path', Status
Expand Down
29 changes: 24 additions & 5 deletions tests/Backup-DbaDbMasterKey.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Describe "Backup-DbaDbMasterKey" -Tag "UnitTests" {
"ExcludeDatabase",
"SecurePassword",
"Path",
"FileBaseName",
"InputObject",
"EnableException",
"WhatIf",
Expand Down Expand Up @@ -45,27 +46,45 @@ Describe "Backup-DbaDbMasterKey" -Tag "IntegrationTests" {
if (-not (Get-DbaDbMasterKey -SqlInstance $instance -Database $database)) {
$null = New-DbaDbMasterKey -SqlInstance $instance -Database $database -Password $password -Confirm:$false
}
}

AfterAll {
Get-DbaDbMasterKey -SqlInstance $instance -Database $database | Remove-DbaDbMasterKey -Confirm:$false
}

It "Backs up the database master key" {
$splatBackup = @{
SqlInstance = $instance
Database = $database
SecurePassword = $password
Confirm = $false
}
}
$results = Backup-DbaDbMasterKey @splatBackup
$results | Should -Not -BeNullOrEmpty
$results.Database | Should -Be $database
$results.Status | Should -Be "Success"
$results.DatabaseID | Should -Be (Get-DbaDatabase -SqlInstance $instance -Database $database).ID

AfterAll {
Get-DbaDbMasterKey -SqlInstance $instance -Database $database | Remove-DbaDbMasterKey -Confirm:$false
$null = Remove-Item -Path $results.Path -ErrorAction SilentlyContinue -Confirm:$false
}

It "Backs up the database master key" {
It "Backs up the database master key with a specific filename (see #9484)" {
$random = Get-Random
$splatBackup = @{
SqlInstance = $instance
Database = $database
SecurePassword = $password
FileBaseName = "dbatoolscli_dbmasterkey_$random"
Confirm = $false
}
$results = Backup-DbaDbMasterKey @splatBackup
$results | Should -Not -BeNullOrEmpty
$results.Database | Should -Be $database
$results.Status | Should -Be "Success"
$results.DatabaseID | Should -Be (Get-DbaDatabase -SqlInstance $instance -Database $database).ID

[IO.Path]::GetFileNameWithoutExtension($results.Path) | Should -Be "dbatoolscli_dbmasterkey_$random"
$null = Remove-Item -Path $results.Path -ErrorAction SilentlyContinue -Confirm:$false
}

}
}

0 comments on commit 0c15cc6

Please sign in to comment.