Skip to content

Commit bee08f8

Browse files
Copy-DbaSsisCatalog - Add standard MigrationObject output, integrate with Start-DbaMigration (#10311)
1 parent 6416b4e commit bee08f8

2 files changed

Lines changed: 127 additions & 6 deletions

File tree

public/Copy-DbaSsisCatalog.ps1

Lines changed: 118 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,22 @@ function Copy-DbaSsisCatalog {
6262
Using this switch turns this "nice by default" feature off and enables you to catch exceptions with your own try/catch.
6363
6464
.OUTPUTS
65-
None
65+
PSCustomObject
6666
67-
This command performs migration operations and does not return any output objects. Check the Verbose stream for operation details, or use -WhatIf to preview what would be executed.
67+
Returns one object per migration operation attempt. Each object represents the result of copying a single folder, project, or environment to a destination instance.
68+
69+
Default display properties (via Select-DefaultView with TypeName MigrationObject):
70+
- DateTime: Timestamp when the migration operation occurred (DbaDateTime)
71+
- SourceServer: Name of the source SQL Server instance
72+
- DestinationServer: Name of the destination SQL Server instance
73+
- Name: Name of the object that was copied (folder, project, or environment name)
74+
- Type: Object type (Folder, Project, or Environment)
75+
- Status: Result of the migration attempt (Successful, Skipped, or Failed)
76+
- Notes: Additional details about the operation or reason for skipping/failure
6877
6978
.NOTES
7079
Tags: Migration, SSIS
71-
Author: Phil Schwartz (philschwartz.me, @pschwartzzz)
80+
Author: Phil Schwartz (philschwartz.me, @pschwartzzz), the dbatools team + Claude
7281
7382
dbatools PowerShell module (https://dbatools.io)
7483
Copyright: (c) 2018 by dbatools, licensed under MIT
@@ -394,52 +403,91 @@ function Copy-DbaSsisCatalog {
394403
$srcFolder = $sourceFolders | Where-Object {
395404
$_.Name -eq $folder
396405
}
406+
$copyFolderStatus = [PSCustomObject]@{
407+
SourceServer = $sourceServer.Name
408+
DestinationServer = $destinationConnection.Name
409+
Type = "Folder"
410+
Name = $folder
411+
Status = $null
412+
Notes = $null
413+
DateTime = [DbaDateTime](Get-Date)
414+
}
397415
if ($destinationFolders.Name -contains $folder) {
398416
if (!$force) {
399417
Write-Message -Level Warning -Message "Integration services catalog folder $folder exists at destination. Use -Force to drop and recreate."
418+
$copyFolderStatus.Status = "Skipped"
419+
$copyFolderStatus.Notes = "Integration services catalog folder exists at destination. Use -Force to drop and recreate."
420+
$copyFolderStatus | Select-DefaultView -Property DateTime, SourceServer, DestinationServer, Name, Type, Status, Notes -TypeName MigrationObject
400421
} else {
401422
if ($Pscmdlet.ShouldProcess($destinstance, "Dropping folder $folder and recreating")) {
402423
try {
403424
New-CatalogFolder -Folder $srcFolder.Name -Description $srcFolder.Description -Force
425+
$copyFolderStatus.Status = "Successful"
404426
} catch {
405427
Stop-Function -Message "Issue dropping folder" -Target $folder -ErrorRecord $_
428+
$copyFolderStatus.Status = "Failed"
429+
$copyFolderStatus.Notes = $_.Exception.Message
406430
}
407-
431+
$copyFolderStatus | Select-DefaultView -Property DateTime, SourceServer, DestinationServer, Name, Type, Status, Notes -TypeName MigrationObject
408432
}
409433
}
410434
} else {
411435
if ($Pscmdlet.ShouldProcess($destinstance, "Creating folder $folder")) {
412436
try {
413437
New-CatalogFolder -Folder $srcFolder.Name -Description $srcFolder.Description
438+
$copyFolderStatus.Status = "Successful"
414439
} catch {
415440
Stop-Function -Message "Issue creating folder" -Target $folder -ErrorRecord $_
441+
$copyFolderStatus.Status = "Failed"
442+
$copyFolderStatus.Notes = $_.Exception.Message
416443
}
444+
$copyFolderStatus | Select-DefaultView -Property DateTime, SourceServer, DestinationServer, Name, Type, Status, Notes -TypeName MigrationObject
417445
}
418446
}
419447
} else {
420448
throw "The source folder provided does not exist in the source Integration Services catalog."
421449
}
422450
} else {
423451
foreach ($srcFolder in $sourceFolders) {
452+
$copyFolderStatus = [PSCustomObject]@{
453+
SourceServer = $sourceServer.Name
454+
DestinationServer = $destinationConnection.Name
455+
Type = "Folder"
456+
Name = $srcFolder.Name
457+
Status = $null
458+
Notes = $null
459+
DateTime = [DbaDateTime](Get-Date)
460+
}
424461
if ($destinationFolders.Name -notcontains $srcFolder.Name) {
425462
if ($Pscmdlet.ShouldProcess($destinstance, "Creating folder $($srcFolder.Name)")) {
426463
try {
427464
New-CatalogFolder -Folder $srcFolder.Name -Description $srcFolder.Description
465+
$copyFolderStatus.Status = "Successful"
428466
} catch {
429467
Stop-Function -Message "Issue creating folder" -Target $srcFolder -ErrorRecord $_ -Continue
468+
$copyFolderStatus.Status = "Failed"
469+
$copyFolderStatus.Notes = $_.Exception.Message
430470
}
471+
$copyFolderStatus | Select-DefaultView -Property DateTime, SourceServer, DestinationServer, Name, Type, Status, Notes -TypeName MigrationObject
431472
}
432473
} else {
433474
if (!$force) {
434475
Write-Message -Level Warning -Message "Integration services catalog folder $($srcFolder.Name) exists at destination. Use -Force to drop and recreate."
476+
$copyFolderStatus.Status = "Skipped"
477+
$copyFolderStatus.Notes = "Integration services catalog folder exists at destination. Use -Force to drop and recreate."
478+
$copyFolderStatus | Select-DefaultView -Property DateTime, SourceServer, DestinationServer, Name, Type, Status, Notes -TypeName MigrationObject
435479
continue
436480
} else {
437481
if ($Pscmdlet.ShouldProcess($destinstance, "Dropping folder $($srcFolder.Name) and recreating")) {
438482
try {
439483
New-CatalogFolder -Folder $srcFolder.Name -Description $srcFolder.Description -Force
484+
$copyFolderStatus.Status = "Successful"
440485
} catch {
441486
Stop-Function -Message "Issue dropping folder" -Target $srcFolder -ErrorRecord $_
487+
$copyFolderStatus.Status = "Failed"
488+
$copyFolderStatus.Notes = $_.Exception.Message
442489
}
490+
$copyFolderStatus | Select-DefaultView -Property DateTime, SourceServer, DestinationServer, Name, Type, Status, Notes -TypeName MigrationObject
443491
}
444492
}
445493
}
@@ -475,23 +523,49 @@ function Copy-DbaSsisCatalog {
475523
} else {
476524
foreach ($f in $folderDeploy) {
477525
if ($Pscmdlet.ShouldProcess($destinstance, "Deploying project $project from folder $($f.Name)")) {
526+
$copyProjectStatus = [PSCustomObject]@{
527+
SourceServer = $sourceServer.Name
528+
DestinationServer = $destinationConnection.Name
529+
Type = "Project"
530+
Name = $project
531+
Status = $null
532+
Notes = $null
533+
DateTime = [DbaDateTime](Get-Date)
534+
}
478535
try {
479536
Invoke-ProjectDeployment -Folder $f.Name -Project $project
537+
$copyProjectStatus.Status = "Successful"
480538
} catch {
481539
Stop-Function -Message "Issue deploying project" -Target $project -ErrorRecord $_
540+
$copyProjectStatus.Status = "Failed"
541+
$copyProjectStatus.Notes = $_.Exception.Message
482542
}
543+
$copyProjectStatus | Select-DefaultView -Property DateTime, SourceServer, DestinationServer, Name, Type, Status, Notes -TypeName MigrationObject
483544
}
484545
}
485546
}
486547
} else {
487548
foreach ($curFolder in $sourceFolders) {
488549
foreach ($proj in $curFolder.Projects) {
489550
if ($Pscmdlet.ShouldProcess($destinstance, "Deploying project $($proj.Name) from folder $($curFolder.Name)")) {
551+
$copyProjectStatus = [PSCustomObject]@{
552+
SourceServer = $sourceServer.Name
553+
DestinationServer = $destinationConnection.Name
554+
Type = "Project"
555+
Name = $proj.Name
556+
Status = $null
557+
Notes = $null
558+
DateTime = [DbaDateTime](Get-Date)
559+
}
490560
try {
491561
Invoke-ProjectDeployment -Project $proj.Name -Folder $curFolder.Name
562+
$copyProjectStatus.Status = "Successful"
492563
} catch {
493564
Stop-Function -Message "Issue deploying project" -Target $proj -ErrorRecord $_
565+
$copyProjectStatus.Status = "Failed"
566+
$copyProjectStatus.Notes = $_.Exception.Message
494567
}
568+
$copyProjectStatus | Select-DefaultView -Property DateTime, SourceServer, DestinationServer, Name, Type, Status, Notes -TypeName MigrationObject
495569
}
496570
}
497571
}
@@ -505,24 +579,44 @@ function Copy-DbaSsisCatalog {
505579
throw "The environment $environment cannot be found in the source Integration Services catalog."
506580
} else {
507581
foreach ($f in $folderDeploy) {
582+
$copyEnvStatus = [PSCustomObject]@{
583+
SourceServer = $sourceServer.Name
584+
DestinationServer = $destinationConnection.Name
585+
Type = "Environment"
586+
Name = $environment
587+
Status = $null
588+
Notes = $null
589+
DateTime = [DbaDateTime](Get-Date)
590+
}
508591
if ($destinationFolders[$f.Name].Environments.Name -notcontains $environment) {
509592
if ($Pscmdlet.ShouldProcess($destinstance, "Deploying environment $environment from folder $($f.Name)")) {
510593
try {
511594
New-FolderEnvironment -Folder $f.Name -Environment $environment
595+
$copyEnvStatus.Status = "Successful"
512596
} catch {
513597
Stop-Function -Message "Issue deploying environment" -Target $environment -ErrorRecord $_
598+
$copyEnvStatus.Status = "Failed"
599+
$copyEnvStatus.Notes = $_.Exception.Message
514600
}
601+
$copyEnvStatus | Select-DefaultView -Property DateTime, SourceServer, DestinationServer, Name, Type, Status, Notes -TypeName MigrationObject
515602
}
516603
} else {
517604
if (!$force) {
518605
Write-Message -Level Warning -Message "Integration services catalog environment $environment exists in folder $($f.Name) at destination. Use -Force to drop and recreate."
606+
$copyEnvStatus.Status = "Skipped"
607+
$copyEnvStatus.Notes = "Integration services catalog environment exists in folder $($f.Name) at destination. Use -Force to drop and recreate."
608+
$copyEnvStatus | Select-DefaultView -Property DateTime, SourceServer, DestinationServer, Name, Type, Status, Notes -TypeName MigrationObject
519609
} else {
520610
If ($Pscmdlet.ShouldProcess($destinstance, "Dropping existing environment $environment and deploying environment $environment from folder $($f.Name)")) {
521611
try {
522612
New-FolderEnvironment -Folder $f.Name -Environment $environment -Force
613+
$copyEnvStatus.Status = "Successful"
523614
} catch {
524615
Stop-Function -Message "Issue dropping existing environment" -Target $environment -ErrorRecord $_
616+
$copyEnvStatus.Status = "Failed"
617+
$copyEnvStatus.Notes = $_.Exception.Message
525618
}
619+
$copyEnvStatus | Select-DefaultView -Property DateTime, SourceServer, DestinationServer, Name, Type, Status, Notes -TypeName MigrationObject
526620
}
527621
}
528622
}
@@ -531,25 +625,45 @@ function Copy-DbaSsisCatalog {
531625
} else {
532626
foreach ($curFolder in $sourceFolders) {
533627
foreach ($env in $curFolder.Environments) {
628+
$copyEnvStatus = [PSCustomObject]@{
629+
SourceServer = $sourceServer.Name
630+
DestinationServer = $destinationConnection.Name
631+
Type = "Environment"
632+
Name = $env.Name
633+
Status = $null
634+
Notes = $null
635+
DateTime = [DbaDateTime](Get-Date)
636+
}
534637
if ($destinationFolders[$curFolder.Name].Environments.Name -notcontains $env.Name) {
535638
if ($Pscmdlet.ShouldProcess($destinstance, "Deploying environment $($env.Name) from folder $($curFolder.Name)")) {
536639
try {
537640
New-FolderEnvironment -Environment $env.Name -Folder $curFolder.Name
641+
$copyEnvStatus.Status = "Successful"
538642
} catch {
539643
Stop-Function -Message "Issue deploying environment" -Target $env -ErrorRecord $_
644+
$copyEnvStatus.Status = "Failed"
645+
$copyEnvStatus.Notes = $_.Exception.Message
540646
}
647+
$copyEnvStatus | Select-DefaultView -Property DateTime, SourceServer, DestinationServer, Name, Type, Status, Notes -TypeName MigrationObject
541648
}
542649
} else {
543650
if (!$force) {
544651
Write-Message -Level Warning -Message "Integration services catalog environment $($env.Name) exists in folder $($curFolder.Name) at destination. Use -Force to drop and recreate."
652+
$copyEnvStatus.Status = "Skipped"
653+
$copyEnvStatus.Notes = "Integration services catalog environment $($env.Name) exists in folder $($curFolder.Name) at destination. Use -Force to drop and recreate."
654+
$copyEnvStatus | Select-DefaultView -Property DateTime, SourceServer, DestinationServer, Name, Type, Status, Notes -TypeName MigrationObject
545655
continue
546656
} else {
547657
if ($Pscmdlet.ShouldProcess($destinstance, "Deploying environment $($env.Name) from folder $($curFolder.Name)")) {
548658
try {
549659
New-FolderEnvironment -Environment $env.Name -Folder $curFolder.Name -Force
660+
$copyEnvStatus.Status = "Successful"
550661
} catch {
551662
Stop-Function -Message "Issue deploying environment" -Target $env -ErrorRecord $_
663+
$copyEnvStatus.Status = "Failed"
664+
$copyEnvStatus.Notes = $_.Exception.Message
552665
}
666+
$copyEnvStatus | Select-DefaultView -Property DateTime, SourceServer, DestinationServer, Name, Type, Status, Notes -TypeName MigrationObject
553667
}
554668
}
555669
}

0 commit comments

Comments
 (0)