While the subject of my post may be very presumptuous, I submit the following for your consideration to answer the often-asked question about how to deploy Lync 2010 client with SCCM.
Background:
I cannot understand why Microsoft made the Lync install so darned confusing, complex, and convoluted.
After our Lync 2010 FE server was up and running and all users migrated off our OCS server to the Lync environment, I spent about a month and a half trying to figure out how to:
1. Uninstall the OCS 2007 R2 client
2. Install all prerequisites for the Lync client
3. Install Lync on all user workstations silently.
While researching this, the simple answer I kept seeing given to this question was, "just use the .exe with the right switches according to the TechNet article here: http://technet.microsoft.com/en-us/library/gg425733.aspx". Well, my response is, I tried that and while the program installed itself correctly pushed through SCCM, because I was doing it using an administrative account (i.e. the SYSTEM account) due to our users not having admin rights, when the install was done, Lync would automatically start up, but in the SYSTEM context so that the user couldn't see it was running, they go to run it and it won't run for them. I was unable to find any switch or option to prevent the automatic launch. I suppose the simple solution to that would be to have the user reboot, but that's unnecessarily disruptive and was contrary to the desire to make this a silent install.
The next simplest answer I saw was, "extract the MSI and use that with the right switches". Problem with that is that the MSI by itself doesn't remove the OCS client or install the prerequisites, and also either requires a registry change to even allow the MSI to be used or a hacked MSI that bypasses the registry key check. I tried to put a package together to uninstall OCS, install the prereqs, and use a hacked MSI, but I never could get the MSI hacked properly. The other problem I ran into was detecting if the OCS client was running in a predictable way so I could terminate it, properly uninstall it, and then do the rest of the installations. It was this problem that ultimately led me to the solution that I'm about to detail and that has worked marvellously for us.
Solution:
As I said before, when I first looked at this problem, I started by building a typical software deployment package (Computer Management -> Software Distribution -> Packages) and then created the programs to do the install. My first attempt was just with the .exe file provided as-is by Microsoft using the switches they document in the link above for IT-Managed Installation of Lync, and...well, the end result wasn't quite as desirable as hoped. So, my next attempt was to extract all the prerequisite files and the Lync install MSI (both for x86 and x64), attempt to hack it to get around the "UseMSIForLyncInstallation" registry key, and make the command-lines to terminate OCS and uninstall it.
In the past when I had an install to do with SCCM that also required uninstalling an older version of a given application, I typically used the program-chaining technique. That's where you have, for example, 3 or more programs that run in a package in a sequence and you have Program 3 be set to run after Program 2 does and then set Program 2 to run after Program 1 so you get the desired sequence of Programs 1-2-3 running in that order. So, I created programs to 1) kill Communicator.exe 2) uninstall Communicator 2007 R2 by doing an "msiexec /uninstall {GUID}" 3) install Silverlight 4) install Visual C++ x86 5) optionally install Visual C++ x64, and then 6) install the Lync x86 or x64 client. That final step was always the point of failure because I couldn't get the hacked MSI for the Lync Client install to work. I also realized that if Communicator wasn't running when the deployment started, that step would fail and cause the whole process to bail out with an error. That's one of the downsides of program-chaining, if one step fails, SCCM completely bails on the deployment. This is what also led me to the key to my solution: TASK SEQUENCES.
I'm not sure how many people out there look in the "Operating System Deployment" area of SCCM 2007 where Task Sequences normally live, but I also wonder how many people realize that Task Sequences can be used for more than just Operating System deployments. One of the biggest advantages of a task sequence is you can set a step to ignore an error condition, such as if you try to terminate a process that isn't running. Another advantage is that task sequences have some very good built-in conditionals that you can apply to steps, for example, having the sequence skip a step if a certain application (or specific version of an application) is not installed on the machine. Both of those advantages factor highly into my solution.
OK, for those who already think this is "TL;DR", here's the step-by-step of how to do this:
First, you need to extract all the files from the LyncSetup.exe for your needed architectures. We have a mix of Windows XP and Windows 7 64-bit, so my solution here will take both possibilities into account. To extract the files, just start up the .exe like you're going to install it, but then when the first dialog comes up, navigate to "%programfiles%\OCSetup" and copy everything there to a new location. The main files you need are: Silverlight.exe, vcredist.exe (the x64 LyncSetup.exe includes both x86 and x64 Visual C++ runtimes, you need them both, just rename them to differentiate), and Lync.msi (this also comes in an x86 and x64 flavor, so if you have a mix of architectures in your environment, get both and either put them into their own directories or rename them to reflect the architecture).
For my setup, I extracted the files for the x86 and x64 clients and just dumped them each into directories named after the architectures.
Next, move these files into a directory to your SCCM file server, whatever it might be that you deploy from, in our case, it was just another volume on our central site server. Go to the SCCM console into Computer Management -> Software Distribution -> Packages and then create a new package, call it something meaningful, and then point to the directory on your SCCM file server for the source files.
Now you need to create 3 to 5 programs inside the package:
1. Name: Silverlight
Command Line: x86\Silverlight.exe /q (remember, inside my main Lync install folder on my distribution point, I have an x86 directory for the files from the x86 installer and an x64 folder for the files from the x64 installer. The fact is the Silverlight installer is the same in both, so you only need one of them.)
On the Environment tab: Program can run whether or not a user is logged in, runs with administrative rights, Runs with UNC name
On the Advanced tab: Suppress program notifications
All other options leave default.
2. Name: Visual C++ x86
Command Line: x86\vcredist_x86.exe /q
On the Requirements tab: Click the radio button next to "This program can run only on specified client platforms:" and then check off the desired x86 clients.
Environment and Advanced tabs: same as Silverlight
(If you have only x64 clients in your environment, change all x86 references to x64. If you have a mixed environment, create another program identical to this one, replacing references to x86 with x64.)
3. Name: Lync x86
Command Line: msiexec /qn /i x86\Lync.msi OCSETUPDIR="C:\Program Files\Microsoft Lync" (The OCSETUPDIR fixes the issue with the Lync client wanting to "reinstall" itself every time it starts up)
Requirements, Environment, and Advanced tabs: Same as with Visual C++ and Silverlight
(Same deal as above if you have all x64 clients or a mix, either change this program to reflect or make a second program if necessary)
Now you need to make the Task Sequence. Go to Computer Management -> Operating System Deployment -> Task Sequences. Under the Actions pane, click New -> Task Sequence. In the Create a New Task Sequence dialog, choose "create a new custom task sequence", Next, enter a meaningful name for the task sequence like "Install Microsoft Lync", Next, Next, Close.
The task sequence will have up to 12 steps in it. I'll break the steps down into 3 phases, the prereqs phase, uninstall OCS phase, and then Lync install phase.
Prereqs Phase:
These are the easiest of the steps to do. Highlight the task sequence and then in the Actions pane, click Edit.
1. Click Add -> General -> Install Software. Name: "Install Microsoft Silverlight". Select "Install a single application", browse to the Lync package created earlier and then select the Silverlight program.
2. Add -> General -> Install Software. Name: "Install Microsoft Visual C++ 2008 x86". Install Single Application, browse to the Lync package, select the Visual C++ x86 package.
As before, if you're an all-x64 environment, replace the x86 references with x64. If you have a mixed environment, repeat step 2, replacing x86 with x64.
3. Add -> General -> Run Command Line. Name: "Enable Lync Installation". This step gets around the UseMSIForLyncInstallation registry requirement. The Lync client MSI simply looks for the presence of this key when it runs, so
we'll inject it into the registry now and it doesn't require a reboot or anything. It just has to be there before the client MSI starts.
Command Line: reg add "hklm\Software\Policies\Microsoft\Communicator" /v UseMSIForLyncInstallation /t REG_DWORD /d 1 /f
Uninstall OCS Phase:
This part consists of up to 6 Run Command Line steps. (Add -> General -> Run Command Line)
4. Name: "Terminate Communicator". Command Line: "taskkill /f /im communicator.exe". On the Options page, check the box next to "Continue on error". This will terminate the Communicator process if it's running, and if it's not, it'll ignore the error.
5. Name: "Terminate Outlook". Command Line: "taskkill /f /im OUTLOOK.exe". Check the "Continue on error" on the Options page here too. Communicator 2007 hooks into Outlook, so if you don't kill Outlook, it might prompt for a reboot because components are in use.
(NOTE: If necessary, you could also add another step that terminates Internet Explorer because Communicator does hook into IE and without killing IE, it might require a restart after uninstalling Communicator in the next steps. I didn't run into this in my environment, though. Just repeat step 5, but replace OUTLOOK.EXE with IEXPLORE.EXE)
6. Name: "Uninstall Microsoft Office Communicator 2007". Command Line: "msiexec.exe /qn /uninstall {E5BA0430-919F-46DD-B656-0796F8A5ADFF} /norestart" On the Options page: Add Condition -> Installed Software -> Browse to the Office Communicator 2007 non-R2 MSI -> select "Match this specific product (Product Code and Upgrade Code)".
7. Name: "Uninstall Microsoft Office Communicator 2007 R2". Command Line: "msiexec.exe /qn /uninstall {0D1CBBB9-F4A8-45B6-95E7-202BA61D7AF4} /norestart". On the Options page: Add Condition -> Installed Software -> Browse to the Office Communicator 2007 R2 MSI -> select "Match any version of this product (Upgrade Code Only)".
SIDEBAR
OK, I need to stop here and explain steps 6 and 7 in more detail because it was a gotcha that bit me after I'd already started deploying Lync with this task sequence. I found out after I'd been deploying for a while that a tech in one of our remote offices was reinstalling machines and putting the Communicator 2007 non-R2 client on instead of the R2 client, and my task sequence was expecting R2, mostly because I thought we didn't have any non-R2 clients out there. So, at first I just had our Help Desk people do those installs manually, but later on decided to add support for this possibility into my task sequence. Now, when you normally uninstall something with msiexec, you would use the Product Code GUID in the command, as you see in steps 6 and 7. All applications have a Product Code that's unique to a specific version of an application, but applications also have an Upgrade Code GUID that is unique for an application but common across versions. This is part of how Windows knows that Application X version 1.2 is an upgrade to Application X version 1.1, i.e. Application X would have a common Upgrade Code, but the Product Code would differ between versions 1.1 and 1.2.
The complication comes in that Communicator 2007 and Communicator 2007 R2 have a common Upgrade Code, but different Product Codes and the "MSIEXEC /uninstall" command uses the Product Code, not the Upgrade Code. This means that if I didn't have step 6 to catch the non-R2 clients, step 7 would be fine for the R2 clients, but fail on non-R2 clients because the Product Code in the MSIEXEC command would be wrong. Luckily, we only had one version of the non-R2 client to deal with versus 4 or 5 versions of the R2 client. So, I put the command to remove Communicator 2007 non-R2 first and checked for that specific product and version on the machine. If it was present, it uninstalled it and then skipped over the R2 step. If non-R2 was not present, it skipped that step and instead uninstalled any version of the R2 client. It's important that steps 6 and 7 are in the order they are because if you swap them, then you'd have the same outcome as if step 6 wasn't there. What if neither is on the machine? Well the collection this was targeted to included only machines with any version of Communicator 2007 installed, so this was not a problem. It was assumed that the machines had some version of Communicator on them.
8. Name: "Uninstall Conferencing Add-In for Outlook". Command Line: "msiexec.exe /qn /uninstall {730000A1-6206-4597-966F-953827FC40F7} /norestart". Check the "Continue on error" on the Options Page and then Add Condition -> Installed Software -> Browse to the MSI for this optional component and set it to match any version of the product. If you don't use this in your environment, you can omit this step.
9. Name: "Uninstall Live Meeting 2007". Command Line: "msiexec.exe /qn /uninstall {69CEBEF8-52AA-4436-A3C9-684AF57B0307} /norestart". Check the "Continue on error" on the Options Page and then Add Condition -> Installed Software -> Browse to the MSI for this optional component and set it to match any version of the product. If you don't use this in your environment, you can omit this step.
Install Lync phase:
Now, finally the main event, and it's pretty simple:
10. Click Add -> General -> Install Software. Name: "Install Microsoft Lync 2010 x86". Select "Install a single application", browse to the Lync package created earlier and then select the "Lync x86" program. As before, if you only have x64 in your environment, replace the x86 with x64, or if you have a mixed environment, copy this step, replacing x86 references with x64.
And the task sequence is done! The final thing you need to do now is highlight the task, click Advertise in the Actions pane, and deploy it to a collection like you would with any other software distribution advertisement. Go get a beer!
Some final notes to keep in mind:
1. You can't make a task sequence totally silent...easily. Users will get balloon notifications that an application is available to install. The notifications cannot be suppressed through the GUI. I've found scripts that supposedly hack the advertisement to make it be silent, but neither of them worked for me. It was OK, though because in the end we wanted users, especially laptop users, to be able to pick a convenient time to do the upgrade. The task sequence will appear in the "Add/Remove Programs" or "Programs and Features" Control Panel. You can still do mandatory assignments to force the install to happen, you just can't make it totally silent. On the plus side, the user shouldn't have to reboot at any point during or after the install!
2. In the advertisement setup, you can optionally show the task sequence progress. I've configured the individual installs in this process to be silent, however, I did show the user the task sequence progress. This means instead of seeing 5 or 6 Installer windows pop up and go away, the user will have a single progress bar with the name of the step that is executing.
3. One step that I didn't consider when I actually did this was starting the Lync client as the user when the install was complete. The user either had to start the client manually or just let it start on its own at the next logon. However, while I was writing this, I realized that I could possibly start the client after installing by making another Program in the Lync Package with a command line that was along the lines of "%programfiles%\Microsoft Lync\communicator.exe" and then in the Environment tab, set it to "Run with user's rights" "only when a user is logged on".
4. My first revision of this task sequence has the Prereqs phase happening after the OCS uninstall phase, but I kept running into problems where the Silverlight installer would throw some bizarre error that it couldn't open a window or something wacky and it would fail. Problem was, I couldn't re-run the task sequence because now it would fail because OCS had been uninstalled, so that's why the Prereqs happen first. It ran much more reliably this way.
5. For some reason that baffles me, when I'd check the logs on the Site Server to monitor the deployment, I'd frequently see situations where the task sequence would start on a given machine, complete successfully, almost immediately start again, and then fail. I'm not sure what is causing that, but I suspect either users are going to Add/Remove Programs and double-clicking the Add button to start the install instead of just single-clicking it, or the notification that they have software to install doesn't go away immediately or Lync doesn't start up right after the install, so they think the first time it didn't take and try it a second time.
I hope this helps some of you SCCM and Lync admins out there!