Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New command - Get-DbaDbFileMapping #7578

Merged
merged 8 commits into from Jul 18, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions dbatools.psd1
Expand Up @@ -174,6 +174,7 @@
'Get-DbaDbQueryStoreOption',
'Set-DbaDbQueryStoreOption',
'Restore-DbaDatabase',
'Get-DbaDbFileMap',
'Copy-DbaDbQueryStoreOption',
'Get-DbaExecutionPlan',
'Export-DbaExecutionPlan',
Expand Down
1 change: 1 addition & 0 deletions dbatools.psm1
Expand Up @@ -439,6 +439,7 @@ $script:xplat = @(
'Get-DbaDbQueryStoreOption',
'Set-DbaDbQueryStoreOption',
'Restore-DbaDatabase',
'Get-DbaDbFileMap',
'Copy-DbaDbQueryStoreOption',
'Get-DbaExecutionPlan',
'Export-DbaExecutionPlan',
Expand Down
90 changes: 90 additions & 0 deletions functions/Get-DbaDbFileMap.ps1
@@ -0,0 +1,90 @@
function Get-DbaDbFileMap {
<#
.SYNOPSIS
Provides an easy way to build the FileMapping Hashtable for Restore-DbaDatabase from an existing database

.DESCRIPTION
Provides an easy way to build the FileMapping Hashtable for Restore-DbaDatabase from an existing database

.PARAMETER SqlInstance
The target SQL Server instance or instances. This can be a collection and receive pipeline input.

.PARAMETER SqlCredential
Login to the target instance using alternative credentials. Accepts PowerShell credentials (Get-Credential).

Windows Authentication, SQL Server Authentication, Active Directory - Password, and Active Directory - Integrated are all supported.

For MFA support, please use Connect-DbaInstance.

.PARAMETER Database
The database(s) to process - this list is auto-populated from the server. If unspecified, all databases will be processed.

.PARAMETER InputObject
Database object piped in from Get-DbaDatabase

.PARAMETER EnableException
By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message.
This avoids overwhelming you with "sea of red" exceptions, but is inconvenient because it basically disables advanced scripting.
Using this switch turns this "nice by default" feature off and enables you to catch exceptions with your own try/catch.

.NOTES
Tags: Database
Author: Chrissy LeMaire (@cl), netnerds.net | Andreas Jordan (@JordanOrdix), ordix.de

Website: https://dbatools.io
Copyright: (c) 2021 by dbatools, licensed under MIT
License: MIT https://opensource.org/licenses/MIT

.LINK
https://dbatools.io/Get-DbaDbFileMap

.EXAMPLE
PS C:\> $filemap = Get-DbaDbFileMap -SqlInstance sql2016 -Database test
PS C:\> Get-ChildItem \\nas\db\backups\test | Restore-DbaDatabase -SqlInstance sql2019 -Database test -FileMapping $filemap.FileMap

Restores test to sql2019 using the file structure built from the existing database on sql2016
#>
[CmdletBinding()]
param ([parameter(ValueFromPipeline)]
[DbaInstanceParameter[]]$SqlInstance,
[PSCredential]$SqlCredential,
[object[]]$Database,
potatoqualitee marked this conversation as resolved.
Show resolved Hide resolved
[parameter(ValueFromPipeline)]
[Microsoft.SqlServer.Management.Smo.Database[]]$InputObject,
[switch]$EnableException
)
process {
if (Test-Bound -not 'SqlInstance', 'InputObject') {
Write-Message -Level Warning -Message "You must specify either a SQL instance or supply an InputObject"
return
}

if (Test-Bound -Not -ParameterName InputObject) {
$InputObject += Get-DbaDatabase -SqlInstance $SqlInstance -SqlCredential $SqlCredential -Database $Database
}

foreach ($db in $InputObject) {
if ($db.IsAccessible) {
Write-Message -Level Verbose -Message "Processing database: $db"
$fileMap = @{ }

foreach ($file in $db.FileGroups.Files) {
$fileMap[$file.Name] = $file.FileName
}
foreach ($file in $db.LogFiles) {
$fileMap[$file.Name] = $file.FileName
}

[PSCustomObject]@{
ComputerName = $db.ComputerName
InstanceName = $db.InstanceName
SqlInstance = $db.SqlInstance
Database = $db.Name
FileMap = $fileMap
potatoqualitee marked this conversation as resolved.
Show resolved Hide resolved
}
} else {
Write-Message -Level Verbose -Message "Skipping processing of database: $db as database is not accessible"
}
}
}
}
31 changes: 31 additions & 0 deletions tests/Get-DbaDbFileMap.Tests.ps1
@@ -0,0 +1,31 @@
$CommandName = $MyInvocation.MyCommand.Name.Replace(".Tests.ps1", "")
Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan
. "$PSScriptRoot\constants.ps1"

Describe "$CommandName Unit Tests" -Tag 'UnitTests' {
Context "Validate parameters" {
[object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object { $_ -notin ('whatif', 'confirm') }
[object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Database', 'InputObject', 'EnableException'
$knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters
It "Should only contain our specific parameters" {
(@(Compare-Object -ReferenceObject ($knownParameters | Where-Object { $_ }) -DifferenceObject $params).Count ) | Should Be 0
}
}
potatoqualitee marked this conversation as resolved.
Show resolved Hide resolved
}

Describe "$CommandName Integration Tests" -Tag "IntegrationTests" {
Context "Should return file information" {
$results = Get-DbaDbFileMap -SqlInstance $script:instance1
It "returns information about multiple databases" {
$results.Database -contains "tempdb" | Should -Be $true
$results.Database -contains "master" | Should -Be $true
}
}
Context "Should return file information for a single database" {
$results = Get-DbaDbFileMap -SqlInstance $script:instance1 -Database tempdb
It "returns information about tempdb" {
$results.Database -contains "tempdb" | Should -Be $true
$results.Database -contains "master" | Should -Be $false
}
}
}