Skip to content

Commit

Permalink
Backup-DbaServiceMasterKey, add FileBaseName parameter (#9598)
Browse files Browse the repository at this point in the history
  • Loading branch information
niphlod authored Feb 24, 2025
1 parent 978b97c commit 00aaf8d
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
30 changes: 21 additions & 9 deletions public/Backup-DbaServiceMasterKey.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@ function Backup-DbaServiceMasterKey {
For MFA support, please use Connect-DbaInstance.
.PARAMETER KeyCredential
Pass a credential object for the password
.PARAMETER Path
The directory to export the key. If no path is specified, the default backup directory for the instance will be used.
.PARAMETER KeyCredential
Pass a credential object for the password
.PARAMETER FileBaseName
Override the default naming convention with a fixed name for the service master key, useful when exporting a single one.
".key" will be appended to the filename.
.PARAMETER SecurePassword
The password to encrypt the exported key. This must be a SecureString.
Expand Down Expand Up @@ -72,13 +76,13 @@ function Backup-DbaServiceMasterKey {
[Alias("Password")]
[Security.SecureString]$SecurePassword,
[string]$Path,
[string]$FileBaseName,
[switch]$EnableException
)
begin {
if ($KeyCredential) {
$SecurePassword = $KeyCredential.Password
}
$time = Get-Date -Format yyyMMddHHmmss
}
process {
foreach ($instance in $SqlInstance) {
Expand Down Expand Up @@ -116,16 +120,24 @@ function Backup-DbaServiceMasterKey {
$Path = $Path.TrimEnd("\")
$Path = $Path.TrimEnd("/")
$fileinstance = $instance.ToString().Replace('\', '$')
$filename = Join-DbaPath -SqlInstance $server -Path $Path -ChildPath "$fileinstance-servicemasterkey.key"
$targetBaseName = "$fileinstance-servicemasterkey"
if ($FileBaseName) {
$targetBaseName = $FileBaseName
}

$exportFileName = Join-DbaPath -SqlInstance $server -Path $Path -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 $Path -ChildPath "$fileinstance-servicemasterkey-$time.key"
if (Test-DbaPath -SqlInstance $server -Path $exportFileName) {
$time = Get-Date -Format yyyyMMddHHmmss
$exportFileName = Join-DbaPath -SqlInstance $server -Path $Path -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 service master key to $filename")) {
if ($Pscmdlet.ShouldProcess($instance, "Backing up service master key to $exportFileName")) {
try {
$masterkey.Export($filename, ($SecurePassword | ConvertFrom-SecurePass))
$masterkey.Export($exportFileName, ($SecurePassword | ConvertFrom-SecurePass))
$status = "Success"
} catch {
$status = "Failure"
Expand All @@ -135,7 +147,7 @@ function Backup-DbaServiceMasterKey {
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 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, 'Filename as Path', Status
Expand Down
10 changes: 9 additions & 1 deletion tests/Backup-DbaServiceMasterKey.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Describe "Backup-DbaServiceMasterKey" -Tag "UnitTests" {
"KeyCredential",
"SecurePassword",
"Path",
"FileBaseName",
"EnableException",
"Confirm",
"WhatIf"
Expand All @@ -36,14 +37,21 @@ Describe "Backup-DbaServiceMasterKey" -Tag "IntegrationTests" {
Context "Can backup a service master key" {
BeforeAll {
$securePassword = ConvertTo-SecureString -String "GoodPass1234!" -AsPlainText -Force
$results = Backup-DbaServiceMasterKey -SqlInstance $TestConfig.instance1 -SecurePassword $securePassword -Confirm:$false
}

AfterAll {
$null = Remove-Item -Path $results.Path -ErrorAction SilentlyContinue -Confirm:$false
}

It "backs up the SMK" {
$results = Backup-DbaServiceMasterKey -SqlInstance $TestConfig.instance1 -SecurePassword $securePassword -Confirm:$false
$results.Status | Should -Be "Success"
}

It "backs up the SMK with a specific filename (see #9483)" {
$random = Get-Random
$results = Backup-DbaServiceMasterKey -SqlInstance $TestConfig.instance1 -SecurePassword $securePassword -FileBaseName "smk($random)" -Confirm:$false
[IO.Path]::GetFileNameWithoutExtension($results.Path) | Should -Be "smk($random)"
$results.Status | Should -Be "Success"
}
}
Expand Down

0 comments on commit 00aaf8d

Please sign in to comment.