functions/invoke-adoworkitemlayoutmigration.ps1
<# .SYNOPSIS Migrates layouts (pages, sections, groups, controls). .DESCRIPTION This function migrates work item type layouts from a source process to a target process within Azure DevOps. .PARAMETER SourceOrganization The name of the source Azure DevOps organization. .PARAMETER TargetOrganization The name of the target Azure DevOps organization. .PARAMETER SourceToken The authentication token for accessing the source Azure DevOps organization. .PARAMETER TargetToken The authentication token for accessing the target Azure DevOps organization. .PARAMETER SourceProcess The source process object containing details about the process to migrate from. .PARAMETER TargetProcess The target process object containing details about the process to migrate to. .PARAMETER SourceWitList The list of work item types in the source process. .PARAMETER TargetWitList The list of work item types in the target process. .PARAMETER ApiVersion The version of the Azure DevOps REST API to use. .EXAMPLE $apiVersion = '7.1' $sourceOrg = 'srcOrg' $targetOrg = 'tgtOrg' $sourceToken = 'pat-src' $targetToken = 'pat-tgt' $sourceProjectName = 'Sample' $sourceProjectMeta = (Get-ADOProjectList -Organization $sourceOrg -Token $sourceToken -ApiVersion $apiVersion -StateFilter All) | Where-Object name -eq $sourceProjectName $sourceProject = Get-ADOProject -Organization $sourceOrg -Token $sourceToken -ProjectId $sourceProjectMeta.id -IncludeCapabilities -ApiVersion $apiVersion $proc = Invoke-ADOProcessMigration -SourceOrganization $sourceOrg -TargetOrganization $targetOrg -SourceToken $sourceToken -TargetToken $targetToken -SourceProject $sourceProject -ApiVersion $apiVersion $witResult = Invoke-ADOWorkItemTypeMigration -SourceOrganization $sourceOrg -TargetOrganization $targetOrg -SourceToken $sourceToken -TargetToken $targetToken -SourceProcess $proc.SourceProcess -TargetProcess $proc.TargetProcess -ApiVersion $apiVersion Invoke-ADOWorkItemLayoutMigration -SourceOrganization $sourceOrg -TargetOrganization $targetOrg ` -SourceToken $sourceToken -TargetToken $targetToken -SourceProcess $proc.SourceProcess -TargetProcess $proc.TargetProcess ` -SourceWitList $witResult.SourceList -TargetWitList $witResult.TargetList -ApiVersion $apiVersion # Recreates custom pages/sections/groups/controls for inherited WITs. .NOTES This function is part of the ADO Tools module and adheres to the conventions used in the module for logging, error handling, and API interaction. Author: Oleksandr Nikolaiev (@onikolaiev) #> function Invoke-ADOWorkItemLayoutMigration { [CmdletBinding()] param( [Parameter(Mandatory)][string]$SourceOrganization, [Parameter(Mandatory)][string]$TargetOrganization, [Parameter(Mandatory)][string]$SourceToken, [Parameter(Mandatory)][string]$TargetToken, [Parameter(Mandatory)][pscustomobject]$SourceProcess, [Parameter(Mandatory)][pscustomobject]$TargetProcess, [Parameter(Mandatory)][System.Collections.IEnumerable]$SourceWitList, [Parameter(Mandatory)][System.Collections.IEnumerable]$TargetWitList, [Parameter(Mandatory)][string]$ApiVersion ) Convert-FSCPSTextToAscii -Text "Migrate layouts.." -Font "Standard" Write-PSFMessage -Level Host -Message "Starting to process layouts." foreach ($wit in $SourceWitList) { Write-PSFMessage -Level Host -Message "Processing layouts for WIT '$($wit.name)'." $targetWit = $TargetWitList.Where({$_.name -eq $wit.name}) if (-not $targetWit) { continue } $srcLayout = Get-ADOWorkItemTypeLayout -Organization $SourceOrganization -Token $SourceToken -ApiVersion $ApiVersion -ProcessId $SourceProcess.typeId -WitRefName $wit.referenceName $tgtLayout = Get-ADOWorkItemTypeLayout -Organization $TargetOrganization -Token $TargetToken -ApiVersion $ApiVersion -ProcessId $TargetProcess.typeId -WitRefName $targetWit.referenceName foreach ($page in $srcLayout.pages | Where-Object pageType -eq 'custom') { Write-PSFMessage -Level Host -Message "Processing page '$($page.label)'." $tgtPage = $tgtLayout.pages.Where({$_.label -eq $page.label}) if (-not $tgtPage) { $body = @{ id=$page.id; label=$page.label; pageType=$page.pageType; visible=$page.visible } | ConvertTo-Json -Depth 10 Write-PSFMessage -Level Verbose -Message "Adding page '$($page.label)'." $tgtPage = Add-ADOWorkItemTypePage -Organization $TargetOrganization -Token $TargetToken -ApiVersion $ApiVersion -ProcessId $TargetProcess.typeId -WitRefName $targetWit.referenceName -Body $body } else { $body = @{ id=$tgtPage.id; label=$page.label; pageType=$page.pageType; visible=$page.visible } | ConvertTo-Json -Depth 10 Write-PSFMessage -Level Verbose -Message "Updating page '$($page.label)'." $null = Update-ADOWorkItemTypePage -Organization $TargetOrganization -Token $TargetToken -ApiVersion $ApiVersion -ProcessId $TargetProcess.typeId -WitRefName $targetWit.referenceName -Body $body } $tgtPage = Get-ADOWorkItemTypeLayout -Organization $TargetOrganization -Token $TargetToken -ApiVersion $ApiVersion -ProcessId $TargetProcess.typeId -WitRefName $targetWit.referenceName | Select-Object -ExpandProperty pages | Where-Object label -eq $page.label foreach ($section in ($page.sections | Where-Object groups -ne $null)) { $tgtSection = $tgtPage.sections.Where({$_.id -eq $section.id}) if (-not $tgtSection) { $body = @{ id=$section.id; label=$section.label; visible=$section.visible } | ConvertTo-Json -Depth 10 Write-PSFMessage -Level Verbose -Message "Adding section '$($section.label)' on page '$($page.label)'." $tgtSection = Add-ADOWorkItemTypeSection -Organization $TargetOrganization -Token $TargetToken -ApiVersion $ApiVersion -ProcessId $TargetProcess.typeId -WitRefName $targetWit.referenceName -PageId $tgtPage.id -Body $body } foreach ($group in $section.groups) { $tgtGroup = $tgtSection.groups.Where({$_.label -eq $group.label}) if (-not $tgtGroup) { $body = @{ id=$group.id; label=$group.label; visible=$group.visible; controls=$group.controls } | ConvertTo-Json -Depth 10 Write-PSFMessage -Level Verbose -Message "Adding group '$($group.label)' in section '$($section.label)'." $tgtGroup = Add-ADOWorkItemTypeGroup -Organization $TargetOrganization -Token $TargetToken -ApiVersion $ApiVersion -ProcessId $TargetProcess.typeId -WitRefName $targetWit.referenceName -PageId $tgtPage.id -SectionId $section.id -Body $body } foreach ($control in $group.controls) { $tgtControl = $tgtGroup.controls.Where({$_.id -eq $control.id}) if (-not $tgtControl) { $body = @{ id=$control.id; label=$control.label; controlType=$control.controlType; contribution=$control.contribution; visible=$control.visible; height=$control.height; readOnly=$control.readOnly } | ConvertTo-Json -Depth 10 Write-PSFMessage -Level Verbose -Message "Adding control '$($control.id)' in group '$($group.label)'." $null = Add-ADOWorkItemTypeGroupControl -Organization $TargetOrganization -Token $TargetToken -ApiVersion $ApiVersion -ProcessId $TargetProcess.typeId -WitRefName $targetWit.referenceName -GroupId $tgtGroup.id -Body $body } } } } } } } |