کد:
http://blogs.msdn.com/crm/archive/2008/02/22/how-to-deploy-microsoft-dynamics-crm-client-through-sms.aspx
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:
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:
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
3.3 At the Collection Properties screen, enter the collection name
3.4 After entering the collection name, select the “Membership Rules” tab, then click in the button
.
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.
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.
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”
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.
4.5 For the Package Identification page, enter a name for the package then click Next.
4.6 At the Sources Files page, select “Create a compressed version of the source”
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.
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.
4.9 At the Program Identification page, enter the Program Name and the command line.
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
/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.
4.11 At the Advertise a Program page, select Yes.
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.
The advertisement status messages will be shown.
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