Tuesday, 6 September 2016

Upgrading Microsoft CRM Dynamics from 2011 to 2016

Upgrading Microsoft CRM Dynamics from 2011 to 2016 for multiple Organizations

On today’s post I will go through the upgrade multiple organizations in just one go using PowerShell or Console Application from version 2011 to 2016. So this will be a long post...

Prepare the environments:
Since we are dealing with 3 differents environments counting the 4th the source, in this case the Test or Production Environment. We need to create new 3 new environments with everything inside, CRM Dynamics, SQL, Async etc. One for 2013, one for 2015 and one for 2016.

In my case i have more then 1 organization per server and this will be really painful do it all by hand. So the script will help to speed up the upgrades and allow me to do other stuff when they are upgrading. Since this is a process that will take at least 2 hours depending on the size of the database, in some cases one day.... yes one day :( ...you cant spend time do it manually. So..

  1. If you are using VM`s or Azure or Amazon Web Services make sure the machines can see each other and if you doing clones of the VM be sure you run the "Sysperp" or you going to face problems on the CRM side and SQL server and even running the VM`s.
  2. Build the different environment installing the CRM normally in each machine with each version. (No need to create one machine to Async, other for SQL, put everything in the same machine or you will have problems and will take you more time.)
  3. After all done and CRM running on each version on each machine we can now start to build our PorwerShell or Console application
The below script will help you to do all this process automatically.

Having in mind the following:
  • Creating a copy of your production CRM database (if needed) or just do a backup.
  • The below script don't do backups, therefore you will need to create the rest of the script, however it will not be needed because the code only copy`s the Database to a new destination server.
  • This script will not upgrade your custom code / solution. For more information about how to upgrade your code see my post regarding that: http://hugorsilva.blogspot.ie/2015/03/migration-to-crm-20111315-and.html 
  • If you having problems and errors importing the Organizations make sure you don't have other organization with the same Guid, open the Deployment Management and Delete the other Org with the same Guid, this could happen if you doing Test.
  • Make sure no one break your eggs :D

Let`s Start... Powershell
Note: Before you run the script please search on the code pieces for "CHANGE TEXT HERE" to setup and configure. This is needed for you to change the Server Names, Folders and Reporting Servers URL.

Prompt the user to request the values for server names, database names, etc.
$newOrgName = read-host "New Organization Name ex:ContosoNew"$Server1 = read-host "2011 Source Server"$Server2 = read-host "2013 Destination Server"$Server3 = read-host "2015 Destination Server"$Server4 = read-host "2016 Destination Server"$Db1 = read-host "Source Database Name ex:Contoso_MSCRM"$Db2 = read-host "Destination Database Name ex:ContosoNew_MSCRM"
$appSVR = read-host "Application Server"

SQL Function:
This will be used to copy the database from one server to other, like server1 to server2 and so on. Create the variables need on your code to do the connection and assign paths.

function SQLCopy {[cmdletBinding(DefaultParametersetName='WindowsAuthentication')]param(                [Parameter(Mandatory=$true, ParameterSetName = 'WindowsAuthentication')]                [Parameter(Mandatory=$true, ParameterSetName = 'SQLAuthentication')]                [ValidateNotNullOrEmpty()]                [alias('Source', 'Src')]                [System.String]                $SourceInstance                ,                [Parameter(Mandatory=$true)]                [ValidateNotNullOrEmpty()]                [alias('SourceDb', 'SrcDb', 'Database')]                [System.String]                $SourceDatabase                ,                [Parameter(Mandatory=$true)]                [ValidateNotNullOrEmpty()]                [alias('Target', 'Tgt')]                [System.String]                $TargetInstance                ,                [Parameter(Mandatory=$false)]                [ValidateNotNullOrEmpty()]                [alias('TargetDb', 'TgtDb', 'RenameAs')]                [System.String]                $TargetDatabase = $SourceDatabase                ,                [Parameter(Mandatory=$true)]                [ValidateNotNullOrEmpty()]                [alias('Path')]                [System.String]                $BackupDirectoryPath # <--<-- CHANGE TEXT HERE - Add folder name and create variable                ,                [Parameter(Mandatory=$true, ParameterSetName = 'SQLAuthentication')]                [ValidateNotNull()]                [System.String]                $Username                ,                [Parameter(Mandatory=$true, ParameterSetName = 'SQLAuthentication')]                [ValidateNotNull()]                [System.String]                $Password                ,                [Parameter(Mandatory=$false)]                [Switch]                $Force = $false)

Migration Function:
This will copy the database from Server1 (Source) to Server2 (Destination) by calling the  the function SQLCopy and will import the Organization into the CRM 2013 and will do upgrade after. To repeat the process for 2015 and 2016 you only need to duplicate the following code with the different name servers, folders and functions, changing also 2013 to 2015 and so on. Bear in mind if you change the variables names you need to change also on the prompt variables.

function 2013Merge {                New-Item "\\2013DestinationServer\migration\$Db1\2013$Db1" -type directory # <--<-- CHANGE TEXT HERE - Dont forget to create the folder
SQLCopy -SourceInstance $Server1 -SourceDatabase $Db1 -TargetInstance $Server2 -TargetDatabase $Db2 -BackupDirectoryPath \\2013DestinationServer\migration\$Db1\2013$Db1 # <--<-- CHANGE TEXT HERE - Change folder name                Invoke-Command -ComputerName $Server2 -ScriptBlock {
                }                Invoke-Command -ComputerName $Server2 -ScriptBlock {                                New-ItemProperty HKLM:\SOFTWARE\Microsoft\MSCRM -Name "MergeBaseAndExtensionTables" -Value "0" -PropertyType dword
                                Set-ItemProperty HKLM:\SOFTWARE\Microsoft\MSCRM -Name "MergeBaseAndExtensionTables" -Value "0"                      
                C:\Windows\Microsoft.NET\Framework64\v4.0.30319\installutil.exe "C:\Program Files\Microsoft Dynamics CRM\Tools\Microsoft.Crm.PowerShell.dll" # <--<-- CHANGE TEXT HERE - Change Files Origin                Add-PSSnapin Microsoft.Crm.PowerShell
                $opId = Import-CrmOrganization -SqlServerName $($args[0]) -DatabaseName $($args[1]) -SrsUrl "https://2013DestinationServer/ReportServer" -DisplayName $($args[2]) -Name $($args[2]) -UserMappingMethod KeepExisting # <--<-- CHANGE TEXT HERE - Change Reporting Server URL
                $opStatus = (Get-CrmOperationStatus -OperationId $opId).State                Write-Output "Starting 2013 Import"
                While ($opStatus -ne 'Completed')
                                {                                                Write-Output " 2013 In progress..."                                                Start-Sleep -Seconds 30                                                $opStatus = (Get-CrmOperationStatus -OperationId $opID).State                                }
                Write-Output "Import 2013 Completed!"
                Set-ItemProperty HKLM:\SOFTWARE\Microsoft\MSCRM -Name "MergeBaseAndExtensionTables" -Value "1"
                New-ItemProperty HKLM:\SOFTWARE\Microsoft\MSCRM -Name "EnableRecreateCustomIndexes" -Value "1" -PropertyType dword
       Set-ItemProperty HKLM:\SOFTWARE\Microsoft\MSCRM -Name "EnableRecreateCustomIndexes" -Value "1"
                Write-Output "Disabling Org and Starting Table Merge"
                Disable-CrmOrganization -Name $($args[2])
                              } -argumentlist $Server2, $Db2, $newOrgName                               Invoke-Command -ComputerName $Server2 -ScriptBlock {
                                New-Item "c:\CRMMigration" -type directory                                C:\"Program Files"\"Microsoft Dynamics CRM"\tools\CrmMergeBaseAndExtensionTableTool.exe /s:2013DestinationServer /o:$($args[0]) /log:c:\CRMMigration\mergelog.txt # <--<-- CHANGE TEXT HERE - Change Destination Files, folder and Server Name
                                C:\Windows\Microsoft.NET\Framework64\v4.0.30319\installutil.exe "C:\Program Files\Microsoft Dynamics CRM\Tools\Microsoft.Crm.PowerShell.dll"                                Add-PSSnapin Microsoft.Crm.PowerShell                                Enable-CrmOrganization -Name $($args[1])
                } -argumentlist $Db2, $newOrgName}

You can always check if the upgrading is running well by open the Deployment Manager and if the organization is on the Status "Pending" means that the Deployment Manager is doing the upgrade, this may take several hours... so sit back and relax :D

Common Issues:

  • If you get any error will show up on the Powershell and also on the Log located at c:\CRMMigration\mergelog.txt (Code removed for professional reasons)
  • You could also have the following issue in case you import the Organization manually, don't worry this is a normal alert.

Thank you and enjoy.

No comments:

Post a Comment