Public/Sync-CrmSolutionFromSource.ps1
Function Sync-CrmSolutionFromSource { <# .SYNOPSIS Syncs a Solution in a Dynamics Crm org against a source solution in another org. .DESCRIPTION Syncs a Solution in a Dynamics Crm org against a source solution in another org. Necessary parameters read from config file. File can be generated using the '-GenerateConfig' switch -- this will prompt you for the required parameters -- or via the 'New-CrmSolutionFromSourceConfig' cmdlet. If Solution does not already exist on target, it will be created. If publisher does not already exist on target, it will be created. All publisher info and solution name are assumed to be the same on source and target. If the target Solution exists and contains SolutionComponents, any SolutionComponents not in source Solution will be removed from the target Solution. If specified in config, entities with rootcomponentbehaviors of 0 will be changed to 1. .OUTPUTS -Solution on target Dynamics Crm Org. -'Errorlog.txt', if errors encountered. -'BuildCrmSolutionLog.json', contains useful information about SolutionComponents manipulated by the cmdlet. This includes those Added, Skipped, and comparison results. #> [cmdletbinding()] Param ( [Parameter(ParameterSetName = 'Cred')] [pscredential]$SourceCredential, [Parameter(ParameterSetName = 'Cred')] [pscredential]$TargetCredential, [Parameter(ParameterSetName = 'DiscreteCreds', Mandatory = $true)] [string]$SourceUsername, [Parameter(ParameterSetName = 'DiscreteCreds', Mandatory = $true)] [securestring]$SourcePassword, [Parameter(ParameterSetName = 'DiscreteCreds', Mandatory = $true)] [string]$TargetUsername, [Parameter(ParameterSetName = 'DiscreteCreds', Mandatory = $true)] [securestring]$TargetPassword, [Parameter(Mandatory = $true)] [string]$ConfigFilePath ) $config = Get-Config -ConfigFilePath $ConfigFilePath $solutionName = $config.SolutionName $publisher = $config.Publisher $usePSCred = -Not $PSBoundParameters.ContainsKey('SourcePassword') if ($UsePSCred) { $sourceConn = Get-CrmConnection -Cred $SourceCredential -Url "https://$($config.sourceOrg).crm.dynamics.com" $targetConn = Get-CrmConnection -Cred $TargetCredential -Url "https://$($config.targetOrg).crm.dynamics.com" } else { $sourceConn = Get-CrmConnection -Username $SourceUsername -Password $SourcePassword -Url "https://$sourceOrg.crm.dynamics.com" $targetConn = Get-CrmConnection -Username $TargetUsername -Password $TargetPassword -Url "https://$targetOrg.crm.dynamics.com" } if (-Not (Test-CrmSolutionExists -Conn $sourceConn -SolutionName $solutionName)) { throw "Source solution does not exist" } if (-Not (Test-CrmSolutionExists -Conn $targetConn -SolutionName $solutionName)) { New-CrmSolution -SolutionName $solutionName -Publisher $publisher -Conn $targetConn } $metadata = Get-MetadataHash -TargetConn $targetConn -SourceConn $sourceConn if ($config.FixRootComponentBehavior) { $updatedRoots = Update-RootComponentBehavior -SolutionName $solutionName -Conn $sourceConn -Metadata $Metadata.Source.Attributes } $payload = Get-Payload -Metadata $metadata -TargetConn $targetConn -SourceConn $sourceConn if ($payload.Release) { Add-Component -Conn $targetConn -Component $payload.Release -SolutionName $solutionName } if ($payload.Remove) { Remove-Component -Component $payload.Remove -Conn $targetConn -SolutionName $solutionName | Out-Null $correctionPayload = Get-Payload -Metadata $metadata -TargetConn $targetConn -SourceConn $sourceConn Write-Verbose "Re-adding any dependencies flushed by removal process..." if ($correctionPayload.Release) { Add-Component -Conn $targetConn -Component $correctionPayload.Release -SolutionName $solutionName } } $log = @{} $log["Timestamp"] = (Get-Date -Format o) $log["Config"] = $config $log["Manifest"] = $payload $log["RootsUpdated"] = $updatedRoots $log["Correction"] = $correctionManifest ConvertTo-Json -InputObject $log -Depth 10 | Out-File -FilePath "SyncLog.json" Write-Verbose "Data log saved to SyncLog.json" } |