Summarize Functionality
Copy-DbaDatabase has no parameter to control where a database's data/log/FILESTREAM files are restored on the destination. The only directory-related parameter is SharedPath, which is the staging location for backup files as well documented. Every migrated database ends up restored to whatever the destination instance's single default data/log path is (or the source's original path, depending on internal logic), with no way to place each database into its own subfolder.
By contrast, Restore-DbaDatabase (which Copy-DbaDatabase presumably wraps internally for its backup/restore mode) already exposes exactly this: DestinationDataDirectory, DestinationLogDirectory, DestinationFileStreamDirectory.
Is there a command that is similiar or close to what you are looking for?
Yes
Technical Details
my requirement was to have each database data/log/fs folder on destination in it's own directory by database, it's a bulk migration.
to reproduce the error use below:
$dbs = Get-DbaDatabase -SqlInstance $source -ExcludeSystem
foreach ($db in $dbs) {
$migrateDbSplat = @{
Source = $source
Destination = $destination
Database = $db.Name
BackupRestore = $true
SharedPath = '\share\backups'
Force = $true
DestinationDataDirectory = "D:\Data$($db.Name)"
DestinationLogDirectory = "E:\Log$($db.Name)"
DestinationFileStreamDirectory = "F:\Filestream$($db.Name)"
}
Copy-DbaDatabase @migrateDbSplat -verbose
}
error per db:
Copy-DbaDatabase : A parameter cannot be found that matches parameter name 'DestinationDataDirectory'.
Copy-DbaDatabase : A parameter cannot be found that matches parameter name 'DestinationFileStreamDirectory'.
working replacement
foreach ($db in $dbs) {
$backupSplat = @{
SqlInstance = $source
Database = $db.Name
Path = '\share\backups'
Verbose = $true
}
$restoreSplat = @{
SqlInstance = $destination
DestinationDataDirectory = "D:\Data\$($db.Name)"
DestinationLogDirectory = "E:\Log\$($db.Name)"
WithReplace = $true
Verbose = $true
}
$hasFileStream = [bool](Get-DbaDbFile -SqlInstance $source -Database $db.Name |
Where-Object TypeDescription -eq 'FILESTREAM')
if ($hasFileStream) {
$restoreSplat.DestinationFileStreamDirectory = "F:\Filestream\$($db.Name)"
}
Backup-DbaDatabase @backupSplat | Restore-DbaDatabase @restoreSplat
}
--this worked as expected, migrated a bulk of databases, created individual folders on dest and restored each db to it's own data/log/filestream folder
####added note
Without DestinationFileStreamDirectory, Copy-DbaDatabase -BackupRestore doesn't error on FILESTREAM databases — it silently restores the FILESTREAM container to whatever the implicit default location is (in testing, this landed inside the regular data directory rather than any FILESTREAM-specific path), reporting Status: Successful the whole time in my case.
Summarize Functionality
Copy-DbaDatabase has no parameter to control where a database's data/log/FILESTREAM files are restored on the destination. The only directory-related parameter is SharedPath, which is the staging location for backup files as well documented. Every migrated database ends up restored to whatever the destination instance's single default data/log path is (or the source's original path, depending on internal logic), with no way to place each database into its own subfolder.
By contrast, Restore-DbaDatabase (which Copy-DbaDatabase presumably wraps internally for its backup/restore mode) already exposes exactly this: DestinationDataDirectory, DestinationLogDirectory, DestinationFileStreamDirectory.
Is there a command that is similiar or close to what you are looking for?
Yes
Technical Details
my requirement was to have each database data/log/fs folder on destination in it's own directory by database, it's a bulk migration.
to reproduce the error use below:
$dbs = Get-DbaDatabase -SqlInstance $source -ExcludeSystem
foreach ($db in $dbs) {
$migrateDbSplat = @{
Source = $source
Destination = $destination
Database = $db.Name
BackupRestore = $true
SharedPath = '\share\backups'
Force = $true
DestinationDataDirectory = "D:\Data$($db.Name)"
DestinationLogDirectory = "E:\Log$($db.Name)"
DestinationFileStreamDirectory = "F:\Filestream$($db.Name)"
}
Copy-DbaDatabase @migrateDbSplat -verbose
}
error per db:
Copy-DbaDatabase : A parameter cannot be found that matches parameter name 'DestinationDataDirectory'.
Copy-DbaDatabase : A parameter cannot be found that matches parameter name 'DestinationFileStreamDirectory'.
working replacement
foreach ($db in $dbs) {
$backupSplat = @{
SqlInstance = $source
Database = $db.Name
Path = '\share\backups'
Verbose = $true
}
}
--this worked as expected, migrated a bulk of databases, created individual folders on dest and restored each db to it's own data/log/filestream folder
####added note
Without DestinationFileStreamDirectory, Copy-DbaDatabase -BackupRestore doesn't error on FILESTREAM databases — it silently restores the FILESTREAM container to whatever the implicit default location is (in testing, this landed inside the regular data directory rather than any FILESTREAM-specific path), reporting Status: Successful the whole time in my case.