Enterprise Printing Introduction

Until now, I have focused all of my blog posts on deploying software. With this and subsequent posts, I use a broader definition of the word “deployment”. This is the first of a series of posts on deploying and managing printers in an enterprise.

Several of my coworkers and I were frustrated with inconsistent printer configurations, ad hoc printer deployment and management practices, and lack of printer driver management and deployment guidance in our organization. Online research yielded many results of how to implement specific technologies, but we found no big-picture guidance for managing printing in the enterprise. Over the course of about a year, we met biweekly on our own time to share research and experimental results, brainstorm, argue, and formulate a comprehensive enterprise printing service and strategy for our organization. We have implemented the service described in this blog series, and we offer this to the world as a model for enterprise printing implementation in any organization.

It was a privilege to collaborate with my colleagues Shaun Holmes, Matt Norton, and Branden Mazure on this project.

Problem and Goal

How do you deploy and manage printers? How do you provide users with connections to the printers that they need? How do you update printer software and drivers? How do you secure network printers?

These were some of the questions we faced as we began thinking about building and documenting an enterprise printing service for our organization. As we researched, we found a lot of vendor-specific documentation, a lot of which was not very good. We never found a comprehensive description of enterprise printing best practices, so we met and argued about it biweekly for a year, and this is the result.

Our goals:

  • Research and document high-quality enterprise printing guidance for use by ourselves and others to provide consistency and quality of service.
  • Build a system that we would want to use and which would provide as much flexibility and automation as possible.
  • Never think about printing again, except for when we want to.

Framework for Discussion

As we wrestled with the technical and human problems involved in enterprise printing, we arrived at the concept of “Enterprise Printing Competency” levels, or “EPC”. This is a framework where each idea builds and improves on the previous one, and if you stop at any point, you are better off than you were before.


“Enterprise Printing” refers to the management of network-connected printers using scripting or other tooling for automation, consistency, and reliability wherever possible. As examples, large departmental printers and multifunction copiers are in scope. Even a desktop printer used primarily by a single person is in scope if it is connected to the network. The following are not in scope:

  • Non-network-attached printers, such as a USB printer on a staff member’s desk.
  • Large printers or multifunction copiers without network connectivity.

To be clear, such out-of-scope devices would benefit from many of the practices described in this blog series, but I will make no effort to call these out. This is going to be a long series even with a narrow scope.

Many vendors would love to sell you their printer management products. In our organization, a large midwestern university, we use such a vendor solution to manage printers for student use, but we had no commercial solution for faculty and staff printers. The solution described here is for the latter case and uses capabilities already available in a Windows Server environment.

Continuum of Competency

The Enterprise Printing Competency (EPC) levels form a continuum. At the lowest level, EPC-0, all printer configuration and management is performed manually. Printing as an IT service is a high-maintenance, low-flexibility activity at EPC-0. As the EPC level of an organization increases, maintenance costs decrease and flexibility increases.

Illustration of Enterprise Printing Continuum of Competency

Here are the EPC levels shown above in table form for reference.

Enterprise Printing Competency (EPC) Levels
EPC Level Name
0 Manual Configuration
1 Names, Not Addresses
2 Secure Hardware
3 Print Servers
4 Deployment
5 High Availability, Part 1

The EPC continuum is open ended. We decided to stop at level 5 because we realized that it was all that was achievable in our organization at the time, but you can tell by the name that we imagined a future EPC-6 for further implementation of high availability (High Availability, Part 2).

Coming Up

In subsequent articles, I will describe each of the Enterprise Printing Competency levels in depth.

Posts in this series:

  1. Enterprise Printing Introduction

Deploying Microsoft .NET Framework 3.5 SP1 to Windows 10 Anniversary Update and Windows Server 2016 with System Center Configuration Manager

With the August 2016 release of Windows 10 version 1607 (“Anniversary Update”) and the initial release of Windows Server 2016 in October 2016, it is well past time to revisit last year’s entry on deploying the .NET Framework 3.5 SP1. Although Windows Server 2016 was released two months after its corresponding Windows 10 release, both have the same year-month version number of “1607”, and their build numbers are also identical: 14393. This is excellent news because it suggests that we may be able to use the same files for installing .NET 3.5 on both operating systems; indeed, investigation shows that the Microsoft-Windows-NetFx3-OnDemand-Package.cab files found under sources\sxs on the installation media for Windows 10 v1607 64-bit and Windows Server 2016 are identical.

Please refer to my January 2016 entry on building the Configuration Manager application for .NET 3.5 SP1 if you need to start from scratch. Below, I will add to that Configuration Manager application.

Acquiring the Payload Files

Remember, nearly every Windows version has a different payload for NetFx3. We will have to locate all of the needed files and copy them to a file share for access by Configuration Manager. In this case, we’ll just add to what we built before.

On your application staging file share (wherever you put application source files for Configuration Manager to find), locate the folder structure for .NET 3.5 that you created before. Mine is \\fileserver\software$\Microsoft\.NET Framework 3.5 SP1. Under this folder, create a folder for each operating system version that we will be adding. Note that the 64-bit client OSes can share source files with their server counterparts; as mentioned above, I checked, and the NetFx3 files are the same for Windows Server 2016.

Folder Name Description
Win10.0.14393×86 Windows 10 Anniversary Update (32-bit)
Win10.0.14393×64 Windows 10 Anniversary Update and Windows Server 2016 (64-bit)

We are only adding two deployment types to our existing ConfigMgr application, but they will bring the total count of deployment types to 11.

Get your DVDs or ISOs ready; it’s time to copy the NetFx3 payload files to the folders you just created! Assuming that your Windows 10 v1607 32-bit installation media is available in drive D: (whether physical media or a mounted ISO), here is my preferred command to copy the files:

I prefer using Robocopy because it allows me to preserve the time stamps on any folders I am copying with the /DCOPY switch. Use a similar command to copy the NetFx3 content from the Windows 10 v1607 64-bit media to its folder in the folder structure we built above.

You can also get the files from the Features on Demand ISO available from the Microsoft Volume Licensing Service Center. In that case, use this command to copy the 32-bit Windows 10 Anniversary Update payload for NetFx3:

Building the Configuration Manager Application

Windows 10 and Windows Server 2016 v1607

Previously, we built deployment types for Windows 10 v1507 and v1511, 64-bit and 32-bit. We need to add two more deployment types for Windows 10 v1607 (“Anniversary Update”) and Windows Server 2016. The properties for these new deployment types are very similar to those for the earlier versions of Windows 10. As usual, we must make appropriate changes to the Name, Content location, and Requirements properties. We’ll use the custom Global Condition from a previous post in the Requirements. For any properties omitted below, such as the detection logic, use the same values as with earlier versions of Windows 10.

Property Value
Deployment Type Properties – Windows 10 Anniversary Update (32-bit)
Name Feature Installation – Windows 10 Version 1607 (32-bit)
Content location \\fileserver\software$\Microsoft\.NET Framework 3.5 SP1\Win10.0.14393×86\
Installation program “%SystemRoot%\System32\Dism.exe” /Online /LogLevel:4 /Add-Package /PackagePath:”Microsoft-Windows-NetFx3-OnDemand-Package.cab” /NoRestart /Quiet
Uninstall program “%SystemRoot%\System32\Dism.exe” /Online /LogLevel:4 /Remove-Capability /CapabilityName:NetFx3~~~~ /NoRestart /Quiet
Requirements Operating system
One of All Windows 10 (32-bit)
OS BuildNumber Equals 14393
Deployment Type Properties – Windows 10 Anniversary Update (64-bit)
Name Feature Installation – Windows 10 and Windows Server 2016 Version 1607 (64-bit)
Content location \\fileserver\software$\Microsoft\.NET Framework 3.5 SP1\Win10.0.14393×64\
Installation program Same as Windows 10 Anniversary Update (32-bit)
Uninstall program Same as Windows 10 Release (32-bit)
Requirements Operating system
One of All Windows 10 (64-bit), All Windows Server 2016 (64-bit)
OS BuildNumber Equals 14393

Coming Up

Next time, we’ll build a new Configuration Manager application for the Microsoft .NET Framework 4.6.2, which was also released with Windows 10 Anniversary Update.

Deploying Adobe Shockwave Player with System Center Configuration Manager

Welcome to part two of a five-part series on deploying runtimes and reader from Adobe with an app store-like experience using Microsoft System Center Configuration Manager. Today’s episode: Shockwave Player! As I prepared to write, I asked myself, “Does anyone use Shockwave anymore?” It turns out that the answer is pretty much a “no”, but I’m going to stick with my plan to cover Shockwave, Flash, AIR, and Acrobat Reader (in that order) for completeness. Also, Shockwave is the only one of the four that is actually packaged appropriately by the vendor for an acceptable user experience, so it makes sense to cover it first so we can focus on the plumbing of building the application package. Each of these programs receives frequent updates, and it can be quite a task to build new application packages every few weeks. As I have mentioned previously, there are vendors that will take care of this for you, and I encourage you to use one of them if you can afford it and if it makes sense in your organization. My approach here will be to show a do-it-yourself method for automating app package creation for these frequent updates using Windows PowerShell.


To follow along, you will need to have distribution rights from Adobe, PowerShell 5.0, and the Configuration Manager cmdlets. See my previous blog post for details. You may not technically need PowerShell 5.0, but that’s what I have. I’m not going to make any effort to ensure that what I’m doing works on previous versions, so to make sure everything below works for you, I suggest upgrading to version 5.0 or higher. You can check your version of PowerShell from a PowerShell prompt by displaying $PSVersionTable.PSVersion. Here’s the command and its output from my Windows 10 v1511 computer with PowerShell 5.0 installed:

Using PowerShell for Packaging: First Iteration

Let’s begin by outlining the plan in comments. We’ll start with a simple, single-use script and then refine it later.


There are several ways to download a file from the web with PowerShell. I’m going to choose the simplest one (which may not be the “best” one, depending on your criteria): a built-in PowerShell cmdlet called Invoke-WebRequest. Start by clicking the Shockwave link you received from Adobe. In the Shockwave Player Distribution Downloads table, right-click the Download MSI Installer link, and choose Copy shortcut or its equivalent to copy it to the clipboard. Paste the URL into the PowerShell script and assign it to a variable. This will be important later. Basically, we’re going to use Invoke-WebRequest to download the file to a temporary folder. Unfortunately, things are never as easy as they sound. The download link provided by Adobe does not include a filename, but Invoke-WebRequest needs one in order to save the file. It is important (to me, at least) to use the real filename of the file rather than something arbitrary. Also, the link provided by Adobe redirects elsewhere, which complicates matters. Here is the somewhat scary-looking code, and an explanation follows.

Obviously, replace the URI placeholder text with the appropriate download link from Adobe. Since that link does not include the filename, we generate one with a call into the .NET Framework’s System.IO.Path.GetRandomFilename() function. Next, we use Invoke-WebRequest to download the file to a temporary folder. The Invoke-WebRequest cmdlet puts its result on the pipeline as a WebResponseObject unless you pass the OutFile parameter, in which case it puts nothing on the pipeline. The PassThru switch overrides this behavior and puts the response object on the pipeline in addition to writing the output file. This object, which is captured by the response variable, contains the actual URI used to obtain the downloaded file after any redirects were followed. The System.IO.Path.GetFileName() function extracts just the filename from this URI. We delete any existing file with the same name in the temporary folder and then rename the downloaded file with the proper name. Finally, we remove the zone identifier from the downloaded file with Unblock-File in order to prevent security prompts when attempting to install the program later. For more information on this, see About URL Security Zones on TechNet. Scott Hanselman also has a great discussion of the zone identifier alternate data stream from 2007, but he doesn’t mention the PowerShell cmdlet we will use, so maybe it did not yet exist back then.

Extracting Version Information

The download link and the file we downloaded does not contain any version information in the name, but we will need the version in order to make the Configuration Manager application. I have not found any built-in PowerShell cmdlets to extract version information from a Windows Installer (MSI) file, but fortunately, we have the Internet to help us!

I found a number of scripts in a number of places, but I chose to use the one from Nickolaj Andersen at scconfigmgr.com because it was the simplest that suited my needs. Visit that link, follow the instructions there, and then come back here to continue. When you’re finished, you’ll have a Get-MSIFileInformation.ps1 file in the same folder as the script we are writing here.

Since we’re leveraging an outside script for most of the work here, our own version extraction code is quite short.

Unfortunately, the output of the Get-MSIFileInformation function is not of the type that we need, and it cannot be converted directly to a System.Version. To overcome this, we cast it to a string, remove the leading spaces with Trim(), and then cast the string to System.Version.

Saving the Installer to the Proper Location

Now that we’ve downloaded the installer and extracted the version number, it’s time to move it to its final location. This location should be wherever you normally save application installation files for use by Configuration Manager. We’ll supply the root folder, the manufacturer name, and the product name, and then the script will concatenate it all together to make a folder structure of “\\server\share\manufacturer\product ww.xx.yy.zz” for the installer.

Alert readers will have noticed my inconsistent capitalization of variable names. I did that on purpose because I am going to convert some of the variables to parameters later. Future parameters are in Pascal case; regular variables are in camel case.

Extracting the Program Icon

If you supply an icon file when creating a Configuration Manager application, Software Center will use that icon rather than the generic program icon. This looks more professional and makes Software Center seem more legitimate to the user as a real app store.

The cmdlet we will use later to create the ConfigMgr application accepts only image file formats; it does not accept EXEs, DLLs, or ICOs. How, then, does one extract the needed icons for use with this cmdlet? I would like to be able to extract the highest-quality icon from the EXE setup file, but unfortunately, there does not appear to be a built-in facility for doing so in .NET. I found some native code examples online, so I may revisit this in the future. In the meantime, we’ll make use of the System.Drawing.Icon class.

It takes a little bit of work to get the program icon out of a Windows Installer file. The methodology we will use is:

  1. Perform an Administrative Installation of the MSI in order to extract all of its files.
  2. Extract the desired icon from the main program file (EXE) and save it somewhere for use later.
  3. Delete the Administrative Installation files and folders.

This section of code leaves us with a PNG file of Shockwave’s main program icon saved in the temporary folder with the name stored in the $extractedIconFilename variable.

Creating the Configuration Manager Application

With all of the requisite pieces prepared, it is time to create the application object. We’ll use splatting to improve the readability of the code. The ConfigurationManager PowerShell module (one of the prerequisites) contains the needed cmdlets.

Application Object

All the parameters that we care about for New-CMApplication are included in the $appParams variable. The ConfigurationManager module’s cmdlets require use of a special PSDrive in order to function, so you should substitute your site name for “CM1” and your preferred location for the application object for “Applications\Free” in the $ConfigurationManagerApplicationLocation variable. Unfortunately, regardless of the current directory, the New-CMApplication cmdlet creates application objects in the Applications folder only, so we must use the Move-CMObject cmdlet to put it where we want it. Finally, we use Remote-Item to delete the extracted icon file.

All of this code creates an application object and puts it in the desired location, but so far, it doesn’t actually install any software. To do that, we must add a deployment type.

Deployment Type

We’ll use splatting again to simplify the code; all of the parameters that we care about for the deployment-type-creation cmdlet are included in $dtParams.

The installation command is a standard Windows Installer command line that specifies no user interface and blocks any requested computer restart requests. MsiExec.exe will, however, return a special value (1641 or 3010) if a restart is needed, and since we didn’t override the return values, the defaults in Configuration Manager will honor this and cause Software Center to notify the user. (In a task sequence, the Configuration Manager client will restart the computer, if needed, and then continue with the next task sequence item.)

We specify the application object created earlier as the InputObject so that the cmdlet knows which one should get this new deployment type. We specify the full path and filename of the MSI file to the ContentLocation field so that the cmdlet knows which MSI file to read, but content location in the resulting deployment type that we create only contains the path. Because we are supplying an MSI file to an MSI-specific cmdlet, the cmdlet figures out the uninstallation command and detection logic on its own, so we need not specify these items. The values for the LogonRequirementType, UserInteractionMode, and InstallationBehaviorType fields are standard for non-interactive installations that are intended for use from Software Center or in a task sequence.

Coming Up

That’s it for now. You can run this script at any time to get the latest Shockwave Player downloaded and imported into Configuration Manager.

Now, this script leaves room for improvement. Here are some to-do items for the future:

  • Refactor the code into several functions.
  • Parameterize to add flexibility.
  • Generalize the code to make it work for other, similarly-distributed applications.
  • Rewrite the icon-extraction code to get a higher-resolution icon, if available.

I’m going to tackle these items in future posts in this series. In addition, once this blog series is finished, I plan to post the final code on GitHub to facilitate easier usage than copying and pasting from numerous code snippets.

Next time, we’ll take a look at Adobe Flash Player.

Deploying Adobe Runtimes and Reader: Introduction

Last time, I presented my views on what the software deployment experience ought to be like for users and described some rules or principles for software installation programs to provide that experience. I want to flesh out those principles with some small, focused examples. This five-post series will present deployment of the free runtimes and readers from Adobe, using System Center Configuration Manager’s Software Center application to provide the app store experience. We’ll be working with AIR, Flash, Shockwave, and Acrobat Reader DC.

Obtain Distribution Rights from Adobe

Adobe packages its free players differently for consumers and businesses. This is unfortunate because all installers for desktop Windows applications should be packaged as Windows Installer (MSI) files, period. The good news is that the business versions of three out of four of these Adobe programs are packaged as Windows Installer files. The bad news is that they are not publicly available; you have to ask for them.

To get the needed files, you must obtain distribution rights from Adobe. You will also have to create an Adobe ID in order to complete the distribution agreement. The following pages describe the availability of distribution rights for their respective products.

Clicking the “Apply” button on any of these pages will prompt you to sign in with an Adobe ID. After signing in, the Adobe Runtimes / Reader Distribution License Agreement page will be displayed. You can select all four products from this page and apply for licenses for all of them at once.

It usually takes at least 24 hours for the distribution request to be processed. You will receive an approval e-mail with a link to the installer for each product. I will not be revealing the links I received in this blog series as that would be a violation of the agreement. You must obtain distribution rights directly from Adobe in order to get the download links and follow along with this blog series.

Obtain Configuration Manager PowerShell Cmdlets from Microsoft (Optional)

I’m planning to use PowerShell in my examples in this series. There is entirely too much clicking involved in building application packages in Configuration Manager. Using PowerShell will alleviate the wrist strain of clicking, and the scripts we write for building these Adobe packages will be reusable for Adobe’s frequent updates to its products.

I’ll be using PowerShell 5.0, so if you are on a version of Windows lower than 10 (where PowerShell 5.0 is built in), be sure to upgrade by installing Windows Management Framework 5.0.

You will also need the System Center Configuration Manager Cmdlet Library, which is available from the Microsoft Download Center. Be sure to install the latest version.

Coming Up

Next time, we’ll examine the behavior of Adobe Shockwave and its installer. This is the simplest installer of the four, so it is a good place to get started and to get our feet wet with the Configuration Manager PowerShell cmdlets. In later posts, we’ll cover the other three programs, going in order of increasing complexity.

Providing a Great Software Deployment Experience

What is the ideal software delivery experience? Apple figured it out initially with the iPhone and later with other products, and Microsoft followed suit beginning with Windows 8. The App Store and the Windows Store are curated, safe spaces from which to purchase and download applications, and these stores provide fantastic user experiences. (Other platforms have package management systems with varying features and capability, but I have no experience with those, and my focus is on Windows software deployment.)

With an app store, an application and all of its updates come from one place. Because all of the apps available there go through a validation process, users can feel confident that they are not downloading malware. The apps install without prompting the user for information, and they work immediately. If an app requires configuration, it prompts the user and can save the configuration to a cloud storage location so that the app is immediately usable upon whichever device the user runs it. Software just works, and users can quickly get to the business of using the software instead of installing and configuring it.

The Desktop Difference

Contrast this with the installation and usage experience for traditional desktop applications. I’m going to focus on software for the Windows operating system for the rest of this post. Here are some typical steps to installing and using software.

  1. Find the desired software somewhere on the Internet and buy it. If it is free, hope that you were not tricked into downloading malware instead of the software you wanted.
  2. Run the installer. This is probably an executable program that must be run with administrative credentials, so you are basically giving complete control of your computer over to the setup program.
  3. Answer configuration questions asked by the setup program. You may not be confident in your answers or may not have any idea how to answer some of them.
  4. Restart your computer and then spend 20 minutes re-opening all of your programs and browser tabs.
  5. Notice that the installer has put one or more icons not only on your Start menu, but also on the desktop and on the taskbar.
  6. Further notice that the notification area shows that the new program is already running, even though you didn’t specify this.
  7. Run the new program, and answer additional configuration questions asked by the program. Again, you may not know the answers to these questions.
  8. Take a tour of new features!
  9. Dismiss a “Did you know…” pop-up message or maybe a new feature advertisement pane.
  10. Actually use the program.
  11. Realize that you also need the program on another computer, and begin the whole process again.

This may seem extreme, but all of the above behaviors are commonplace. If you decide to uninstall a program, you may have to go through these steps.

  1. Uninstall the application.
  2. Specify options for removal. Should all components be removed? Should data be removed? You don’t really want to uninstall the program, do you?
  3. Complete a survey about why you uninstalled the application.
  4. Restart the computer and then spend 20 minutes re-opening all of your programs and browser tabs.
  5. Discover that some components of the application are still installed but that there is no way to uninstall them through standard procedures.

Here is a concrete example that I observed and recorded in early 2015. There is one particular program that nearly everyone in my organization wants that, when it installs, puts shortcuts on the Start menu, on the desktop, and on the taskbar. Then, even if you delete the desktop and taskbar icons, when another user runs the program, it recreates those icons in that user’s profile. It even uses (or at least did so in early 2015) an undocumented feature of Windows Setup to insert itself into the first-logon experience so that it can create these icons before the user has ever decided to use the program, causing a two-second delay in the first logon experience. Then, when a user actually wants to run the program, the first thing it does is try to take over being the default handler for its particular file type. When the program actually opens, it displays a tab with a tour of new features and tries to get the user to create an account with the manufacturer. This entire experience is bad enough for regular users, but it is truly horrible for lab or classroom environments in a school or university because every single user logon is probably that user’s first time logging onto a given machine. What is this malware, you ask? It’s Google Chrome.

It didn’t have to be this way. Microsoft has published application user experience guidelines for years and years, and it has also had a “Designed for Windows” logo program for software since the Windows XP days (2001) and perhaps even before that. Unfortunately, these guidelines and programs seem to have been largely ignored by software vendors and their customers. I have some ideas about why this happened and thus why software distribution is in such a sorry state today, but my purpose here is not to assign blame; rather, I want to discuss the problems and arrive at some principles to guide the creation of solutions. I think the Apple App Store and the Microsoft Windows Store are reactions to the resistance of independent software vendors to write good software; these app stores codify into “law” the kinds of behaviors that have always been prescribed by user experience and logo program guidelines and make them non-optional, since the operating vendor acts as the gatekeeper for what appears in the store.

The installation, usage, and uninstallation steps listed above are disastrous for large-scale rollouts of software in an organization. It is disturbing to consider the amount of money spent on wages to employees that are not actually doing any work because they are struggling with bad software. If something goes wrong, they will hopefully call the organization’s help desk for assistance; this may reduce downtime, but it requires that another employee be on the other end of the telephone line to help with the issue. If your organization’s IT and top management are even mildly interested in data security and keeping support costs low, most users will not have administrative access on their machines and will thus not even be able to install software themselves. This leaves the deployment to the IT staff using any number of deployment tools available on the market, but there is still a lot of work required to deploy software in a way that mitigates the behaviors described above. In organizations with hundreds or thousands of client computers, manual installation of software expensive and error prone, so we must rely upon software deployment tools. There are numerous deployment and package management systems available, but they cannot help fix the fundamental problems built into software vendors’ setup programs by design. That task falls to the IT professional.

Guidelines for Great User Experience

My goal is to make the desktop application installation and usage experience as close to the idealized app store experience as possible. To guide the work toward that goal, some reference documentation and some specific principles are helpful.

Microsoft provides some great documentation on the proper behavior of Windows applications throughout their entire life cycle—installation, use, and uninstallation. See the following resources at the Windows Dev Center for the most recent versions of the Windows application design and certification guidelines:

Everything written by Rob Mensching or anyone else on the WiX Toolset team is also fantastic source material for the way installers ought to work. With that knowledge, we must then set about the task of bending the software to our will, as the tagline of this blog suggests, by fixing or working around the terrible installers published by software vendors, so that we can provide the app store experience to users.

Here is my list of guiding principles with explanations.

  1. The software must be able to be installed silently—that is, without any user prompts. This provides that app store-like experience of one-click installation. It also makes it possible for IT administrators to deploy software without user involvement.
  2. The software must be able to be installed without forcing the computer to restart. A forced restart could cause data loss, and that’s obviously unacceptable.
  3. Eliminate all first-run experiences. This one is sometimes difficult. Many programs want to interrogate the user the first time they run, but this is incredibly frustrating for the user if the application is updated often or in public computing spaces where a user may never sign into the same computer twice (thus getting the first-run experience every time).
  4. Don’t ask the user questions he/she cannot answer. This is a special case of first-run experiences, but it bears mentioning separately. In my observation, there is often a clear mismatch between the level of understanding a software developer expects a user to have about a piece of software and the level of understanding that the user actually has. Many applications ask users questions that they just don’t know how to answer.
  5. As a consequence of the previous four principles, provide any required configuration information either in the application deployment process itself (preferred if possible) or through an outside mechanism like Group Policy or Group Policy Preferences.
  6. Don’t allow an application to overwrite user preferences.
  7. Don’t allow an application to put icons on the desktop or the taskbar. This is a special case of user preferences, since these locations are intended to be for the user to customize. The only appropriate place for an application to put a shortcut is on the Start menu.

Some applications will easily work within these principles. If an application is packaged as a Windows Installer package, you’re already in pretty good shape. Unfortunately, many are provided as setup executables, and these require a variety of techniques to tame. Future posts will focus on individual applications that are common to many organizations—specifically, free readers, players, and browsers—and how to package them in System Center Configuration Manager so that the user experience is as much like an app store as possible.

An Easier Way

There are commercial products available to take care of free apps. I know people that subscribe to one of these services, and they are very happy with it. There are several reasons why an organization may not be able to do this though. An organization that only needs one or two apps covered by one of these auto-updater programs might have trouble justifying the cost for so little benefit. There may be concerns about performance or the additional management burden of another agent program running on every computer in the organization. There may also be security concerns, legitimate or not, that result in blocking such a subscription.

In any case, free readers, players, and browsers are useful for exploring the ideas described above in the context of a specific deployment tool (Configuration Manager) and practicing the techniques needed to achieve the goal of an app store-like application experience. Then when an important, paid-for, poorly-behaved app comes along, the principles and methods needed to fix it will be well understood.

Deploying Microsoft Office 2016: Building the Task Sequence in System Center Configuration Manager for Reliable Deployment

It’s time to wrap up this series on Office 2016 deployment. We’ve built several prerequisite application packages, some Global Conditions, and the Office application package itself. Because Microsoft recommends not installing multiple versions of Office together and because Office Setup cannot remove all components of previous versions, we built a Configuration Manager package with all of the OffScrub scripts from Microsoft Product Support Services to allow reliable removal of previous versions.

The application package we built last time brought everything together except the Offscrub package. That application package is useful for an operating system deployment task sequence or to device collections where you know that no member device has a version of Office already installed. To have reliable installations of Office 2016 with no previous versions, we need to add one more component: a task sequence.

Building the Configuration Manager Task Sequence

Create a custom task sequence. Do not specify a boot image. Assuming that you are installing multiple Office programs, here is a suggested name and description:

Name Office Family 2016 (32-bit) [Remove existing]
Description Removes previous versions of Office programs and then installs Office, Project, and Visio 2016 and all of their prerequisites.

You will have to give some careful thought to the content of these fields; both of them have rather short length limitations that prevent more accurate descriptions than what is shown above.

Right-click the newly-created task sequence, and click Edit. Now I will describe each step you should add to the task sequence.

Step 1: Start Software Center after restart

Type Run Command Line
Name Start Software Center after restart
Description Software Center must be running in order for progress to be displayed. The intrinsic “start” command of cmd.exe must be used; otherwise, Software Center will start on sign-in, but the desktop will not be loaded until it is closed.
Command line "%SystemRoot%\System32\reg.exe" add "HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce" /v "!SoftwareCenterForOffice2016TS" /t REG_SZ /d "\"%SystemRoot%\System32\cmd.exe\" /C \"start \"Starting Software Center...\" \"%SystemRoot%\CCM\SCClient.exe\" softwarecenter:\"" /f /reg:64
Disable 64-bit file system redirection Checked

This step ensures that Software Center is restarted automatically the next time someone signs in. This is important to show status to the user in case the task sequence is being run. The exclamation point prefix on the RunOnce registry value defers deletion of the value until after the command has completed successfully. That means that the command will not be deleted if it fails, and it will therefore by tried again the next time the RunOnce key is evaluated.

Step 2: Restart the computer

Type Restart Computer
Name Restart Computer
Description The “/Force” switch is being passed to all of the OffScrub scripts. This kills running Office programs and will thus cause data loss of any unsaved files. Restart to prevent this from happening.
Specify what to run after restart The currently installed default operating system
Notify the user before restarting Checked
Notification message Microsoft Office 2016 will be installed, and old versions of Office will be removed. The computer must restart to continue. Please save your work and close all programs. This upgrade process requires multiple restarts. You may sign into the computer after it restarts in order to view progress, but do not attempt use any programs until this process is complete.

As the description says, the OffScrub scripts will all forcibly terminate any running Office application without prompting the user to save data. If a user runs this task sequence manually, this delayed restart step informs the user what is happening and gives him or her time to save data.

Step 3: Remove old versions of Office

Type Group
Name OffScrub
Description Remove old versions of Microsoft Office.

We’ll call all of the OffScrub scripts from inside this group.

Step 3a: Remove Office 2003

Type Install Package
Name Remove Office 2003
Description Runs OffScrub03 script from Microsoft Support.
Install a single software package Selected
Package Microsoft OffScrub
Program OffScrub03

Step 3b: Remove Office 2007

Add a step to remove Office 2007 just like the one for Office 2003, replacing property values as appropriate.

Steps 3c and 3d: Remove Office 2010

Add a step to remove Office 2010 just like the one for Office 2003, replacing property values as appropriate. Then, make a copy of it so that there are two identical steps that remove Office 2010. Make the following changes:

  • Change the description of the first one to:
    Runs OffScrub10 script from Microsoft Support and continues on errors. OffScrub10 uses non-zero exit codes for informational reporting, which are interpreted by ConfigMgr to be errors.
  • Set the first one to Continue on error (on the Options tab).
  • Change the name of the second one to:
    Remove Office 2010 (retry).
  • Change the description of the second one to:
    Runs OffScrub10 script from Microsoft Support again and fails on errors. OffScrub10 uses non-zero exit codes for informational reporting, which are interpreted by ConfigMgr to be errors.
  • Add a condition to the second one (on the Options tab):
    Task Sequence Variable _SMSTSLastActionSucceeded equals “false”

Microsoft was consistent in the return values for all of the OffScrub scripts except for the one for Office 2010. In this one, some non-error conditions are reported back via the script’s exit code, and unfortunately there is no way to specify success values for ConfigMgr package programs. The approach I chose was to run the script once ignoring errors, and then run it again, if needed, failing on errors (thus causing the task sequence to stop).

If the first run of the script is successful and returns 0 (zero), the task sequence will record “true” in the _SMSTSLastActionSucceeded variable, and the second run of the script will be skipped due to the condition.

If the first run of the script is successful and returns a non-zero informational value, the task sequence will record “false” in the _SMSTSLastActionSucceeded variable, and the second run of the script will be executed, but it will have nothing to do and so will finish quickly, returning 0 (zero) because it has no special information to report.

If the first run of the script fails and returns a non-zero failure value, the task sequence will record “false” in the _SMSTSLastActionSucceeded variable, and the second run of the script will be executed. Assuming the script runs into the same problem that it did during the previous try, it will fail again, but this time the task sequence engine will see the failure and stop the task sequence.

Step 3e: Remove Office 2013

Add a step to remove Office 2013 just like the one for Office 2003, replacing property values as appropriate.

Step 3f: Remove Office 2016

Add a step to remove Office 2016 just like the one for Office 2003, replacing property values as appropriate.

Step 3g: Remove Office Click-to-run

Add a step to remove Office Click-to-run just like the one for Office 2003, replacing property values as appropriate.


Back outside of the OffScrub group, we’re ready to start installing software. The instructions below install all of the Office prerequisites as separate task sequence steps. This provides better feedback to the user as to what is happening and should make it easier to follow along in the logs if something goes awry.

New Install Application steps have a Retry this step if computer unexpectedly restarts checkbox checked and the number of times to retry set to 2 on the options tab. Leave these default settings for all Install Application steps added below.

Step 4: Install .NET 3.5 SP1

Type Install Application
Name Install .NET 3.5 SP1
Description Leave blank.
Install the following applications Add the .NET Framework 3.5 SP1 application package that we created earlier as the only item in the list.

Step 5: Start Software Center after restart

Copy the Start Software Center after restart step from the top of the task sequence and paste it here.

In my testing, installing the .NET Framework 4.x required a restart for completion, so we’ll set up Software Center to start again after that installation and restart is complete. At the very end of the task sequence, we’ll delete this registry value if it is still present. This would be the case if the computer already had .NET 4.5.2 or higher installed prior to running this task sequence.

Step 6: Install .NET 4.5.2 or higher

Type Install Application
Name Install .NET 4.5.2 or higher
Description Leave blank.
Install the following applications Add the .NET Framework 4.5.2 or higher application package that we created earlier as the only item in the list.

Step 7: Install Report Viewer 2008

Type Install Application
Name Install Report Viewer 2008
Description Microsoft Report Viewer 2008 is required for Database Compare 2016, which is a companion program to Access 2016.
Install the following applications Add the Microsoft Report Viewer Redistributable 2008 (KB971119) application package that we created earlier as the only item in the list.

Step 8: Install Office Professional Plus 2016 (32-bit)

Type Install Application
Name Install .NET 3.5 SP1
Description Leave blank.
Install the following applications Add the Microsoft Office Professional Plus 2016 (32-bit) application package that we created earlier as the only item in the list.

Steps 9 and 10: Install Visio and Project

Add Install Application steps for the Visio and Project application packages that we created earlier. These will be much like the Office installation step above.

Step 11: Install Software Updates

Type Install Software Updates
Name Install Software Updates
Description Leave blank.
Install software updates assigned to the destination computer All Software Updates

Step 12: Remove RunOnce value to start Software Center

Properties tab
Type Run Command Line
Name Remove RunOnce value to start Software Center
Description If the OS was fully patched (including having .NET 4.5.2 or higher installed) prior to running this task sequence, no restarts may have been triggered since the last “Start Software Center after restart” step, so remove the registry value if it is present.
Command line "%SystemRoot%\System32\reg.exe" delete "HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce" /v "!SoftwareCenterForOffice2016TS" /f /reg:64
Disable 64-bit file system redirection Checked
Options tab
Success codes 0 1

That’s the number zero, followed by a space, followed by the number one.

Continue on error Checked

The description field contents pretty much explains what this is doing. Note the changes to the Options tab, though. If reg.exe deletes the value successfully, it returns 0 (zero). If the value is not there, though, it returns 1. Since we just want to run the command and consider it successful no matter what, we need to set 0 and 1 as valid success codes as shown above. As insurance that some other unknown error condition won’t cause the task sequence to register as a failure, we also check the Continue on error box.


That’s it! Running this task sequence will ensure that target machines have exactly one version of Microsoft Office—Office 2016—and that all of its prerequisites are present. You will want to think carefully about how you deploy it. If your users are conditioned to sign out at the end of each work day, you may be able to deploy the task sequence as required for a specific time overnight without many problems. If users typically leave their computers turned on and signed in, with unsaved data open in various applications, you may want to just deploy the task sequence as “Available”, and then notify users via e-mail that they can run the task sequence themselves from Software Center. Running it manually will give users the warning that the computer will be restarted and give them time to save their data.

Be advised that in my testing, this task sequence took a minimum of 30 minutes to run and typically took quite a bit longer; just installing the updates takes a while. If users will run the task sequence themselves, I suggest advising them to begin the task sequence before going to lunch or before leaving for the day. If you know that your environment doesn’t have certain versions of Office, you could disable the corresponding OffScrub step(s) in order to save time. For example, I don’t think there are any Office 2003 installations remaining in my organization, so I disabled that step. Further, we no longer have a site license for Project, so I removed it. With those changes, here is what my task sequence looks like this:

Picture of Task Sequence Editor window


Deploying Microsoft Office 2016: Building the Application Package in System Center Configuration Manager

It’s been a long process, but it’s finally time to build the Application objects in System Center Configuration Manager for Microsoft Office and its sibling programs. There is just one bit of housekeeping to take care of first. One of my rules for a Configuration Manager Application is that it must have an uninstallation command. This provides Software Center with the ability to remove it, thus giving users an “app store” experience. That takes a little bit of work, and so we’ll do that first. Then we’ll walk through the Application-building process. Next time, we’ll use our new Applications along with our Offscrub package to build a task sequence for deployment.

Silent Uninstallation

As we did in the Customizing Setup post, we will consult the Office 2013 documentation to help us. The Setup command-line options reference for Office 2013 on TechNet has a helpful section describing uninstallation. Basically we need to use a custom config.xml file to instruct the setup program to perform a quiet uninstallation. This documentation doesn’t mention it, but because Configuration Manager Applications must not initiate a reboot, I’m going to add the SETUP_REBOOT property with a value of “Never” in order to be certain that the uninstallation process will not restart the computer unexpectedly. (You may recall that we added this property to the customization file for installation, but we don’t have a customization file for uninstallation.) To do that, we’ll use the Setting element of config.xml.

Open your favorite text editor, and save the following text as UTF-8. I named my file “Config-ProPlus2016-Silent-Uninstall-2016-02-22.xml” in the root of my deployment folder: \\fileserver\software$\Microsoft\Office Professional Plus 2016 (32-bit).

You can quickly create the needed files for other products in the Office family by changing the Product attribute of the Configuration element. Open the config.xml file located inside each product’s folder to obtain the appropriate value for that product. For example, for Visio Professional, look at the vispro.ww\config.xml file, and find that the Product attribute must be “VisPro”.

Warning: Don’t change the existing config.xml files in the installation source. Office Setup uses these files during installation, so our uninstallation settings must be saved elsewhere.

Building the Configuration Manager Application

Building the Configuration Manager Application for Office is a two-pass process. First, we’ll point ConfigMgr to the product MSI so that as many properties as possible populate automatically. Then we’ll go back and edit the Application to add our uninstallation command, prerequisite applications, and system requirements.

  1. In Configuration Manager Console, in the Software Library workspace, navigate to Overview > Application Management > Applications.
  2. In the ribbon, click Create Application. The Application Wizard will appear.
  3. On the General – Specify settings for this application page, select Automatically detect information about this application from installation files, and choose Windows Installer (*.msi file) as the Type.
  4. In the Location box, type the network path to the specific product’s MSI file under your installation source. For example, the MSI file for 32-bit Office Professional Plus is located in the proplus.ww folder. In my installation source, it is
  5. Click Next, and then click Next again to begin customization.
  6. Fill out the Specify information about this application page. This is where we supply Office Setup with our Office Customization Tool settings as well as our uninstallation settings. Although Office has a Windows Installer-based setup process, using setup.exe is required. Run setup /? to see all of the options. Keeping in mind that our example is 32-bit Office Professional Plus 2016, here are the settings.
    Name Microsoft Office Professional Plus 2016 (32-bit)
    Publisher Microsoft
    Software version 2016 (32-bit)
    Installation program setup.exe /adminfile "OCT-ProPlus2016-x86-Silent-Install-2016-02-22.MSP" /config "proplus.ww\config.xml"
    Run installation program as 32-bit process on 64-bit clients. Checked
    Install behavior Install for system

    Because we combined multiple products into one installation source, Office Setup does not automatically know which product we want to install. The /config switch and its argument provide this information to Setup so that the user is not prompted.

  7. Click Next, and verify that the settings are correct.
  8. Click Close to exit the wizard.

Double-click the newly-created Application object to open it. Now we’ll change additional settings that weren’t available in the wizard.

  1. On the General tab, check the Allow this application to be installed from the Install Application task sequence action without being deployed.
  2. On the Application Catalog tab, next to the Icon label, click Browse… Navigate to the Office installation source folder, and choose setup.exe. Select its only icon as the icon for this Application. Although this setting is on the Application Catalog tab, the icon will also appear in Software Center. This adds a level of professionalism to the Application package and makes Software Center seem more like a well-put-together app store.
  3. On the Deployment Types tab, select the deployment type and click Edit.
  4. On the Content tab, in the Content location box, remove the specific product folder from the path. In this case, that means deleting proplus.ww so that the path is \\fileserver\software$\Microsoft\Office Professional Plus 2016 (32-bit)\. (Configuration Manager used the longer path because we initially pointed it to the MSI file, but we really need the whole folder structure.)
  5. On the Programs tab, type the following into the Uninstall program text box:
  6. On the Requirements tab, add the system requirements we obtained in the Overview and Prerequisites.
    Requirement Type Operator Values
    CPU speed Greater than or equal to 1000 MHz
    Total physical memory Greater than or equal to 2000 MB
    Free Disk Space of system drive Greater than or equal to 3000 MB
    Operating system One of Windows 7 SP1 (64-bit), Windows 7 SP1 (32-bit), Windows Server 2008 R2 SP1 (64-bit), All Windows 8 (64-bit), All Windows 8 (32-bit), Windows Server 2012, All Windows 8.1 (64-bit), All Windows 8.1 (32-bit), Windows Server 2012 R2, Windows 10
    OS Installation Type Not equal to Server Core
    Internet Explorer Version Begins with 11.
    (Note that the period is included in the value: “11.”)
  7. On the Dependencies tab, add a dependency group with the name .NET Framework 3.5, and add the 32-bit deployment types from the Microsoft .NET Framework 3.5 Application package that we created earlier. That should be nine deployment types: two each (32-bit and 64-bit) for Windows 10 v1511, 10 Release, 8.1/2012 R2, and 8/Server 2012; and one for all bitnesses of Windows 7/Server 2008 R2.
  8. Add a dependency group with the name .NET Framework 4.x, and add both deployment types from the Microsoft .NET Framework 4.5.2 or higher application package that we created earlier.
  9. Add a dependency group with the name Report Viewer, and add the single deployment type for the Microsoft Report Viewer Redistributable 2008 Application that we created earlier.
  10. Click OK until you have dismissed the Application’s Properties window.

Congratulations! Now you have an Office 2016 application package suitable for deploying during operating system deployment with a task sequence. Unfortunately, all the work we have done up to this point is still not quite enough to have a reliable deployment of Office on existing computers with a previous version of Office already installed. Do not–I repeat, DO NOT–deploy this application package to your whole company. If you do, you will have a bad time. Why? See my previous post on removing old versions for the answer. For now, you can go ahead and use this application in new deployments, but you’ll have to tune in next time to get the solution for existing installations.

Other Programs in the Office Family

You can follow the same general procedure to package the other Microsoft Office-family products we included in our source folder structure. Make a separate Configuration Manager Application for Visio and Project Standard. Include all of the same system requirements and dependencies except for Report Viewer which can be omitted.

Coming Up

The next post is the last one in the series on deploying Microsoft Office 2016. In it, I will explain how to use everything we’ve built to provide a reliable delivery of Office 2016 in your organization regardless of whether an existing Office installation is present.

<update date=”2017-07-11″>Corrected HTML encoding errors in code samples.</update>

Deploying Microsoft Report Viewer Redistributable 2008 with System Center Configuration Manager

Microsoft Office 2016 has a prerequisite that is not mentioned in the system requirements. If you want to use the Database Compare 2016 program to compare Microsoft Access databases, you must have the Report Viewer Redistributable 2008 installed, or you will get a most unhelpful error message.

On you application staging file share (wherever you put application source files for Configuration Manager to find), create a folder for Microsoft Report Viewer Redistributable 2008 with Service Pack 1. Mine will be \\fileserver\software$\Microsoft\Report Viewer 2008 SP1 GDIPLUS.DLL Security Update (KB971119).

Download the executable installer from the Microsoft Download Center, and then extract its content into the folder you just created: Report Viewer Redistributable 2008 Service Pack 1 GDIPLUS.DLL Security Update. Using the folder path I stated above, run the following command at an elevated command prompt: ReportViewer.exe /x:"\\fileserver\software$\Microsoft\Report Viewer 2008 SP1 GDIPLUS.DLL Security Update (KB971119)".

Property Value
Application Properties
Name Microsoft Report Viewer Redistributable 2008 (KB971119)
Publisher Microsoft
Version 2008 (KB971119)
Deployment Type Properties
Name Microsoft Report Viewer Redistributable 2008 (KB971119) – Windows Installer (*.msi file)
Technology Windows Installer (*.msi file)
Content location \\fileserver\software$\Microsoft\Report Viewer 2008 SP1 GDIPLUS.DLL Security Update (KB971119)
Installation program install.exe /q /l “%TEMP%\reportviewer2008KB971119installationlog.txt”
Uninstall program msiexec /x {CED243AB-C7BA-3D42-9609-14EF5A6FC601} /q
Detection method MSI Product Code: {CED243AB-C7BA-3D42-9609-14EF5A6FC601}
Installation behavior Installation behavior: Install for system
Logon requirement: Whether or not a user is logged on
Installation program visibility: Hidden
Configuration Manager behavior: Determine behavior based on return codes
Requirements None
Dependencies .NET 2.0 SP2 (See below for details.)

Note that although the extracted files are still installed with an executable, deep down, the installer is actually an MSI. I was able to find the MSI’s product code and create an MSI deployment type using that information. For now, I’ll leave it as an exercise for the reader to figure out how to do this, but I may revisit the topic in the future. In any case, I provided the product code above, so you don’t need to go searching for it.

Report Viewer requires .NET 2.0. Since .NET 2.0 is basically a sub-component of .NET 3.5, and since .NET 3.5 SP1 is the minimum supported .NET version on all of our supported platforms except for Windows 7, the most economical way to proceed is to just reuse the .NET Framework 3.5 application package that we already built as a dependency (prerequisite) for this application package. On the Dependencies tab, click Add…, and give the new dependency the name .NET 2.0 SP2. Then (still in the Add Dependency dialog window) click Add… and select all nine of the deployment types from the .NET Framework 3.5 application package.

Coming Up

Now we have all of the prerequisite application packages built and our custom installation settings defined. Next time, we’ll put everything together to build a set of Configuration Manager Applications for 32-bit and 64-bit versions of Office, Project, and Visio!

Deploying Any Supported Version of Microsoft .NET Framework 4.x as a Prerequisite Application

Several weeks ago, I described how to ensure that some version of the .NET Framework 4.x would be installed on any version of Windows from 7 through 10. This was accomplished by installing the latest version on Windows 7 (.NET 4.6.1) and just ensuring that the built-in .NET version was turned on in all other versions of Windows. I used this method for performance and stability. If a program can use any 4.x version of .NET, then using whatever is already there is faster than installing a newer version; avoiding unnecessary upgrades makes it less likely that the process will break some other program. (Admittedly, the chance of breakage is small with .NET 4.x, but I think this is a good general principle.) I published that blog post on Monday, February 1; unfortunately, I was unaware that Microsoft had announced, months previous, that support for all 4.x versions of .NET prior to version 4.5.2 would end on January 12, 2016.

When I discovered that announcement, I rethought my strategy for providing this prerequisite package. I decided that instead of using the application package I described previously, I would rather use an application package that ensures that some supported version of the .NET Framework 4.x would be installed. That application package is the subject of this post.

Update from 2016-03-20

Subsequent to this post’s initial publication, I completed all of the application packages and task sequences for my Office 2016 series, and I discovered in testing that the .NET 4.6.1 executable installer would not function correctly on 32-bit versions of Windows when run in a task sequence! On all supported versions of 32-bit Windows, running NDP461-KB3102436-x86-x64-AllOS-ENU.exe /q /norestart results in an exit code of 16389 when run in a task sequence, and the framework is not installed. This registers as a failure to the Configuration Manager client and causes the task sequence to fail. This failure occurs regardless of the state of the Run installation and uninstall program as 32-bit process on 64-bit clients checkbox, which shouldn’t have any effect on 32-bit OSes, but which I tried anyway in troubleshooting. The same command line run on 64-bit Windows in a task sequence also failed with the same exit code if that checkbox was unchecked, but checking the box made it work.

At publication on 2016-02-29, this post described a single deployment type for all versions of Windows previous to Windows 10, and this worked when installed from Software Center on all supported operating systems. Due to the problems described above when installation was run as a task sequence step, I subsequently had to add an additional deployment type for 32-bit Windows. I also originally passed the parameter /ChainingPackage ADMINDEPLOYMENT, but I removed it in the course of troubleshooting and never put it back.

Acquiring the Installation Files

If you’ve been following along with my Deploying Office 2016 series, you’ll find that we already have everything we need. We’ll test for the minimum supported .NET version of 4.5.2, which was not included as an OS component in any version of Windows. For computers without this version or higher, we’ll reuse our .NET 4.6.1 application package from a few weeks ago to bring them up to the latest version. Windows 10 v1507 includes .NET 4.6, and Windows 10 v1511 includes .NET 4.6.1. The NetFx4 feature cannot be disabled in those OSes, so we’ll have a special deployment type for Windows 10 that basically just detects those OS versions.

On your application staging file share (wherever you put application source files for Configuration Manager to find), create a folder for .NET 4.x. Mine will be \\fileserver\software$\Microsoft\.NET Framework 4.x. We’ll use this folder for Windows 10, so we don’t actually need any source files. As we did with .NET 3.5 on Windows 7 and .NET 4.6.1 on Windows 10 v1511, we will just provide Configuration Manager with a single file in that folder. I used Notepad to create a text file named readme.txt in the folder containing the following text:

That explains the presence of the otherwise empty folder to anyone reviewing this folder structure.

Building the Configuration Manager Application

Windows 7, 8, 8.1 (64-bit), Windows Server 2008 R2 SP1, 2012, 2012 R2 (64-bit, full installations)

In the Configuration Manager Console, create a new Application. We are going to reuse the source folder and settings from our .NET 4.6.1 application package for our first deployment type. Here are the values I provided in mine:

Property Value
Application Properties
Name Microsoft .NET Framework 4.5.2 or higher
Publisher Microsoft
Version 4.x
Deployment Type Properties
Name Microsoft .NET Framework 4.6.1 – Windows 7, 8, 8.1, Server 2008 R2 SP1, 2012, 2012 R2 (64-bit, full installations)
Technology Script Installer
Administrator comments Detects whether a supported version of .NET 4.x is installed (4.5.2 and higher). If any targeted OS does not have .NET 4.x or has an unsupported version of .NET 4.x, install .NET 4.6.1. This deployment type cannot be uninstalled because it registers as installed for multiple minor versions of the .NET Framework 4.x; to remove .NET 4.x, uninstall the exact version in Software Center (if present) or in Programs and Features.
Content location \\fileserver\software$\Microsoft\.NET Framework 4.6.1\PreWin10v1511\
Installation program "NDP461-KB3102436-x86-x64-AllOS-ENU.exe" /q /norestart /ChainingPackage ADMINDEPLOYMENT
Uninstall program None (leave blank)
Run installation and uninstall program as 32-bit process on 64-bit clients Checked
Detection method See below.
Installation behavior Installation behavior: Install for system
Logon requirement: Whether or not a user is logged on
Installation program visibility: Hidden
Configuration Manager behavior: Determine behavior based on return codes
Requirements Operating system
One of Windows 7 SP1 (64-bit), Windows 2008 R2 SP1 (64-bit), All Windows 8 (64-bit), All Windows Server 2012, All Windows 8.1 (64-bit), Windows Server 2012 R2
CPU speed: Greater than or equal to 1000 MHz
Total physical memory: Greater than or equal to 512 MB
Free Disk Space of system drive: Greater than or equal to 2560 MB
OS Installation Type: Not equal to Server Core
Return Codes 0 Success (no reboot) Installation completed successfully.
1602 Failure (no reboot) The user canceled installation.
1603 Failure (no reboot) A fatal error occurred during installation.
1641 Hard reboot A restart is required to complete the installation. This message indicates success.
3010 Soft reboot A restart is required to complete the installation. This message indicates success.
5100 Failure (no reboot) The user’s computer does not meet system requirements.

The detection logic for this deployment type is complex.

Connector ( Clause )
LocalMachine\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\Release Greater than or equal to 379893.
And ( LocalMachine\SOFTWARE\Microsoft\Windows NT\CurrentVersion\CurrentVersion Equals 6.1.
Or  LocalMachine\SOFTWARE\Microsoft\Windows NT\CurrentVersion\CurrentVersion Equals 6.2.
Or ( LocalMachine\SOFTWARE\Microsoft\Windows NT\CurrentVersion\CurrentVersion Equals 6.3.
And LocalMachine\SOFTWARE\Microsoft\Windows NT\CurrentVersion\CurrentBuild Equals 9600. ))
 And  LocalMachine\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\PROCESSOR_ARCHITECTURE Equals Amd64

This deployment type’s properties are basically the same as those in our .NET 4.6.1 Application except for the detection logic. Remember that the .NET 4.6.1 setup program doesn’t work for Server Core installations, so those are excluded here under Requirements. This application package has a user-friendly name because it is displayed during task sequence deployment, but because it does not represent an exact version of an application, and because it cannot be uninstalled, it doesn’t make sense to deploy this application directly to devices or users. Don’t deploy this Application on its own; just set it as a prerequisite for other Applications that need it, or include it as a step in a task sequence.

Now let’s look at the complicated detection method. What’s happening here? First, we don’t actually test for version 4.6.1; instead we test that a minimum of .NET 4.5.2 is installed; that’s build 379893 stored in the Release registry value. (See How to: Determine Which .NET Framework Versions Are Installed on MSDN for build numbers.) Then we verify that the OS version is less than that of Windows 10, since this deployment type doesn’t apply to Windows 10. The CurrentVersion registry value works for Windows 7 (6.1) and 8 (6.2), but it does not work for Windows 8.1 (6.3). In its latest attempt to mitigate version-check bugs in other vendors’ applications, Microsoft no longer updates this registry value. Both versions of Windows 10 released so far, as well as Windows 8.1, have a CurrentVersion registry value of 6.3. To verify that the OS is really Windows 8.1, we must also check that the build number is 9600.

To build this detection logic, add each clause in the order shown. Then adjust the Connectors as needed by clicking on the word to give it focus; it changes to a drop-down menu from which you can choose which verb you want. Group the Windows 8.1 detection by selecting the “6.3” and “9600” lines and then clicking the Group button. Finally, group all of the operating system detection logic by selecting everything except the top and bottom lines and clicking the Group button.

Windows 7, 8, 8.1 (32-bit)

Due to the inability of the .NET 4.6.1 executable installer to function when run by a ConfigMgr task sequence, it is necessary to extract the files for 32-bit versions. This works, but it has the unfortunately effect of creating a huge installation source due to Microsoft’s needless bloating of the installation packages.

On your application staging file share (wherever you put application source files for Configuration Manager to find), create a new folder for the extracted 32-bit .NET 4.6.1 files. Mine will be \\fileserver\software$\Microsoft\.NET Framework 4.6.1\PreWin10v1511x86. Use 7-Zip to extract the contents of NDP461-KB3102436-x86-x64-AllOS-ENU.exe into the folder you just created. Then delete the huge, hundreds-of-megabyte files than end in “x64”. Since this folder is only for 32-bit content, we can save quite a bit of space by getting rid of what we don’t need.

Then create a new deployment type for 32-bit client operating systems.

Property Value
Deployment Type Properties
Name Microsoft .NET Framework 4.6.1 – Windows 7, 8, 8.1 (32-bit)
Technology Script Installer
Administrator comments Detects whether a supported version of .NET 4.x is installed (4.5.2 and higher). If any targeted OS does not have .NET 4.x or has an unsupported version of .NET 4.x, install .NET 4.6.1. This deployment type cannot be uninstalled because it registers as installed for multiple minor versions of the .NET Framework 4.x; to remove .NET 4.x, uninstall the exact version in Software Center (if present) or in Programs and Features.
Content location \\fileserver\software$\Microsoft\.NET Framework 4.6.1\PreWin10v1511x86\
Installation program "Setup.exe" /x86 /x64 /redist /q /norestart
Uninstall program None (leave blank)
Run installation and uninstall program as 32-bit process on 64-bit clients Unchecked
Detection method Same as 64-bit deployment type except for the last line, which is:
LocalMachine\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\PROCESSOR_ARCHITECTURE Equals x86
Installation behavior Installation behavior: Install for system
Logon requirement: Whether or not a user is logged on
Installation program visibility: Hidden
Configuration Manager behavior: Determine behavior based on return codes
Requirements Operating system
One of Windows 7 SP1 (32-bit), All Windows 8 (32-bit), All Windows 8.1 (32-bit)
CPU speed: Greater than or equal to 1000 MHz
Total physical memory: Greater than or equal to 512 MB
Free Disk Space of system drive: Greater than or equal to 2560 MB
OS Installation Type: Not equal to Server Core
Return Codes Same as 64-bit deployment type.

When NDP461-KB3102436-x86-x64-AllOS-ENU.exe is passed the parameters /q /norestart,  it extracts the contents and runs Setup.exe /x86 /x64 /redist /q /norestart. Since we extracted the content already to get around the bug in the self-extracting executable that prevents it from running in a task sequence, we use that command line as the installation command.

The detection method rules are the same as with the 64-bit deployment type except that the last line is adjusted to detect the x86 platform. The operating system requirements are similarly adjusted to only allow installation on 32-bit operating systems.

Windows 10 (64-bit and 32-bit)

All releases of Windows 10 can be handled by a single deployment type. The NetFx4 feature cannot be disabled in Windows 10, so this deployment type has nothing to do except detect the operating system version. We’ll verify the .NET 4.x version as well for good measure, but that test should never fail in a healthy system.

Property Value
Deployment Type Properties
Name NetFx4 Unremovable Feature – Windows 10 (64-bit and 32-bit)
Technology Script Installer
Administrator comments Windows 10 RTM includes .NET 4.6, and Windows 10 November Update includes .NET 4.6.1. The NetFx4 feature cannot be turned off in Windows 10, so this deployment type performs no installation.
Content location \\fileserver\software$\Microsoft\.NET Framework 4.x\
Installation program "%SystemRoot%\System32\cmd.exe" /C type readme.txt
Uninstall program None (leave blank)
Detection method Rule 1:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full
Value: Release
Data type: Integer
Greater than or equal to 393295
Rule 2:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
Value: CurrentMajorVersionNumber
Data type: Integer
Greater than or equal to 10
Installation behavior Same settings as other deployment type. See table above.
Requirements Operating system
One of Windows 10
Return codes Leave defaults

For the installation program, we just display the contents of a text file. This should never actually run, and even if it did, no one would see it because the deployment type is hidden. The detection logic uses a new registry value in Windows 10, CurrentMajorVersionNumber, to ensure that the OS is Windows 10, and it checks that the .NET 4.x version is 4.6 at minimum.

Coming Up

Next time, we’ll take care of one more prerequisite application before we put everything together to build a set of Configuration Manager Applications for 32-bit and 64-bit versions of Office, Project, and Visio.

<update date=”2016-03-20″>Added new deployment type for 32-bit Windows versions and explanatory text describing the reason for the change.</update>

<update date=”2016-04-17″>Revised the “Coming Up” section for accuracy.</update>

Deploying Microsoft Office 2016: Customizing Setup

It’s finally time to work on the actual Office installation. We’ve spent several weeks preparing prerequisites, but now it’s time to get down to business. We’ll assemble all of the needed components, and then next time, we’ll will build our application packages and task sequences in Configuration Manager.

Acquiring the Installation Files

As I stated in the overview, my organization has licensed Microsoft Office Professional Plus 2016. Note that this is not the same thing as “Office 365 ProPlus“, which is a subscription plan. The former is packaged the same way as the previous three versions—as a collection of MSI packages coordinated by an executable installer. The latter is delivered via a streaming model. I will be addressing the former.

My organization has also licensed Microsoft Visio Professional 2016 and Microsoft Project Standard 2016. Since these two products are considered part of the Office family of applications even though they are packaged and licensed separately, there is some overlap in their installation files and those of Office Professional Plus. We’ll take advantage of this to build a single installation source for Configuration Manager, thus decreasing the amount of disk space and network bandwidth required to install all three products. (Machines that don’t have all three installed will still get the entire payload in their Configuration Manager caches, but in my environment, it makes sense to bundle them.)

  1. Download the ISO files from the Microsoft Volume Licensing Service Center. I downloaded both 32-bit and 64-bit media, so my files were:
    • SW_DVD5_Office_Professional_Plus_2016_64Bit_English_MLF_X20-42432.ISO
    • SW_DVD5_Office_Professional_Plus_2016_W32_English_MLF_X20-41353.ISO
    • SW_DVD5_Project_2016_64Bit_English_MLF_X20-42644.ISO
    • SW_DVD5_Project_2016_W32_English_MLF_X20-41488.ISO
    • SW_DVD5_Visio_Pro_2016_64Bit_English_MLF_X20-42764.ISO
    • SW_DVD5_Visio_Pro_2016_W32_English_MLF_X20-41585.ISO
  2. On your application staging file share (wherever you put application source files for Configuration Manager to find), create a folder for the Office, Project, and Visio installation sources. Mine will be \\fileserver\software$\Microsoft\Office Professional Plus 2016 (32-bit).
  3. Mount 32-bit Office ISO in Windows File Explorer by double-clicking it.
  4. Run the following commands to copy the ISO content to your installation source folder, checking the log file afterward to ensure that all files were copied successfully:
    rem Change the path to match your installation source.
    set OFFICEFOLDER=\\fileserver\software$\Microsoft\Office Professional Plus 2016 (32-bit)
    rem Change the path to the root of the drive where the ISO is mounted
  5. Eject the Office ISO image, and mount the 32-bit Project ISO.
  6. Run the following command to copy the ISO content to your installation source folder. The /XC, /XN, and /XO switches prevent Robocopy from overwriting any existing files in the destination.
  7. Eject the Project ISO image, and mount the 32-bit Visio ISO.
  8. Run the following commands to copy the ISO content to your installation source folder.
  9. Repeat steps 2 through 8 for the 64-bit ISOs, copying their contents into a separate installation source folder. Mine will be \\fileserver\software$\Microsoft\Office Professional Plus 2016 (64-bit).
  10. Download the Office 2016 Administrative Template files (ADMX/ADML) and Office Customization Tool from the Microsoft Download Center. These were released after Office, Project, and Visio, and so contain updated versions of the included files.
  11. Run the two downloaded executables to extract the files.
  12. Run the following commands to copy the ISO content to your installation source folder. Note that for product installation, we are only interested in the admin folder.
    rem Change this to the location where you extracted the 32-bit Office Customization Tool files
    set OCTSOURCE=E:\Downloads\Microsoft Office 2016 Administrative Template files (ADMX_ADML) and Office Customization Tool 32-bit (2015-10-21)\admin
    robocopy "%OCTSOURCE%" "%OFFICEFOLDER%\admin" /E /XJ /COPY:DAT /DCOPY:DAT /XC /XO /LOG:"%OFFICEFOLDER%\AdminCopyLog.txt"
  13. Repeat step 12 for the 64-bit Office Customization Tool and the 64-bit installation source admin folder.

Customize Setup with the Office Customization Tool

We’re going to use the Office Customization Tool to make our Office installations silent and to tweak a few settings. It looks like Microsoft has not revised its documentation for OCT in Office 2016, so please review a little bit of the Office Customization Tool (OCT) reference for Office 2013 if you are unfamiliar with the tool. I will take a step-by-step approach, though, so if you are new to OCT, you should still be able to follow along.

As I mentioned in the overview, my approach to application packaging is to make the installation silent so that it can be deployed with or without user interaction and to minimize or preferably eliminate first-run prompts wherever possible. For example, people that have been using Microsoft Office for years do not want to watch a video about Office or sign in with a Microsoft Account when their version of Office is upgraded; they just want it to work and not get in their way. On the other hand, as a system administrator, I don’t ever want to be too heavy-handed or nitpicky in application of custom settings because unexpected changes to default settings could be surprising or frustrating to users. I want to give users an experience as close as possible to the out-of-box experience designed by Microsoft without compromising the no-first-run-pop-ups rule. You can customize almost any setting in Office by using the Office customization tool, but don’t do it! Most organization-specific setting customizations belong in Group Policy, not in the installation program.

Open an administrative Command Prompt window and run the Office setup program with the /admin switch:

"\\fileserver\software$\Microsoft\Office Professional Plus 2016 (32-bit)\setup.exe" /admin

The Microsoft Office Customization Tool window will open and prompt you to select a product. Office, Project, and Visio should be listed. Choose to create a new Setup customization file for Office.

32-bit Office

Here are the settings that I used. These settings eliminate most first-run pop-ups. Also, since my organization uses Microsoft Exchange, Outlook will be able to figure out the account settings for the signed-in user automatically, so I include a setting that tells it to just do that and not bother the user with the new account wizard. As is the case with most installers, specifying a silent installation is not enough to prevent a reboot, so a Setup property is specified to make that intention clear. (See Setup properties reference for Office 2013; again, we’re relying on some 2013 documentation because there is no updated version for 2016.)

Setup section
Install location and organization name Leave the default installation path.

Type your organization’s name in the appropriate box.

Licensing and user interface Ensure that Use KMS client key is selected. (This is the default.)

Ensure that the I accept the terms in the License Agreement checkbox is checked.

Set the display level to None. Then ensure that the subsequent checkboxes have the following states:

  • Completion notice –  not checked (the default once display level is set to None)
  • Suppress modal – checked
  • No cancel – not checked (the default)
 Modify Setup properties  Add the property name SETUP_REBOOT (all capital letters) with the value Never (first letter only capitalized).
Features section
Modify user settings Ensure that the Migrate user settings checkbox is checked.

Configure the following settings:

  • Microsoft Office 2016
    • Privacy
      • Trust Center
        • Disable Opt-in Wizard on first run – Enabled
          The Opt-in Wizard is a first-run prompt that allows users to opt into Internet-based services like MS Update, CEIP, Office Diagnostics, & online help.
        • Automatically receive small updates to improve reliability – Enabled
    • First Run
      • Disable First Run Movie – Enabled
      • Disable Office First Run on application boot – Enabled.
  • Microsoft Outlook 2016
    • Account Settings
      • Exchange
        • Automatically configure profile based on Active Directory Primary SMTP address – Enabled
          Outlook knows all of the right answers for the account setup wizard; this setting prevents the user from having to click next Next-Next-Next-Finish. Instead, it just works.
Set feature installation states Set the root node to Run all from my computer.
Regardless of feature installation settings, everything is copied to disk no matter what. The whole thing is there, and we paid for it, so let’s turn it all on so that people can use it without any hassle.
Additional content section
Add registry entries  Add a registry entry under HKLM to tag installations of Office with an easy-to-read marker denoting this Setup customization file. I use a registry key with my organization’s name and a value that contains the customization file’s name.

For example:

  • Data type: REG_SZ
  • Key: SOFTWARE\Generic Midwestern University
  • Value name: Office Customization Tool Patch – ProPlus 2016-x86
  • Value data: OCT-ProPlus2016-x86-Silent-Install-2016-02-15

That last item is just my personal preference and is completely optional. I thought it might come in handy at some point in the future to be able to easily tell whether a given Office installation had been installed using my customization file.

Save the customization file to the root of the Office installation source folder. (It should be in the same location as setup.exe.) It is saved as a Windows Installer patch file (MSP). I use the following formula for naming the customization file; a hyphen separates the individual pieces of information:

  • “OCT” for “Office Customization Tool”
  • Product name based on its folder name in the installation source (e.g., ProPlus), followed by the version under which it is marketed (e.g., 2016)
  • CPU platform (i.e., x86 or x64)
  • “Silent-Install” to indicate that the installation requires no user interaction
  • The date the customization was created in yyyy-mm-dd format.

Following this naming scheme, the filename for the customization we just built is OCT-ProPlus2016-x86-Silent-Install-2016-02-15.MSP. This, of course, matches the registry value I added.

Project, Visio, and 64-bit Versions of Everything

You will need to create new customization files for each of the other two products. All of my settings for Project and Visio are identical to those for Office with the following exceptions:

  • There are obviously no Outlook 2016 settings.
  • The added registry value will reflect the name of its own customization file.

Then, when that is done, you can move to your 64-bit Office installation source folder and create three more customization files for 64-bit versions of Office, Project, and Visio. Don’t mix the bitness of customization files and installation files. You must use the 64-bit setup.exe program to build 64-bit customization files, and you must use the 32-bit setup.exe program to build 32-bit customization files. You cannot use the same customization file for both the 32-bit and 64-bit versions of a product. You can, however, import a 32-bit customization file for a given product into the 64-bit OCT and then resave it as a 64-bit customization file for that same product, and vice versa.

When you are done, you should have six customization files. Mine are:

  • OCT-ProPlus2016-x86-Silent-Install-2016-02-15.MSP
  • OCT-VisPro2016-x86-Silent-Install-2016-02-15.MSP
  • OCT-PrjStd2016-x86-Silent-Install-2016-02-15.MSP
  • OCT-ProPlus2016-x64-Silent-Install-2016-02-15.MSP
  • OCT-VisPro2016-x64-Silent-Install-2016-02-15.MSP
  • OCT-PrjStd2016-x64-Silent-Install-2016-02-15.MSP

Testing Installation

My instructions above specified saving the customization files in the root of the Office installation source folder rather than in the Updates folder. If the customization files were in the Updates folder, they would be applied automatically during any installation. The problem is that only one customization for a given product can exist in the Updates folder. That’s fine for now; we only built a single customization file for each product. If I wanted to support multiple installations from a single installation source, though, this would not work. For example, suppose most users are served well by the installations described above, but for some business reason, some computers can only have Microsoft Word installed. If the customization files were in the Updates folder, I could not reuse this installation source; instead, I would have to have a separate copy of the complete Office installation files. That is clearly ridiculous, and so I planned ahead in case something like that happens by saving the customization files outside of the Updates folder. The consequence of that decision is that I must be explicit about which customization file when running setup. That will be our first command-line argument.

The second command-line argument will tell Setup which product to install. Since there is one setup.exe file in a folder structure of three products, Setup will prompt for which product to install unless we tell it on the command line in advance. To specify the product to install, we must point setup.exe to the config.xml file for the desired product. This file is located in the folder named after the product.

To get a full description of the command line parameters available, run setup.exe /?. Here are the commands to silently install the 32-bit versions of our three products:

rem The following command lines assume that the current directory is the installation source folder.

rem Office
setup.exe /adminfile "OCT-ProPlus2016-x86-Silent-Install-2016-02-15.MSP" /config "proplus.ww\config.xml"

rem Project
setup.exe /adminfile "OCT-PrjStd2016-x86-Silent-Install-2016-02-15.MSP" /config "prjstd.ww\config.xml"

rem Visio
setup.exe /adminfile "OCT-VisPro2016-x86-Silent-Install-2016-02-15.MSP" /config "vispro.ww\config.xml"

Coming Up

Next time, we’ll revisit the .NET prerequisites.

<update date=”2016-02-20″>Added setting the SETUP_REBOOT property to “Never”.</update>

<update date=”2016-04-17″>Revised the “Coming Up” section for accuracy.</update>