functions/Move-RegentSolution.ps1
Write-Verbose "Entering PackAndImport.ps1" Import-Module "$PsScriptRoot\Get-Config.ps1" function Move-RegentSolution { ############################## #.SYNOPSIS # Moves a solution from one crm to another, checking the solution into source control in between. If given a time, schedules the import for that time. Please reivew details,especially parameter details. # #.DESCRIPTION # This function is intended to be the one actually used in this module. You give it all the details, and it handles the whole process of exporting, unpacking, checking into source control, and importing back again (or scheduling the import for a later time). The function itself merely glues the other functions in the module together. In the case of scheduling for later, it accomplishes this by writing a JSON file with everything needed (including the users encrypted credentials), which will be picked up later by Invoke-RegentScheduledImports. The command usually prompts the user to review the details before continuing with the operation, but for scripting/testing purposes, this can be disabeld with the -Force switch. See the parameter details for more information on each parameter. # #.EXAMPLE #An example of immediate export and reimport from CRMRECRUITTEST to CRMRECRUIT (backtick line-break escapes are used for reading clarity) # Move-RegentSolution # -SolutionName MySolution ` # -SourceCrmInstance CRMRECRUITTEST ` # -DestinationCrmInstance CRMRECRUIT ` # -Managed $false ` # -PublishCustomizations $true ` # -Emails "dhines@regent.edu;bryatho@regent.edu" ` # -CommitMessage "Added fields regent_importantfield1 and regent_importantfield2 to capture Sling import data. Added new fields to dashboard displays" # #.EXAMPLE #An example of a scheduled export and reimport from CRMADVISETEST to CRMADVISE. Note the import will begin on the current day at 11:59PM (or slightly thereafter). The value provided for -ImportTime can be any value parsable by the Get-Date function. # Move-RegentSolution ` # -SolutionName "MyOtherSolution"` # -SourceCrmInstance CRMADVISETEST ` # -DestinationCrmInstance CRMADVISE ` # -Managed $true ` # -PublishCustomizations $false ` # -Emails "dhines@regent.edu;acofer@regent.edu" ` # -CommitMessage "Added web resource for display on the application folder that calculates GPA based on rubric logic in regent_gparubric entity records" ` # -Branch "mybranch" ` # -ImportTime "11:59PM"` # -Force # #.NOTES #General notes ############################## param ( # Credentials used to connect to the Crm, such as those generated by Get-Credential. If not provided, the function will prompt user for input. [pscredential]$Credential, # The unique name of the solution to import. This must correspond to a folder already in the solution repository. [Parameter(Mandatory = $true)] [string]$SolutionName, # Determines which CRM instance the solution will be imported to. Note that these are hard-coded - any changes will require changes to this script module's source code or it will break! [ValidateSet("CRMRECRUIT", "CRMRECRUITTEST", "CRMADVISE", "CRMADVISETEST")] [Parameter(Mandatory = $true)] $SourceCrmInstance, # Determines which CRM instance the solution will be imported to. Note that these are hard-coded - any changes will require changes to this script module's source code or it will break! [ValidateSet("CRMRECRUIT", "CRMRECRUITTEST", "CRMADVISE", "CRMADVISETEST")] [Parameter(Mandatory = $true)] $DestinationCrmInstance, # Provide $true or $false. If set to $true, the solution will be imported as a managed solution. [Parameter(Mandatory = $true)] [bool]$Managed, # Provide $true or $false (defaults to $true). If set to $true and the import succeeds, all customizations will be published once the import is finished. [bool]$PublishCustomizations = $true, # A list of of emails to receive the notification, seperated by semicolons. E.g "user1@regent.edu;user2@regent.edu" [Parameter(Mandatory = $true)] [string]$Emails, # The new version of the solution. Setting this will update it in the development crm instance [string]$UpdateVersion, # The time to begin the import job. If not provided, the import begins immediately. The value provided can be a DateTime object or any value that can be parsed by Get-Date. $ImportTime, # The message associated with these changes. Be specific! Rather than saying "Added fields to Person record", be sure to include which fields, and maybe a few words about the purpose. [Parameter(Mandatory = $true)] [string]$CommitMessage, # The branch to commit to. If not provided, defaults to the branch in your config (which is desirable 99% of the time). [string]$Branch, # Set this flag to skip the confirmation prompt and proceed directly with the operation [switch]$Force ) $ErrorActionPreference = "Stop" # Use the credential object provided, or prompt user for a new one $global:cred = $Credential if ( -Not $global:cred) { $global:cred = Get-Credential -Message "Enter Your CRM Credentials" -UserName $env:USERNAME } Write-Host "Searching CRM $SourceCrmInstance for solution $SolutionName..." $sourceConn = Get-RegentConnection -CrmInstance $SourceCrmInstance $Solution = Get-CrmRecords -conn $sourceConn -EntityLogicalName solution -FilterAttribute uniquename ` -FilterOperator eq -FilterValue $SolutionName -Fields uniquename, description, createdon, ismanaged, publisherid Write-Host -ForegroundColor Yellow "Solution found. Please review the details below to confirm they're correct." $solDetails = $Solution.CrmRecords | Select-Object uniquename, description, createdon, ismanaged, publisherid, solutionid if (-not $solDetails) { throw "No Solution ""$SolutionName"" found in $SourceCrmInstance. Check spelling and that solution exists." } Write-Host "`n`n$($solDetails | ConvertTo-Json)`n`n" Write-Host -ForegroundColor Yellow "Continuing the operation will schedule the following job:" Write-Host -ForegroundColor Cyan @" Solution $SolutionName will be transferred from $SourceCrmInstance to $DestinationCrmInstance; The solution will be in imported in $(if($Managed) {"MANAGED"} else {"UNMANAGED"}) mode; Cusomizations WILL $(if(-not $PublishCustomizations) {"NOT "})BE PUBLISHED; "@ if ($UpdateVersion) { Write-host -ForegroundColor Cyan " The soluion version will be upgraded to $UpdateVersion;" } Write-host -ForegroundColor Cyan @" The solution import will begin $(if($ImportTime) {"at $($ImportTime.ToShortDateString()) $($ImportTime.ToLocalTime().ToLongTimeString())"} else {"immediately"}); The following emails will be notified of the results: $Emails Changes will be committed to branch $Branch with the following message: "$CommitMessage" "@ if (-not $Force.IsPresent) { Write-host "Please review all the information printed above. Is this information correct?" -ForegroundColor Yellow $Readhost = Read-Host "Select Y or N (default N) " Switch ($ReadHost) { Y { $continue = $true} N { $continue = $false} Default { $continue = $false } } if (-not $continue) { Write-Host "Canceling operation." return } } # Export the solution ------------------------------------------------- Export-RegentSolution ` -SolutionName $SolutionName ` -conn $sourceConn ` -UpdateVersion $UpdateVersion # Pack the solution --------------------------------------------------- Push-RegentSolutionChanges -CommitMessage $CommitMessage -Branch $Branch # If not scheduled, import immediately if (-not $ImportTime) { Import-RegentSolution ` -SolutionName $SolutionName ` -CrmInstance $DestinationCrmInstance ` -Managed $Managed ` -PublishCustomizations $PublishCustomizations ` -Emails $Emails ` -Credential $global:cred Write-Host -ForegroundColor Green "Solution imported successfully!" } # Else, schedule the import for later by adding it to a json file else { $configPath = "$env:APPDATA\solution-imports.json" # create object with current job parameters $params = New-Object psobject -Property @{ SolutionName = $SolutionName; CrmInstance = $DestinationCrmInstance; Managed = $Managed; PublishCustomizations = $PublishCustomizations; Emails = $Emails; UserName = $env:USERNAME; Password = ($Credential.Password | ConvertFrom-SecureString) Time = $ImportTime; # Note the local time! } # Check for existing config. If it exists, append this job to it, otherwise just write this job if (Test-Path $configPath) { $existingConfig = Get-Content $configPath | ConvertFrom-Json if ($existingConfig) { if ($existingConfig.GetType().Name -eq "PSCustomObject") { $json = @($existingConfig, $params) | ConvertTo-Json } else { $json = ($existingConfig + @($params)) | ConvertTo-Json } } } else { $json = $params | ConvertTo-Json } $json > $configPath Write-Host -ForegroundColor Green "Solution import scheduled!" } } |