Microsoft Dynamics 365 Blog

This document explains the techniques that I have been using to deploy Microsoft Dynamics CRM Client through SMS. It is a series of steps that worked for us, and not necessarily is the best and for sure is not the only way to do this.

For those already acquainted with SMS and CRM Client setup, this is a short list of what must be taken into consideration to install CRM Client using SMS:

a. Advertisement must run with Administrative Rights.

b. For Offline Client, Advertisement must allow users to interact with the program.

c. For Offline Client, do not use SetupClient’s option /q.

1. Copy setup binaries to a known location

In order to avoid exc essive network traffic, it is a good idea to copy the setup files to the SMS server computer.

1.1 Log on to your SMS server as administrator.

1.2 Go to the setup DVD.

1.3 Create a folder in your SMS server computer, for instance, create a folder named C:\CRMClient

1.4 Merge the Client and the Redists\i386 folders into C:\CRMClient:

1.5 Copy all files and folders from the folder Client in the DVD to the folder C:\CRMCLient

1.6 Copy all files and folders from the folder Redists\i386 from the DVD to the folder C:\CRMCLient. This way, C:\CRMClient will have the following folders and files:

clip_image002

2. Troubleshooting

2.1 General instructions:

2.1.1 Use a non-administrator account. If some operations need administrator privileges, follow these steps:

2.1.1.1 Open a command line prompt.

2.1.1.2 Run:

RunAs /user:<domainname>\administrator cmd

(Of course, <domainname> must be substituted by the proper domain name)

2.1.1.3 Enter administrator password.

2.1.1.4 This way all commands will be entered as administrator, the most useful ones are:

  • Cmd
  • Control
  • Explorer
  • MSTSC

2.1.2 Make sure CRM Client and SQL Server Express are not installed. For instructions, see section 6. Uninstalling.

2.2 Very important: SMS needs a client installed at the client computer. The SMS server must have a shared folder with the installer, ccmsetup. So, if the SMS server is asharadsms and if the share is SMS and the SMS instance is named AS1, the following command line must be ran with administrative rights at the client: \\ asharadsms\sms\client\i386\ccmsetup INSTALLSOURCE=AS1

3. Create collection

An SMS collection contains a set of resources for software distribution. In this case, the resources are the client computers.

3.1 At the SMS Server, logged on as administrator, open SMS

3.2 Open the site Database, right click in “Collections” then select New/Collection

clip_image004

3.3 At the Collection Properties screen, enter the collection name

clip_image006

3.4 After entering the collection name, select the “Membership Rules” tab, then click in the button clip_image008.

3.5 Dismiss the initial Wizard page.

3.6 In the “Search for Resources” page, select Resource Class == “System Resource”, Attribute name == Name, and Value == % (percent). This will return all resources. Or, a specific computer name can be entered.

clip_image010

3.7 In the “Collection Limiting” page, just click Next.

3.8 In the “Select Resources” page, select the computers that should receive CRM Client.

clip_image012

3.9 At the last page, click on Finish.

4. Distribute setup using SMS wizard

4.1 At the SMS Server, logged on as administrator, open SMS

4.2 Open the site Database, open Collections, right click at the desired collection (e.g. the one created in step 3, above), then select All Tasks/Distribute Software. This will start the “Distribute Software to Collection Wizard”

clip_image014

4.3 At the wizard’s first page, click Next.

4.4 At the Package page, select “Create a new package and program” then click Next.

clip_image016

4.5 For the Package Identification page, enter a name for the package then click Next.

clip_image018

4.6 At the Sources Files page, select “Create a compressed version of the source”

clip_image020

4.7 At the Source File Compression page, select “Local drive on site server”, then Browse to the folder that received the setup files as described in section 1 Copy setup binaries to a known location.

clip_image022

VERY IMPORTANT: the source directory must be the folder where the file SetupClient.exe is located.

4.8 At the Distribution Points page, select the SMS server.

clip_image024

4.9 At the Program Identification page, enter the Program Name and the command line.

clip_image026

IMPORTANT:

  • Name: can be any name, a descriptive one preferrably.
  • Command line:

SetupClient.exe /targetdir “c:\program files\Microsoft CRM” INSTALLLEVEL=3 /l c:\log.txt

  • Where:

/targetdir informs where the client must be installed.

INSTALLLEVEL informs what client will be installed: 2==Desktop (always online), 3==Laptop

/l informs where to put the log.

VERY IMPORTANT:

Do not use the /q setup flag for Offline Client.

For Online Client (desktop client), the /q setup flag can be used. This way, setup will run silently. So the command line could be like this:

SetupClient.exe /q /targetdir “c:\program files\Microsoft CRM” INSTALLLEVEL=2 /l c:\log.txt

4.10 At the Program Properties page, select

VERY IMPORTANT, USE THESE SETTINGS,

  • Program can run: Only when a user is logged on.
  • Run with administrative rights.
  • For Laptop Client (where client can go offline):
    • Allow users to interact with this program. (Due to the need to install pre-requisite components, these settings are mandatory, which means silent install cannot be used).
  • For Desktop Client (client will not go offline):
  • The option “Allow users to interact with this program” can be disabled if so desired. This will allow silent install.

clip_image028

4.11 At the Advertise a Program page, select Yes.

clip_image030

4.12 At the Select a Program to Advertise page, just click Next.

4.13 At the Advertisement Name page, just click Next.

4.14 At the Advertise to Subcollections page, just click Next.

4.15 At the Advertisement Schedule page, make sure the advertisement never expires, then click Next.

4.16 At the Assign Program page, select Yes, then click Next.

4.17 At the last page, click Finish.

5. Checking distribution status

After the package is built and advertised, SMS will download the setup binaries to the client computer.

  • For a 32 bits computer, the binaries will be copied at the client to a folder under: C:\WINDOWS\System32\CCM\Cache
  • For a 64 bits, this is the folder: C:\WINDOWS\SysWOW64\CCM\Cache

The status for the downloading and execution can be verified at the server:

  • Open SMS/Site Database/System Status/Advertisement Status/Your advertisement
  • Right click Open then right click at the Site
  • Select Show Messages/All.

clip_image032

The advertisement status messages will be shown.

clip_image034

6. Install it at the client

The client computer will show a tray icon announcing that a new package is available. Double click at the icon, select the CRM Client package and click Run. If an error message is shown saying that the package is not yet available, wait some more minutes and try to run again. This is a known issue with SMS: it will display the info that a package is available before downloading all of the bits.

7. Uninstalling

7.1 Open “Add Remove Programs” (or Programs in Vista) in Control Panel.

7.2 Select Microsoft Dynamics CRM Client and uninstall it.

7.3 After CRM Client is uninstalled, select SQL Server and uninstall it:

7.4 When SQL Server uninstaller asks for what component to uninstall, select “CRM DataEngine” and follow the Wizard to remove this database.

7.5 Delete the folder c:\documents and settings\<UserName>\Application Data\Microsoft\MSCRM. Remove the MSCRM folder completely. For Vista, instead of “Documents and Settings” go to “Users”.

8. Automating tasks after installation is finished

Here’s a sequence to be used in a CMD file that starts client setup, then waits for the setup to finish and finally reboots the machine:

SetupClient.exe /q /targetdir “c:\program files\Microsoft CRM” INSTALLLEVEL=2 /l c:\log.txt

Cscript //nologo CRMSetupLogParser.vbs c:\log.txt Client V4 > ParserOutput.txt

Shutdown –r

Here’s the code for CRMSetupLogParser.vbs:

‘*************************************************************************************

‘CRM Setup Log Parser –

‘ Server setup only gets called once the log is done, so we loop once checking for an ERROR|

‘ Client setup gets called over and over as the log is being generated, so we’ll loop until we get a setup completed successfully message or see a failure

‘Incoming Parameters Examples:

‘ FileToParse = “C:\CRM_Server_Install.txt”

‘ LogType = Client|Server|ConfigureClient

‘ ClientVer = “V4” or “V3”

‘*************************************************************************************

Option Explicit

Dim objFileSystem

Dim objFile

Dim FileToParse

Dim InstallSuccesSearchString

Dim UninstallSuccesSearchString

Dim FailSearchString

Dim StringFound

Dim LogType

Dim LogToPS

Dim ClientVer

Dim PassFail

Dim WaitTime

Dim LineFromFile

Dim LineNumber

Dim TestCaseNumber

Dim BuildNumber

Dim RunPurpose

Dim Owner

Dim CRMServerName

Dim ClientMode

Dim ServerConfig

Dim PSLoggerArgs

Const ForReading = 1

Const TristateTrue = -1

Const CreateFile = False

StringFound = “False”

FileToParse = WScript.Arguments(0)

LogType = WScript.Arguments(1)

IF LogType = “ConfigureClient” THEN

IF WScript.Arguments.Count > 2 THEN

LogToPS = “False”

PSLoggerArgs = Split(WScript.Arguments(2),”,”)

TestCaseNumber = PSLoggerArgs(0)

BuildNumber = PSLoggerArgs(1)

RunPurpose = PSLoggerArgs(2)

Owner = PSLoggerArgs(3)

CRMServerName = PSLoggerArgs(4)

ClientMode = PSLoggerArgs(5)

ServerConfig = PSLoggerArgs(6)

END IF

ELSEIF LogType = “Server” THEN

IF WScript.Arguments.Count > 2 THEN

LogToPS = “False”

PSLoggerArgs = Split(WScript.Arguments(2),”,”)

TestCaseNumber = PSLoggerArgs(0)

BuildNumber = PSLoggerArgs(1)

RunPurpose = PSLoggerArgs(2)

Owner = PSLoggerArgs(3)

CRMServerName = PSLoggerArgs(4)

ClientMode = PSLoggerArgs(5)

ServerConfig = PSLoggerArgs(6)

END IF

ELSEIF LogType = “Client” THEN

ClientVer = Ucase(WScript.Arguments(2))

IF WScript.Arguments.Count > 3 THEN

LogToPS = “False”

PSLoggerArgs = Split(WScript.Arguments(3),”,”)

TestCaseNumber = PSLoggerArgs(0)

BuildNumber = PSLoggerArgs(1)

RunPurpose = PSLoggerArgs(2)

Owner = PSLoggerArgs(3)

CRMServerName = PSLoggerArgs(4)

ClientMode = PSLoggerArgs(5)

ServerConfig = PSLoggerArgs(6)

END IF

END IF

WaitTime = 1000 * 15 ‘The amount of time we’ll wait to let setup get started

LineNumber = 1

‘Call correct log parsing function

‘ The ConfigureClient and Server are the same setup logic

IF LogType = “Client” THEN

ClientSetupLogParser()

ELSEIF LogType = “ConfigureClient” THEN

ServerSetupLogParser()

ELSEIF LogType = “Server” THEN

ServerSetupLogParser()

END IF

‘Write final Pass/Fail to the WTT logger

IF PassFail = “Pass” THEN

WScript.Quit(0)

ELSE

WScript.Quit(1)

END IF

‘*************************************************************************************

‘ClientSetupLogParser –

‘*************************************************************************************

Function ClientSetupLogParser()

IF ClientVer = “V4” THEN

InstallSuccesSearchString = “INSTALL.*1” ‘Regular Expression, search for case sensitive “INSTALL (anything) 1”

UninstallSuccesSearchString = “INSTALL.*1” ‘Regular Expression, search for case sensitive “INSTALL (anything) 1”

FailSearchString = “Installation failed”

ELSEIF ClientVer = “V3” THEN

InstallSuccesSearchString = “Info\| Exit code: 0”

UninstallSuccesSearchString = “has been successfully uninstalled”

FailSearchString = “Error\|”

END IF

Wscript.sleep(WaitTime)

Set objFileSystem = CreateObject(“Scripting.FileSystemObject”)

Set objFile = objFileSystem.OpenTextFile(FileToParse, ForReading, CreateFile, TristateTrue)

Dim Timer, TimeLimit ‘ We’ll only loop for %TimeLimit% minutes as a fallback

Timer = 0

TimeLimit = 20

DO WHILE PassFail = “”

DO WHILE NOT objFile.AtEndOfStream

LineFromFile = objFile.ReadLine

‘Check for failure

IF (RegExMatch(FailSearchString, LineFromFile)) THEN

PassFail = “Fail”

ELSEIF (RegExMatch(InstallSuccesSearchString, LineFromFile)) THEN

‘If we’ve already set it to Fail, we don’t want to overwrite it if the success line appears further down the line

IF PassFail <> “Fail” THEN

PassFail = “Pass”

END IF

ELSEIF (RegExMatch(UninstallSuccesSearchString, LineFromFile)) THEN

‘If we’ve already set it to Fail, we don’t want to overwrite it if the success line appears further down the line

IF PassFail <> “Fail” THEN

PassFail = “Pass”

END IF

END IF

LineNumber = LineNumber + 1

LOOP

IF PassFail = “” THEN

Wscript.sleep(1000 * 60)

Timer = Timer + 1

END IF

IF Timer > TimeLimit AND ClientVer = “V4” THEN ‘ Didn’t find a result in time, assume a pass and move on

PassFail = “Pass”

END IF

LOOP

End Function

‘*************************************************************************************

‘ServerSetupLogParser

‘*************************************************************************************

Function ServerSetupLogParser()

FailSearchString = “Error|”

Set objFileSystem = CreateObject(“Scripting.FileSystemObject”)

Set objFile = objFileSystem.OpenTextFile(FileToParse, ForReading, CreateFile, TristateTrue)

WScript.Sleep (WaitTime)

DO WHILE NOT objFile.AtEndOfStream

LineFromFile = objFile.ReadLine

IF (INSTR(1, LineFromFile, FailSearchString, 1) > 0) THEN

PassFail = “Fail”

END IF

LineNumber = LineNumber + 1

LOOP

IF PassFail <> “Fail” THEN

PassFail = “Pass”

END IF

End Function

‘*************************************************************************************

‘PSLogger

‘*************************************************************************************

Function PSLogger(PassFail)

Dim sh

Dim wsx

Dim cmd

Set sh = CreateObject(“WScript.Shell”)

End Function

‘ Runs an external program and pipes it’s output to

‘ the StdOut and StdErr streams of the current script.

‘ Returns the exit code of the external program.

Function Run (ByVal cmd)

Dim sh: Set sh = CreateObject(“WScript.Shell”)

Dim wsx: Set wsx = Sh.Exec(cmd)

If wsx.ProcessID = 0 And wsx.Status = 1 Then

‘ (The Win98 version of VBScript does not detect WshShell.Exec errors)

Err.Raise vbObjectError,,”WshShell.Exec failed.”

End If

Do

Dim Status: Status = wsx.Status

WScript.StdOut.Write wsx.StdOut.ReadAll()

WScript.StdErr.Write wsx.StdErr.ReadAll()

If Status <> 0 Then Exit Do

WScript.Sleep 10

Loop

Run = wsx.ExitCode

End Function

‘*************************************************************************************

‘Regular Expression comparison function

‘*************************************************************************************

Function RegExMatch(Pattern,StringToSearch)

Dim RegEx, Match

Set regEx = new RegExp

regEx.Pattern = Pattern

regEx.IgnoreCase = False

regEx.Global = True

RegExMatch = regEx.Test(StringToSearch)

End Function

Lucidio Mayer Kuhn Filho

We're always looking for feedback and would like to hear from you. Please head to the Dynamics 365 Community to start a discussion, ask questions, and tell us what you think!