## Deploying Microsoft Office 2016: Removing Old Versions

For the last few weeks, we’ve been building application packages to serve as prerequisites for Office 2016 installation. Today, we’ll tackle one last preparatory issue before actually constructing the Office 2016 Application in Configuration Manager.

As we’ll see next week, Office 2016 has numerous options that can be set at installation time. One of these options instructs the Office Setup program to uninstall previous versions of Office before beginning the installation process. This is great because having multiple versions of Office installed just doesn’t work in several combinations, and in others, it is supported but not recommended. See Install and use different versions of Office on the same PC for links to additional details.

Unfortunately, this fantastic feature of the Office setup program doesn’t actually work! During setup, if the currently installed (old) version of Office contains a program (e.g., SharePoint Designer 2010) that has been eliminated from the product in the current version, the setup program can’t remove it. Also, if the existing installation is damaged in some way, it may not be able to be uninstalled reliably. Therefore, if we want a clean upgrade experience for existing installations, we have to find another method to remove previous versions of Office.

The Office Deployment Support Team Blog provides the answer. In the post, How to uninstall Office 2010 and move to Office 2013 (Click to Run or Volume License), the author writes:

Utilizing Offscrub is the best method of removing a previous version of Office. It will call setup.exe and MSIExec to remove the bits. It is best equipped to deal with machine or software corruption and completely removes Office app shortcuts for the previous version. We recommend using Offscrub in almost every situation of moving from Office 2010 to Office 2013.

What is this “OffScrub” program? OffScrub is the underlying VBScript program that runs when you download and run a Microsoft FixIt program to remove Office. We’re going to follow the Office Deployment Support Blog’s suggestion and use this technology to reliably remove all previous versions of Office back to Office 2003 before installing Office 2016. Let’s get started.

# Acquiring the Script Files

I am going to walk through all of the steps below, but you may want to take a moment to go read How to obtain and use Offscrub to automate the uninstallation of Office products from the Office Deployment Support Blog. That is a major source for this post.

Let me save you some time. I downloaded seven separate FixIt files for various versions of Office and Windows. For each version of Office, one package is available for Windows 7 and lower, and another package is available for Windows 8 and higher. It turns out that the OffScrub*.vbs file is the same in both packages. (There is one exception: The Windows 7 Offscrub03.vbs for Office 2003 is missing one of the subroutines that it calls—a bug—but the subroutine exists in the Windows 8 version.) Therefore, you will only have to download four FixIt files. We’ll use the Windows 8 versions because they are easier to extract and don’t have the bug mentioned above.

1. Browse to the Microsoft Support article, How to uninstall Office 2003, Office 2007 or Office 2010 suites if you cannot uninstall it from Control Panel.
2. Download each of the FixIt programs available on that page for Windows 8. Save them in folders named for the year of the Office version followed by a hyphen and the applicable OS platforms:
• 2003-Win8
• 2007-Win8
• 2010-Win8

Note: There is a FixIt listed separately for Office 2010 on Windows 10 in the Office Support article, Uninstall or remove Office 2010. As with the Windows 7 version, this FixIt is the same as the one listed here for Windows 8.

3. Browse to Uninstall Office 2013, Office 2016, or Office 365 from a Windows computer.

I wanted to show you where all of the files came from, but for reference, here are direct links to all of them:

Windows 7 & earlier
Windows 8 Windows 10
Office 2003 MicrosoftEasyFix50416.msi MicrosoftFixit20054.mini.diagcab No FixIt available
Office 2007 MicrosoftEasyFix50154.msi MicrosoftFixit20052.mini.diagcab  No FixIt available
Office 2010 MicrosoftEasyFix50450.msi MicrosoftFixit20055.mini.diagcab
Office 2013/2016 O15CTRRemove.diagcab

Based on the fact that the Office 2010 FixIt files are the same for Windows 10 and all other Windows versions, I am going to assume that the same is true for Office 2003 and 2007.

## Extract the OffScrub Scripts

Now we must depart a bit from our instructions, which predate the release of Windows 8. The FixIt programs we downloaded are packaged in DIAGCAB files. DIAGCAB files work with the Windows Troubleshooting Platform, but architecturally, they are just CAB files, so we can extract their contents with the expand command.

On your application staging file share (wherever you put application source files for Configuration Manager to find), create a folder structure for the OffScrub scripts. Mine will be \\fileserver\software$\Microsoft\OffScrub with a subfolder for each Office version. Make the appropriate changes for your environment in the commands below, and then run them. rem Change the path to match the parent of all of the folders created earlier. rem This can also be a network path, like \\server\share\OffScrubDownloads set OFFSCRUBSOURCE=E:\OffScrubDownloads set OFC2003WIN8=%OFFSCRUBSOURCE%\2003-Win8 set OFC2007WIN8=%OFFSCRUBSOURCE%\2007-Win8 set OFC2010WIN8=%OFFSCRUBSOURCE%\2010-Win8 set OFC20132016=%OFFSCRUBSOURCE%\2013-2016-O365-Win rem Change the path to match your Configuration Manager application source location. set OFFSCRUBDESTINATION=\\fileserver\software$\Microsoft\OffScrub
md "%OFFSCRUBDESTINATION%\2003"
md "%OFFSCRUBDESTINATION%\2007"
md "%OFFSCRUBDESTINATION%\2010"
md "%OFFSCRUBDESTINATION%\2013"
md "%OFFSCRUBDESTINATION%\2016"
md "%OFFSCRUBDESTINATION%\C2R"

rem Use the EXPAND command to extract the OffScrub files (-f) from the DIAGCAB files, which are really just CAB files with specialized contents, and disregard internal folder structure (-i).
expand -i "%OFC2003WIN8%\MicrosoftFixit20054.mini.diagcab" -f:OffScrub*.vbs "%OFFSCRUBDESTINATION%\2003"
expand -i "%OFC2007WIN8%\MicrosoftFixit20052.mini.diagcab" -f:OffScrub*.vbs "%OFFSCRUBDESTINATION%\2007"
expand -i "%OFC2010WIN8%\MicrosoftFixit20055.mini.diagcab" -f:OffScrub*.vbs "%OFFSCRUBDESTINATION%\2010"
expand -i "%OFC20132016%\O15CTRRemove.diagcab" -f:OffScrub*.vbs "%OFFSCRUBDESTINATION%\2013"
move /y "%OFFSCRUBDESTINATION%\2013\OffScrub_O16msi.vbs" "%OFFSCRUBDESTINATION%\2016"
move /y "%OFFSCRUBDESTINATION%\2013\OffScrubc2r.vbs" "%OFFSCRUBDESTINATION%\C2R"

The expand commands above extract just the VBS files that we need from the DIAGCAB files.

##### Update from 2016-04-03

Subsequent to this blog post’s initial publication, testing showed that while all of the extracted scripts work correctly when run manually, they fail on 64-bit Windows when run from inside a Configuration Manager Package. It turns out that even in Configuration Manager v1511, the engine that executes package programs is run in a 32-bit process on 64-bit Windows. That means that calls to cscript.exe on 64-bit Windows will use the SysWOW64 version of cscript.exe and will get the special modified view of the system provided for 32-bit processes. This prevents the scripts from adequately searching through the entire system and effectively removing Office programs. I added the following section to deal with this issue.

# Overriding the File System Redirector

In order to work properly, the Offscrub scripts must all run in the native bitness of the platform. On 64-bit Windows, that means we must directly call the native cscript.exe program when running from within a Configuration Manager Package. In order to keep the package programs platform neutral, I wrote a small script to use in place of cscript.exe that figures out which cscript.exe to call, and then does so. I am indebted to Andrew Lukaszewski, whose generic script to overcome this issue inspired the more specific script below.

Copy the following into a plain ANSI text file and save it as CScriptNative.cmd in the root of the Offscrub folder structure. (Mine is \\fileserver\software$\Microsoft\OffScrub\CScriptNative.cmd.) @echo off rem CScriptNative.cmd rem Author: Jay Michaud (www.deploymentmadscientist.com) rem Date: 2016-03-02 rem Source: http://www.deploymentmadscientist.com/2016/02/08/deploying-microsoft-office-2016-removing-old-versions/ rem Acknowledgement: Inspired by Andrew Lukaszewski's blog at https://madluka.wordpress.com/2012/09/24/configmgr-2012-64bit-file-system-redirection-bites-again/ rem Description: Use this command script in place of cscript.exe to ensure that the script runs as a 64-bit process on 64-bit operating systems. rem This is useful when deploying a script as a package program in Microsoft System Center Configuration Manager, where the engine that runs the package program is a 32-bit process on 64-bit Windows. rem Example: Instead of rem cscript.exe //B //NoLogo "\\server\share\path\to\my script.vbs" rem run rem NativeCScript //B //NoLogo "\\server\share\path\to\my script.vbs" rem On 32-bit Windows, the PROCESSOR_ARCHITEW6432 environment variable is not defined by the operating system. rem On 64-bit Windows, the PROCESSOR_ARCHITEW6432 environment variable is not defined by the operating system in 64-bit processes. rem On 64-bit Windows, the PROCESSOR_ARCHITEW6432 environment variable is defined by the operating system in 32-bit processes as "AMD64" (without quotation marks). if "%PROCESSOR_ARCHITEW6432%"=="AMD64" ( rem Currently running as 32-bit process on 64-bit Windows (SysWOW64) rem Launch CScript through Sysnative "%SystemRoot%\Sysnative\cscript.exe" %* ) else ( "%SystemRoot%\System32\cscript.exe" %* ) If the script detects that it is running in a 32-bit process on 64-bit Windows, it calls the 64-bit cscript.exe directly, bypassing the File System Redirector, by calling "%SystemRoot%\Sysnative\cscript.exe". Otherwise, it calls the native cscript.exe located in the System32 folder. # Building the Configuration Manager Package In the previous blog posts in this series, I have been using the phrase “application package” and the word “Application” (capitalized) interchangeably to refer to an Application object in Configuration Manager. Because the OffScrub VBS scripts perform a task and don’t actually install anything, an Application will not work. Instead, we will build a single Configuration Manager Package to hold all of the scripts. Please consult the TechNet documentation for assistance in building a ConfigMgr Package: Packages and programs in System Center Configuration Manager. Here are the specifics. Property Value Package Properties Name Microsoft OffScrub Description Collection of program removal scripts for Office 2003, 2007, 2010, 2013, 2016, and Office 365 from Microsoft PSS. Manufacturer Microsoft Language Leave blank Version Leave blank This package contains source files Checked Source folder \\fileserver\software$\Microsoft\OffScrub
Standard Program Properties – Office 2003
Name OffScrub03
Command line "%SystemRoot%\System32\cmd.exe" /C "CScriptNative.cmd //B //NoLogo "2003\OffScrub03.vbs" ALL /Quiet /NoCancel /Force /OSE"
Startup folder Leave blank
Run Hidden
Program can run Whether or not a user is logged on
Run mode Run with administrative rights (selection is disabled)
Allow users to view and interact with the program installation Unchecked
Drive mode Runs with UNC name
Run another program first Unchecked
This program can run only on specified platforms On any platform

Note that these scripts will only run on Windows, but in my environment, the 32-bit versions of Windows 8 and 8.1 are not present in this list, so I could not use this list to filter where this package would appear. I do not know if their absence is a bug in Configuration Manager or a problem with my organization’s ConfigMgr environment. In any case, I need these scripts to run on 32-bit Windows, so I must specify “On any platform” in order to have the above-mentioned platforms included.

Estimated disk space 146 KB
Maximum allowed run time (minutes) 120 (the default)

All of the scripts names are unique, so they all could have been placed into the same folder. Putting each script into its own folder allows this package to grow easily in the future even if Microsoft releases an OffScrub script with the same name as an existing one.

The Run, Program can run, and Run mode properties indicate silent installation and are typical for programs that need to be deployed as “required” or in a task sequence. My plan is to deploy this in a task sequence.

The command line deserves some explanation. Our instructions recommend not using the Force switch because it can cause users to lose data. I looked at the source code of the command line argument handling and the declarations of the flags that are set by those arguments. The reason for that warning is that the Force switch causes the Office programs to exit if they are running, presumably without allowing the user to save his/her data. Because I am planning to deploy this only in a task sequence, I will include a reboot step prior to running any OffScrub scripts; that will prevent any user from having an Office application running when the script starts.

Our instructions further recommend that we bypass stage 1 (/Bypass 1) when automating Office uninstallation because it can trigger repairs in some products. I took a look at the source code to see what stage 1 actually accomplishes, but I didn’t get very far because I noticed that if the Force switch is passed, the Bypass switch is ignored for stage 1. Since I am passing the Force switch to ensure a complete uninstallation, there is no point in passing the Bypass switch just to have it be ignored.

Each of these scripts automatically logs several different files of output to %TEMP% without any need to specify the /Log switch. While you are testing this package, check there to see if anything is going awry.

The rest of the programs are nearly identical to the first one we built above. I will list below only the properties that differ. Set all other properties to the same values as those in the Office 2003 program.

Property Value
Standard Program Properties – Office 2007
Name OffScrub07
Command line "%SystemRoot%\System32\cmd.exe" /C "CScriptNative.cmd //B //NoLogo "2007\OffScrub07.vbs" ALL /Quiet /NoCancel /Force /OSE"
Estimated disk space 172 KB
Standard Program Properties – Office 2010
Name OffScrub10
Command line "%SystemRoot%\System32\cmd.exe" /C "CScriptNative.cmd //B //NoLogo "2010\OffScrub10.vbs" ALL /Quiet /NoCancel /Force /OSE"
Estimated disk space 181 KB
Standard Program Properties – Office 2013
Name OffScrubO15
Command line "%SystemRoot%\System32\cmd.exe" /C "CScriptNative.cmd //B //NoLogo "2013\OffScrub_O15msi.vbs" ALL /Quiet /NoCancel /Force /OSE"
Estimated disk space 364 KB
Standard Program Properties – Office 2016
Name OffScrubO16
Command line "%SystemRoot%\System32\cmd.exe" /C "CScriptNative.cmd //B //NoLogo "2016\OffScrub_O16msi.vbs" ALL /Quiet /NoCancel /Force /OSE"
Estimated disk space 363 KB
Standard Program Properties – Office Click to Run
Name OffScrubC2R
Command line "%SystemRoot%\System32\cmd.exe" /C "CScriptNative.cmd //B //NoLogo "C2R\OffScrubc2r.vbs" ALL /Quiet /NoCancel /OSE"

Note: While the C2R script tests an internal fForce flag value, it does not process a /Force switch, so it is omitted here.

Estimated disk space 265 KB

Finally, now that all of the programs are created in the package, we must edit one property not available during program creation. Open each program, and on the Advanced tab, check the Allow this program to be installed from the Install Package task sequence without being deployed box.

We now have a Configuration Manager Package that can remove all traces of any version of Microsoft Office back to 2003.

# Coming Up

Next time, we will look at the Office 2016 setup program and how to customize it for silent installation through Configuration Manager.

<update date=”2016-02-21″>Added instruction to allow installation in a task sequence without being deployed.</update>

<update date=”2016-03-03″>Changed paths so that each script has its own folder. Removed /Log switch from all scripts because they all log to %TEMP% by default. Added warnings about failure on 64-bit operating systems.</update>

<update date=”2016-04-03″>Removed 64-bit warnings. Added “Overriding the File System Redirector” section and updated program command lines to use CScriptNative.cmd instead of cscript.exe.</update>

## Building a Global Condition in System Center Configuration Manager to Test the Internet Explorer Version

In the first post of this series, I listed the system requirements for Microsoft Office 2016. Those requirements included “The current or immediately previous version of Internet Explorer; the current version of Microsoft Edge, Safari, Chrome, or Firefox” as the browser requirements. Let’s simplify this to a minimum requirement. Since our Office 2016 application package will target Windows operating systems, we can guarantee that some version of Internet Explorer will be present. Our prerequisite logic for our Office 2016 application package can therefore focus on IE and ignore the other available options.

At the end of the overview post for this series, I wrote the following:

Windows 10, 8.1, and Server 2012 R2 have Internet Explorer 11 built in; Windows 8 and Server 2012 have Internet Explorer 10 built in. Both of these IE versions satisfy the requirements. For Windows 7 and Server 2008 R2, we’ll either have to build an IE11 application package or set a condition that checks for IE10 or IE11. My initial thought is to just set a condition because if any Windows installation is on an old version of IE at this point (January 2016), then the user or administrator has specifically blocked it from being installed in Windows Update as well as in the settings of IE itself, and so we should respect that decision and just fail the Office installation. (If I change my mind about this, you’ll find out in a future post.)

Well, I haven’t changed my mind! The day after I published that post, Microsoft ended support for Internet Explorer 10, leaving IE11 as the only supported version.

Microsoft aggressively pushes out Internet Explorer updates, and as I mentioned in the quoted passage above, any machine with IE10 or earlier is purposely configured that way, and our deployment package should not try to overcome that situation. (Alternatively, the computer may be misconfigured, or Windows Update functionality may be broken in some way; in either of these cases, it is better to fail our Office deployment and let the problem get addressed rather than try to resolve the issue in an automated way.) Based on this reasoning, rather than building another prerequisite application package for IE11, we will merely test that it is installed with a new Global Condition.

Microsoft documents several ways to determine a Windows installation’s Internet Explorer version in KB969393: Information about Internet Explorer versions. Fortunately, there is a registry value that will work nicely, and fortunately, even though this value is a string, we can test it with a “Begins with” verb when using it as an Application requirement.

As with our Server Core test, this Global Condition will be a simple query of a registry value. In Configuration Manager, in the Software Library workspace, navigate to Application Management>Global Conditions. I named my Global Condition “Internet Explorer Version”, and here are its properties:

Property Value
Name Internet Explorer Version
Description Returns the version of Internet Explorer 10 or 11 from the registry. The queried registry value (svcVersion) is not present when IE9 or earlier is installed. Use this to test the major version with the “Begins with” verb and a value of either “10.” or “11.”.
Device type Windows
Condition type Setting
Setting type Registry value
Data type String
Hive name HKEY_LOCAL_MACHINE
Key name SOFTWARE\Microsoft\Internet Explorer
Value name svcVersion
This registry value is associated with a 64-bit application Unchecked

# Coming Up

In a later post in this series, we’ll use this Global Condition with the verb “Begins with” and value “11” in the requirements of our Office application package to ensure that IE11 is installed. Next time, we’ll study a pitfall of Microsoft’s Office setup program.

## DEPRECATED: Deploying Any Version of Microsoft .NET Framework 4.x as a Prerequisite Application

This post describes how to turn on features of Windows that are no longer supported by Microsoft as of 12 January 2016, so I have published a new post to replace it. Please read the new post instead: Deploying Any Supported Version of Microsoft .NET Framework 4.x as a Prerequisite Application.

I mentioned last time that any version of the .NET Framework beginning with ‘4’ is an in-place upgrade for any similar version with a lower minor version number. Applications that depend on .NET 4.0 as a minimum should run fine on any subsequent 4.x version. We need something to use as a prerequisite for such applications. Rather than force every computer in an organization to move up to the latest version, it would be more efficient to just use whatever version of .NET is included in the operating system. Note, though, that the .NET Framework feature can be turned off in some versions of Windows, so we do need an application package to ensure that it is turned on. With this in mind, let us build a new Configuration Manager Application.

# Acquiring the Installation Files

We actually have everything we need already. All supported versions of Windows except for Windows 7 and Windows Server 2008 R2 have some 4.x version of .NET built in, and we can reuse our .NET 4.6.1 installer from last time to take care of the exceptions.

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 don’t actually need any source files, and so as with .NET 3.5 on Windows 7 and .NET 4.6.1 on Windows 10 November Update, we will just provide Configuration Manager with a single file in that folder. I created a text file with Notepad in the folder containing the following text: The following Microsoft .NET Framework 4.x versions are included as operating system compoments in the corresponding Windows versions, and so no content is required or available to install them on those versions. -Windows 8/Windows Server 2012 .NET Framework 4.5 -Windows 8.1/Windows Server 2012 R2 .NET Framework 4.5.1 -Windows 10 .NET Framework 4.6 Configuration Manager applications require a content folder, so this folder serves that role for the "Microsoft .NET Framework 4.x [Deploy as prerequisite only]" application's deployment types for these Windows versions. That explains the presence of the otherwise empty folder to anyone reviewing this folder structure. For Windows 7 and Windows Server 2008 R2, we will just install the latest version of .NET (4.6.1 at the time of this writing) in order to satisfy the requirement unless a lower 4.x version is detected. # Building the Configuration Manager Application ## Windows 7 and Windows Server 2008 R2 (64-bit and 32-bit) 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.x [Deploy as prerequisite only] Publisher Microsoft Version 4.x Deployment Type Properties Name Microsoft .NET Framework 4.6.1 – Windows 7 and Windows Server 2008 R2 (64-bit and 32-bit) Technology Script Installer 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)
Detection method Rule 1:
Hive/Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full
Value: Install
Data type: Integer
Equals 1
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 7 SP1 (32-bit), Windows 2008 R2 SP1 (64-bit)
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.

I included the suffix “[Deploy as prerequisite only]” in the name of the package because it doesn’t make sense to show this package to users. If a user opens Software Center, he/she should see normal applications that can be installed, not supporting libraries with ambiguous names. Don’t deploy this Application on its own; just set it as a prerequisite for other Applications that need it. The bracketed text serves as a reminder of this principle.

Speaking of principles, I violated one of my own rules: There is no uninstallation program. This is acceptable because again, this is a prerequisite application, and also because this application package just ensures that an on-by-default feature is still turned on, on most systems. If you want users to be able to uninstall this application from Software Center in Windows 7, deploy the .NET 4.6.1 package we built last time as “available”, and it will be detected as already installed when this application is installed. Then the user can choose to uninstall it.

Finally, notice the detection logic. We don’t actually test for version 4.6.1; we merely test that some version of .NET 4.x has been installed. If the user has previously installed .NET 4.0, 4.5, 4.5.1, 4.5.2, 4.6, or 4.6.1, these will all signify that this application is already installed. Only if none of these is installed will .NET 4.6.1 be installed by Configuration Manager.

# All Other Platforms

All of the other operating systems we are targeting can be satisfied by a single deployment type that merely turns on their built-in NetFx4 feature if it is turned off.

Property Value
Deployment Type Properties
Name Feature Installation – Windows 8, Server 2012, 8.1, Server 2012 R2, and 10 (64-bit and 32-bit)
Technology Script Installer
Content location \\fileserver\software$\Microsoft\.NET Framework 4.x\ Installation program "%SystemRoot%\System32\Dism.exe" /Online /LogLevel:4 /Enable-Feature /FeatureName:NetFx4 /All /NoRestart /Quiet Uninstall program None (leave blank) Detection method Same rule as Windows 7 and Windows Server 2008 R2 deployment type Installation behavior Same settings as Windows 7 and Windows Server 2008 R2 deployment type Requirements Operating system One of All Windows 8 (64-bit), All Windows 8 (32-bit), All Windows Server 2012 (64-bit), All Windows 8.1 (64-bit), All Windows 8.1 (32-bit), All Windows Server 2012 R2 (64-bit), All Windows 10 Professional/Enterprise and higher (64-bit), All Windows 10 Professional/Enterprise and higher (32-bit) Return codes Leave defaults Here we use a Dism command to turn on the NetFx4 feature. This feature name refers to whichever 4.x version is built into the target platform, or, if it has already been upgraded, it turns on the upgraded replacement version. For example, Windows 8 includes .NET 4.5 as an OS feature, so turning on NetFx4 enables .NET 4.5 functionality. If .NET 4.5.2, for instance, has already been installed on Windows 8 and then disabled, turning on NetFx4 enables .NET 4.5.2 functionality. Notice that we didn’t have to worry too much about Server Core in this application package. For the Windows 7/Server 2008 R2 deployment type, we just omit Server Core from the requirements as we did with the .NET 4.6.1 Application. For the other deployment type, since we are enabling an already-installed feature rather than running Microsoft’s buggy .NET 4.6.1 installer, there is nothing to worry about here regarding Server Core. The application package we just build will run fine on all supported platforms except a Server Core installation of Windows Server 2008 R2. # Coming Up That wraps up our three-week focus on .NET Framework installation. Next time, we’ll build one more Global Condition to check a prerequisite, and then we’ll move on to the home stretch of building a robust Microsoft Office 2016 Application in Configuration Manager. ## Deploying Microsoft .NET Framework 4.6.1 with System Center Configuration Manager Previously, we examined how Microsoft ships an old version of the .NET Framework for newer versions of its operating systems. This time, we will examine how Microsoft ships a new version of the .NET Framework for older versions of its operating systems. You may find it helpful to review the history of .NET Framework releases and the servicing methods they employed. I refer you to MSDN blogger Aaron Stebner for a pretty comprehensive description of how the various versions of .NET were bundled with Windows: Mailbag: What version of the .NET Framework is included in what version of the OS? Peter Marcu also has a graphic that shows OS .NET bundling information for Windows Vista, Windows 7, and their server counterparts. Beginning in .NET 4, the servicing model changed. Versions 3.x were additional features added on top of version 2.0. In contrast, any version above 4.0 with a major version number of ‘4’—4.5, 4.5.1, 4.5.2, 4.6, and 4.6.1—were complete, in-place replacements for all previous 4.x versions (but could exist alongside a 3.x version). These were installable on all supported operating systems at the time of their releases, and they shipped with the following OS releases: • Version 4.5 shipped as an operating system component in Windows 8. • Version 4.5.1 shipped as an operating system component in Windows 8.1. • Version 4.5.2 was released separately. • Version 4.6 was shipped as an operating system component in Windows 10. • Version 4.6.1 was shipped as an operating system component in Windows 10 November Update (v1511). Because some version of .NET 4.x shipped as an operating system component in each version of Windows since Windows 8/Server 2012, all subsequent versions are delivered as OS feature updates packaged as CAB files. These are then wrapped by an executable installer, which, in the 4.5.x versions, can extract the CAB files with the /createlayout switch. Unfortunately, it seems that Microsoft now really wants us to use the EXE installer: It has disabled the /createlayout switch in the installers for .NET 4.6 and higher. It is still possible to retrieve the CAB files in 4.6.1, but it is difficult, and you aren’t going to like the results. Here are two methods: 1. Run the offline installer on each platform for which you need to obtain the feature update CAB. The installer will extract the CAB file for only that platform into a temporary folder. 2. Use a third-party tool like 7-Zip to extract the entire contents of the offline installer executable. Reason you won’t like the results: In what I can only speculate is a move to discourage the very methods I have described, Microsoft has padded the CAB files to be gigantic. While the offline installer is less than 50 MB, each extracted CAB file is hundreds of megabytes in size. When I found this out, I surrendered: “OK, Microsoft! I’ll do it your way!” I built a Configuration Manager Application using the executable installer, and I rearranged my operating system image build process in Microsoft Deployment Toolkit to use the executable installer as well. Then I made a very annoying discovery: The executable installer does not work on Server Core installations. The embedded setup program fails and displays a list of “problem signatures”, including None_UI_Interactive_Crash and 0xc000008c. I am still investigating the cause and possible solutions to this problem, but I will not be finished in time for this blog post’s publication date. My goal here is to always provide complete solutions, but for now, I must limit the scope to what actually works, and that means that our .NET Framework 4.6.1 application package will only work on client OSes and full installations of server OSes. # Acquiring the Tools and Installation Files To build a Configuration Manager Application for Microsoft .NET Framework 4.6.1, you will need: Because Windows 10 November Update (v1511) includes .NET 4.6.1 as an OS component, it will have its own, nearly-sourceless deployment type just as Windows 7 did in our .NET 3.5 application package. You might think that all remaining OS versions could share a deployment type that just runs the executable installer, but take a look at this text under the Additional Information heading on the offline installer’s download page: When you install this package you will see following packages/updates installed as per operating system: • On Windows 7 SP1 / Windows Server 2008 R2 SP1, you will see the Microsoft .NET Framework 4.6.1 as an installed product under Programs and Features in Control Panel. • On Windows 8 / Windows Server 2012 you can find this as Update for Microsoft Windows (KB3102439) under Installed Updates in Control Panel. • On Windows 8.1 / Windows Server 2012 R2 you can find this as Update for Microsoft Windows (KB3102467) under Installed Updates in Control Panel. • On Windows 10 you can find this as Update for Microsoft Windows (KB3102495) under Installed Updates in Control Panel. Indeed, simply using the /uninstall switch on the offline installer fails on all platforms except for Windows 7/Server 2008 R2, so each platform must have its own deployment type that utilizes the Windows Update Standalone Installer (wusa.exe) to uninstall the corresponding update. These separate deployment types can share the same installation source folder, though. On your application staging file share (wherever you put application source files for Configuration Manager to find), create a folder structure for .NET 4.6.1. Mine will be \\fileserver\software$\Microsoft\.NET Framework 4.6.1. Under this folder, create the following subfolders.

Folder Name Description
PreWin10v1511 Windows 7, Windows 8, Windows 8.1, Windows 10 RTM (64-bit and 32-bit); Windows Server 2008 R2, Windows Server 2012, Windows Server 2012 R2 (64-bit)
Win10v1511 Windows 10 November Update (64-bit and 32-bit)
Win6.1×64Core Windows Server 2008 R2 (64-bit) (Server Core)
Win6.2×64Core Windows Server 2012 (64-bit) (Server Core)
Win6.3×64Core Windows Server 2012 R2 (64-bit) (Server Core)

Ignore the *Core folders for now; they are just placeholders, and we’ll return to them in a future post. Download NDP461-KB3102436-x86-x64-AllOS-ENU.exe (the offline installer linked above) into the PreWin10v1511 folder.

As with .NET 3.5 on Windows 7, we must provide Configuration Manager with a source file location, and so I created a text file with Notepad containing the following text and saved it into the Win10v1511 folder as readme.txt:

The Microsoft .NET Framework 4.6.1 is included in Windows 10 version 1511, so installation files are neither required nor available.

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

# Building the Configuration Manager Application

## Windows 7 and Windows Server 2008 R2 (64-bit and 32-bit)

In the Configuration Manager Console, create a new Application. Here are the values I provided in mine:

Property Value
Application Properties
Name Microsoft .NET Framework 4.6.1
Publisher Microsoft
Version 4.6.1
Deployment Type Properties
Name Offline Installer – Windows 7 and Windows Server 2008 R2 (64-bit and 32-bit)
Technology Script Installer
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 “NDP461-KB3102436-x86-x64-AllOS-ENU.exe” /q /norestart /uninstall Detection method Rule 1: Hive/Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full Value: Release Data type: Integer Greater than or equal to 394271 Rule 2: Hive/Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion Value: CurrentVersion Data Type: String Equals 6.1 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 7 SP1 (32-bit), Windows 2008 R2 SP1 (64-bit) 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. Take a look at the installation program: "NDP461-KB3102436-x86-x64-AllOS-ENU.exe" /q /norestart /ChainingPackage ADMINDEPLOYMENT You can display all available command line parameters for this program by running it with the /? switch or consulting the .NET Framework Deployment Guide for Developers. This is a typical installation command that suppresses all user interaction (/q for “quiet”) and prohibits the program from attempting to restart the computer. The ChainingPackage switch inserts whatever string is specified into the installation log, so that if something goes wrong, you can track down where the installation came from. The first detection rule and the return codes are also taken from the .NET Framework Deployment Guide for Developers. There are two details to note here. First, Windows Server 2008 R2 Sp1 Core (64-bit) is omitted in the operating system requirements. As described above, the offline installer does not work on Server Core. Second, there is a second detection rule that tests the operating system version. You may remember that we did not need a similar rule for the .NET 3.5 package, and it is unclear to me why we need it now. I just know that without it, the Configuration Manager client was unable to select which application package to use for uninstallation, and so the Uninstall button would be disabled in Software Center. Adding this check fixed the problem. ## Windows 8 and Windows Server 2012 The deployment type for Windows 8 and Windows Server 2012 is similar to that for Windows 7 and Windows Server 2008 R2. Duplicate everything in the Windows 7/Server 2008 R2 deployment type except for the properties in the table below. Property Value Deployment Type Properties Name Offline Installer/Windows Update Uninstaller – Windows 8 and Windows Server 2012 Uninstall program “%SystemRoot%\System32\wusa.exe” /uninstall /kb:3102439 /quiet /norestart /log:”%TEMP%\netfx461uninstallation.log” Detection method Rule 1: Same as Windows 7/Server 2008 R2 rule 1. Rule 2: Hive/Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion Value: CurrentVersion Data Type: String Equals 6.2 Requirements Operating system One of All Windows 8 (64-bit), All Windows 8 (32-bit), Windows Server 2008 R2 (64-bit)Custom: OS InstallationType Not equal to Server Core Note that the second detection rule has the kernel version for Windows 8 and Server 2012 (6.2), and also note that we made use of the OS InstallationType custom Global Condition we built last time to make sure we don’t try to install on Server Core. (Unlike with Windows Server 2008 R2, the there are no built-in requirement options to select or omit Server Core installations.) ## Windows 8.1 and Windows Server 2012 R2 As with Windows 8 and Server 2012, the deployment type for Windows 8.1 and Windows Server 2012 R2 is similar to that for Windows 7 and Windows Server 2008 R2. Once again, duplicate everything except for the properties in the table below. Property Value Deployment Type Properties Name Offline Installer/Windows Update Uninstaller – Windows 8.1 and Server 2012 R2 Uninstall program “%SystemRoot%\System32\wusa.exe” /uninstall /kb:3102467 /quiet /norestart /log:”%TEMP%\netfx461uninstallation.log” Detection method Rule 1: Same as Windows 7/Server 2008 R2 rule 1. Rule 2: Hive/Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion Value: CurrentVersion Data Type: String Equals 6.3 Rule 3: Hive/Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion Value: CurrentBuild Data Type: String Equals 9600 Requirements Operating system One of All Windows 8.1 (64-bit), All Windows 8.1 (32-bit), Windows Server 2012 R2 (64-bit)Custom: OS InstallationType Not equal to Server Core Once again, we’ve adjusted the second detection rule to test for the proper Windows kernel version (6.3), and we again made use of our custom Global Condition to prevent installation attempts on Server Core. Hopefully you noticed that I added a third rule to the requirements that tests the build number. With every release of Windows, Microsoft has to deal with compatibility issues caused by outside software vendors checking for exact versions of Windows rather than checking for a certain version or higher. In what I believe is the latest example of combating this problem by tricking such errant programs, Microsoft has stopped incrementing the CurrentVersion registry value. Windows 8.1, Windows Server 2012 R2, Windows 10 Release, and Windows 10 November Update all have a CurrentVersion value of 6.3. Since our uninstallers are specific to OS version, that means that we need some other value to let us differentiate between these systems. I chose the CurrentBuild value because I verified that it is different between Windows 8.1/Server 2012 R2, Windows 10 Release, and Windows 10 November Update and therefore fits our needs perfectly here. Microsoft may abandon this registry value in the future, too, or actually release an OS with the same build number, but at least for today, it works. (I did not use the new CurrentMajorVersionNumber and CurrentMinorVersionNumber values because they don’t differentiate between feature releases of Windows 10; both the Release and November Update have 10 and 0 for these registry values, respectively.) # Windows 10 Release Copy the deployment type for Windows 8.1/Server 2012 R2, and make the changes shown in the table below. Property Value Deployment Type Properties Name Offline Installer/Windows Update Uninstaller – Windows 10 Release Uninstall program “%SystemRoot%\System32\wusa.exe” /uninstall /kb:3102495 /quiet /norestart /log:”%TEMP%\netfx461uninstallation.log” Detection method Rule 1: Same as Windows 7/Server 2008 R2 rule 1. Rule 2: Hive/Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion Value: CurrentVersion Data Type: String Equals 6.3 Rule 3: Hive/Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion Value: CurrentBuild Data Type: String Equals 10240 Requirements Operating system One of Windows 10Custom: OS BuildNumber Equals 10240 The only thing new here is that we are using a different Global Condition in the requirements to ensure that this deployment type only works on the initial release of Windows 10 (build 10240). The OS InstallationType Global Condition is not needed because no server release accompanied the Windows 10 Release, so there will never be a Windows Server with the same build number as Windows 10 Release. The same is true for Windows 10 November Update. ## Windows 10 November Update We end with the easy one this time. Version 4.6.1 of the .NET Framework is a built-in operating system component in Windows 10 November Update, and it cannot be disabled. All deployment types must have an installation command, so we will just include a command to display the readme.txt file and exit. (This won’t actually display anything to the user because we specified Installation program visibility: Hidden.) No uninstallation command is required, so we’ll leave that box blank. Copy the deployment type for Windows 10 Release, and make the changes shown in the table below. Property Value Deployment Type Properties Name Feature Installation – Windows 10 Version 1511 Installation program “%SystemRoot%\System32\cmd.exe” /C type readme.txt Uninstall program None; leave blank. Detection method Rule 1: Hive/Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full Value: Release Data type: Integer Greater than or equal to 394254 Rule 2: Hive/Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion Value: CurrentVersion Data Type: String Equals 6.3 Rule 3: Hive/Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion Value: CurrentBuild Data Type: String Equals 10586 Requirements Operating system One of Windows 10Custom: OS BuildNumber Equals 10586 Although the Name property begins with “Feature Installation”, again, we cannot actually install anything because the feature is included in the OS and cannot be removed. We need a deployment type so that we can use this application as a prerequisite for another application and have it succeed on Windows 10 November Update; if we didn’t have this deployment type, installation of another application with this one as a prerequisite would fail on the only OS that has the needed feature built in! Note that we are testing for a different .NET 4.6.1 release number as described by the MSDN article referenced above, and we differentiate this deployment type from the one for Windows 10 Release by adjusting the OS BuildNumber value under Requirements. # Coming Up Next time, we’ll build a Configuration Manager Application that ensures that some version of .NET starting with ‘4’ is installed on the computer, and we’ll reuse part of our work on .NET 4.6.1 to do so. ## Building a Global Condition in System Center Configuration Manager to Test for Server Core When specifying requirements for an application package, Configuration Manager doesn’t provide a way to differentiate between full installations and Server Core installations of Windows Server 2012 and higher, but we may sometimes need to know this in order to choose between deployment types or to prevent installation of an application altogether. This is a job for: a new Global Condition! Microsoft was good enough to provide documentation: Determining Whether Server Core Is Running. We’ll use the registry option described on that page. In Configuration Manager, in the Software Library workspace, navigate to Application Management>Global Conditions. I named my Global Condition “OS InstallationType”, and here are its properties: Property Value Name OS InstallationType Description Returns the OS installation type from the registry. Possible values: Client, Server, Server Core. Device type Windows Condition type Setting Setting type Registry value Data type String Hive name HKEY_LOCAL_MACHINE Key name SOFTWARE\Microsoft\Windows NT\CurrentVersion Value name InstallationType This registry value is associated with a 64-bit application Unchecked # Coming Up Next time, we’ll use this new Global Condition to specify an installation requirement for a Configuration Manager Application deployment type. ## Deploying Microsoft .NET Framework 3.5 SP1 with System Center Configuration Manager Today’s topic demonstrates building a Configuration Manager Application package with multiple deployment types. I assume familiarity with the basics of building ConfigMgr Applications here, so if you need some remedial reading, please review the Deploy and manage applications with System Center Configuration Manager topic on TechNet. I will also be using Robocopy in this post. The documentation on TechNet is out of date for the most recent Windows versions, and it is incomplete. Run robocopy /? at a command prompt to get the usage information for your version of Windows. There are some excellent answers with links to better documentation on Super User. The .NET Framework 3.5 is a prerequisite for Microsoft Office 2013 and 2016 as well as many other commercial and internal applications. It was a built-in operating system component in Windows 7, but in Windows 8 and higher, it is a Feature on Demand and is not included by default. It is still an operating system component, but its installation status is “Disabled with Payload Removed”. You can see this for yourself by running the following command from an administrative command prompt in Windows 8/Server 2012 or higher. On a Windows 8.1 installation, for example, the command and its output will be: C:\>Dism /Online /Get-FeatureInfo /FeatureName:NetFx3 Deployment Image Servicing and Management tool Version: 6.3.9600.17031 Image Version: 6.3.9600.17031 Feature Information: Feature Name : NetFx3 Display Name : .NET Framework 3.5 (includes .NET 2.0 and 3.0) Description : .NET Framework 3.5 (includes .NET 2.0 and 3.0) Restart Required : Possible State : Disabled with Payload Removed Custom Properties: FWLink : http://go.microsoft.com/fwlink/?LinkId=296822 The operation completed successfully.  The easy way for consumers to get the .NET Framework 3.5 on these platforms is to turn the feature on in Windows Features (same steps as in Windows 7), and Windows will then download the component from Windows Update. The stated reason for this change was to decrease the Windows image size (install.wim). This is true: The Microsoft-supplied Windows images are indeed smaller for excluding .NET 3.5. Microsoft included all of the required files for .NET 3.5 in the sources\sxs folder in the ISO files and on the physical media that it distributes though, so this change really didn’t reduce the total size of the files that Microsoft delivers, and it made more work for you and me! There are options in Dism to install the .NET Framework 3.5 (hereafter, “NetFx3″—its feature name). (Note that feature names are case sensitive when used with Dism!) The following command installs NetFx3 from Windows Update just as if we had checked the box in Windows Features: Dism /Online /Enable-Feature /FeatureName:NetFx3 /All The following command installs NetFx3 using source files copied from the Windows installation media to the \\myserver\myshare file share: Dism.exe /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:"\\myserver\myshare" Installation of some programs that need NetFx3 will automatically trigger installation of the feature from Windows Update, but what if you are installing on a computer without access to the Internet and Microsoft’s servers? What if you are upgrading 20,000 Windows 7 computers to Windows 10 and don’t want to pay for the bandwidth to download NetFx3 20,000 times during your Office 2016 installation? (In the latter case, you could build a custom Windows 10 image with the feature installed, but maybe you don’t want to do that.) For these reasons, we will use the second approach shown above and depend on Configuration Manager to distribute the needed files for our .NET Framework 3.5 package. For more information about our chosen Dism command, see To restore removed Windows features in the TechNet article Enable or Disable Windows Features Using DISM. # Acquiring the Payload Files Unfortunately, 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. Let’s get started. On your application staging file share (wherever you put application source files for Configuration Manager to find), create a folder structure for .NET 3.5. Mine will be \\fileserver\software$\Microsoft\.NET Framework 3.5 SP1. Under this folder, create a folder for each operating system version that will be supported. Note that the 64-bit client OSes can share source files with their server counterparts; I checked, and the NetFx3 files are the same.

Folder Name Description
Win6.1 Windows 7 and Windows Server 2008 R2 (64-bit and 32-bit)
Win6.2×86 Windows 8 (32-bit)
Win6.2×64 Windows 8 and Windows Server 2012 (64-bit)
Win6.3×86 Windows 8.1 (32-bit)
Win6.3×64 Windows 8.1 and Windows Server 2012 R2 (64-bit)
Win10.0.10240×86 Windows 10 RTM (32-bit)
Win10.0.10240×64 Windows 10 RTM (64-bit)
Win10.0.10586×86 Windows 10 November Update (32-bit)
Win10.0.10586×64 Windows 10 November Update (64-bit)

That’s right, folks: We will be building nine—yes, nine—deployment types for this one application package.

Get your DVDs or ISOs ready; it’s time to copy the NetFx3 payload files to the folders you just created! Skip Windows 7 and Windows Server 2008 R2 for now. Assuming that your Windows 8 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:

Robocopy "D:\sources\sxs" "\\fileserver\software$\Microsoft\.NET Framework 3.5 SP1\Win6.2x86" /E /DCOPY:DAT /XJ I prefer using Robocopy because it allows me to preserve the time stamps on any folders I am copying with the /DCOPY switch. (Note that the Windows 7 version of Robocopy does not have the appropriate options to accomplish this, so you will need to use Windows 8 or higher for this functionality.) File timestamps are preserved by default. The /XJ switch is not really necessary here, but I make it a habit to always use it to exclude junction points unless I know I need to copy a certain junction point. (If a junction point targets a containing folder, Robocopy will keep following the junction in an infinite loop, leaving quite a mess that is difficult to clean up. I’m making a note now to blog about this in the future!) Use similar commands to copy the NetFx3 content from the Windows 8 64-bit, Windows 8.1 32-bit, and Windows 8.1 64-bit media to those operating systems’ respective folders in the folder structure we built above. Windows 10 is different. It supplies NetFx3 as a single file on a separate Features on Demand DVD or ISO file. Use this command to copy the 32-bit Windows 10 Release payload for NetFx3: Robocopy D:\ "\\fileserver\software$\Microsoft\.NET Framework 3.5 SP1\Win10.0.10240x86" microsoft-windows-netfx3-ondemand-package.cab

Use similar commands to copy the NetFx3 content from the Windows 10 Release 64-bit, Windows 10 November Update (build 1511) 32-bit, and Windows 10 November Update (build 1511) 64-bit media to those operating systems’ respective folders.

Finally, let’s take care of Windows 7 and Windows Server 2008 R2. These versions of Windows include Microsoft .NET Framework 3.5.1 as a built-in operating system component. Note that .NET 3.5.1 is .NET 3.5 Service Pack 1 with a few additional bug fixes. The payload cannot be removed, so the feature is always present on disk, even if it has been turned off. Therefore, no installation files are required.

Configuration Manager must have source files for every deployment type, though. My solution was to create a text file with Notepad containing the following text and save it into the Win6.1 folder as readme.txt:

The Microsoft .NET Framework 3.5.1 (SP1 plus some additional fixes) is included in Windows 7 and Windows Server 2008 R2, so installation files are neither required nor available.

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

# Building the Configuration Manager Application

## Windows 7 and Windows Server 2008 R2 (64-bit and 32-bit)

In the Configuration Manager Console, create a new Application. Here are the values I provided in mine:

Property Value
Application Properties
Name Microsoft .NET Framework 3.5 with Service Pack 1
Publisher Microsoft
Version 3.5 SP1
Deployment Type Properties
Name Feature Installation – Windows 7 and Windows Server 2008 R2 (64-bit and 32-bit)
Technology Script Installer
Content location \\fileserver\software$\Microsoft\.NET Framework 3.5 SP1\Win6.1\ Installation program “%SystemRoot%\System32\Dism.exe” /Online /LogLevel:4 /Enable-Feature /FeatureName:NetFx3 /NoRestart /Quiet Uninstall program “%SystemRoot%\System32\Dism.exe” /Online /LogLevel:4 /Disable-Feature /FeatureName:NetFx3 /NoRestart /Quiet Detection method Rule 1: Hive/Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5 Value: Install Data type: Integer Equals 1 Rule 2: Hive/Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5 Value: SP Data Type: Integer Equals 1 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 [all available Windows 7 versions selected], All Windows Server 2008 R2 (64-bit) Take a look at the installation program: "%SystemRoot%\System32\Dism.exe" /Online /LogLevel:4 /Enable-Feature /FeatureName:NetFx3 /NoRestart /Quiet This is a fairly typical Dism command that turns on the built-in .NET 3.5 feature. There are several points to note, though. First, we are not using any files from our file share. We had to provide a content location with a minimum of one file in it (which was the readme.txt described above), but we don’t actually have to use it. Second, we are logging everything so that if something does go awry, we have a chance to begin investigation immediately with a log rather than having to try to reproduce the problem as a first troubleshooting step. Third, we prevent the program from restarting the computer or attempting to interact with the user, which are always the right (and necessary) decisions in Configuration Manager applications—especially those designed to serve as prerequisites for other applications. The detection rules are taken directly from Microsoft Knowledge Base article, How to determine which versions and service pack levels of the Microsoft .NET Framework are installed. For the requirements, I selected “All Windows Server 2008 R2 (64-bit)”, which covers that version with and without SP1, and I selected the topmost “Windows 7” node, which automatically selected all subnodes, indicating all service pack levels and bitnesses of Windows 7. ## Windows 8 and Windows Server 2012 We have to actually provide the content for Windows 8 and Windows Server 2012. We already copied it to our target folder above. Here are the properties for two deployment types—one for 32-bit and one for 64-bit. Property Value Deployment Type Properties – Windows 8 (32-bit) Name Feature Installation – Windows 8 (32-bit) Technology Script Installer Content location \\fileserver\software$\Microsoft\.NET Framework 3.5 SP1\Win6.2×86\
Installation program “%SystemRoot%\System32\Dism.exe” /Online /LogLevel:4 /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:”.” /NoRestart /Quiet
Uninstall program “%SystemRoot%\System32\Dism.exe” /Online /LogLevel:4 /Disable-Feature /FeatureName:NetFx3 /NoRestart /Quiet
Detection method Same two rules as Windows 7 and Windows Server 2008 R2 deployment type
Installation behavior Same settings as Windows 7 and Windows Server 2008 R2 deployment type
Requirements Operating system
One of All Windows 8 (32-bit)
Deployment Type Properties – Windows 8 and Windows Server 2012 (64-bit)
Name Feature Installation – Windows 8 and Windows Server 2012 (64-bit)
Technology Script Installer
Content location \\fileserver\software$\Microsoft\.NET Framework 3.5 SP1\Win6.2×64\ Installation program “%SystemRoot%\System32\Dism.exe” /Online /LogLevel:4 /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:”.” /NoRestart /Quiet Uninstall program “%SystemRoot%\System32\Dism.exe” /Online /LogLevel:4 /Disable-Feature /FeatureName:NetFx3 /NoRestart /Quiet Detection method Same two rules as Windows 7 and Windows Server 2008 R2 deployment type Installation behavior Same settings as Windows 7 and Windows Server 2008 R2 deployment type Requirements Operating system One of All Windows 8 (64-bit), All Windows Server 2012 (64-bit) The Dism command used as the installation program is little bit more involved than a normal feature change command because the NetFx3’s payload is not present by default. It differs from the Windows 7 and Windows Server 2008 R2 version because we are forcing the OS to use the source files (payload) that we are providing: "%SystemRoot%\System32\Dism.exe" /Online /LogLevel:4 /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:"." /NoRestart /Quiet Configuration Manager copies all subfolders and files of the Content location to a folder on the local hard drive for installation. We left the Installation start in property empty in our deployment types, so the Installation program is run with that local folder as the working directory. To point the Dism command to the current directory, we pass “.” to the Source switch. The LimitAccess switch prevents the OS from attempting to download the source files from Windows Update. ## Windows 8.1 and Windows Server 2012 R2 The two 32-bit and 64-bit deployment types for Windows 8.1 and Windows Server 2012 R2 are nearly identical to those for Windows 8 and Windows Server 2012. As you construct these deployment types, make appropriate changes to the following properties: • Name • Content location • Requirements > Operating System ## Windows 10 The properties for all four Windows 10 deployment types are very similar to those for Windows 8, 8.1, Server 2012, and Server 2012 R2. As with the Windows 8.1 and Windows Server 2012 R2 deployment types, you must make appropriate changes to the Name, Content location, and Requirements properties. We’ll use the custom Global Condition from my previous post in the Requirements. You must also alter the installation and uninstallation commands to reflect the different payload packaging method used by Windows 10. For any properties omitted below, use the same values as with Windows 8, etc. Property Value Deployment Type Properties – Windows 10 Release (32-bit) Name Feature Installation – Windows 10 Release (32-bit) Content location \\fileserver\software$\Microsoft\.NET Framework 3.5 SP1\Win10.0.10240×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 Professional/Enterprise and higher (32-bit)
OS BuildNumber Equals 10240
Deployment Type Properties – Windows 10 Release (64-bit)
Name Feature Installation – Windows 10 Release (64-bit)
Content location \\fileserver\software$\Microsoft\.NET Framework 3.5 SP1\Win10.0.10240×64\ Installation program Same as Windows 10 Release (32-bit) Uninstall program Same as Windows 10 Release (32-bit) Requirements Operating system One of All Windows 10 Professional/Enterprise and higher (64-bit) OS BuildNumber Equals 10240 Deployment Type Properties – Windows 10 November Update (32-bit) Name Feature Installation – Windows 10 Version 1511 (32-bit) Content location \\fileserver\software$\Microsoft\.NET Framework 3.5 SP1\Win10.0.10586×86\
Installation program “%SystemRoot%\System32\Dism.exe” /Online /LogLevel:4 /Add-Package /PackagePath:”Microsoft-Windows-NetFx3-OnDemand-Package.cab” /NoRestart /Quiet
Uninstall program Same as Windows 10 Release (32-bit)
Requirements Operating system
One of All Windows 10 Professional/Enterprise and higher (32-bit)
OS BuildNumber Equals 10586
Deployment Type Properties – Windows 10 November Update (64-bit)
Name Feature Installation – Windows 10 Version 1511 (64-bit)
Content location \\fileserver\software\$\Microsoft\.NET Framework 3.5 SP1\Win10.0.10586×64\
Installation program Same as Windows 10 November Update (32-bit)
Uninstall program Same as Windows 10 Release (32-bit)
Requirements Operating system
One of All Windows 10 Professional/Enterprise and higher (64-bit)
OS BuildNumber Equals 10586

You may have noticed that I used the Capability options in Dism for the uninstallation commands but not for the installation commands. This nomenclature is new in Windows 10 as part of Features on Demand v2. Unfortunately, there is a bug in the /Add-Capability switch, so I used the /Add-Package switch as with earlier version for installation and used the new switch for the uninstallation. See the From the Media and From the Media: A Convenient Workaround sections of Michael Niehaus‘s blog post, Adding features (including .NET 3.5) to Windows 10 for details.

You may have also noticed that the release and November Update installation commands are identical except for the CAB filename character case. It’s true that case doesn’t usually matter in filenames on Windows, but I like to match the character case of the actual file; Microsoft used all small letters in the initial release and title casing in the November Update for the NetFx3 feature’s CAB file, and the property values listed above match those choices.

# Coming Up

Next time, we’ll do this all over again for Microsoft .NET Framework 4.6.1.

## Building a Global Condition in System Center Configuration Manager to Test the Windows Build Number

Configuration Manager doesn’t provide a way to differentiate between releases of Windows 10 when specifying requirements for an application package, but the Microsoft .NET Framework 3.5 feature source file differs between the two builds available at the time of this writing. (This may be true of all of Windows 10’s Features on Demand, but I haven’t checked any others.) We will also need a way to tell different releases of Windows 10 apart when installing .NET Framework 4.6.1. Therefore, we must make a custom Global Condition to provide the needed functionality for our application packages.

We need to find some attribute of the operating system that is unique between Windows 10 releases to test in our Global Condition . It turns out that Windows Management Instrumentation (WMI) has a property that we can use: the BuildNumber property of the Win32_OperatingSystem class. This returns—you guessed it—the Windows build number. Even though the build number is, well, a number, WMI defines this property as a string, so keep this in mind if you want to do value comparisons. For example, 10 > 9 (numeric comparison) but “10” < “9” (string comparison).

Global Conditions in Configuration Manager are located in the Software Library workspace under Application Management. I named my Global Condition “OS BuildNumber”, and here are its properties:

Property Value
Name OS BuildNumber
Description Returns the Windows build number from WMI.
Device type Windows
Condition type Setting
Setting type WQL Query
Data type String
Namespace root\cimv2
Class Win32_OperatingSystem
Property BuildNumber
WQL query WHERE clause None (leave blank)

# Coming Up

Next time, we’ll use this new Global Condition to specify an installation requirement for a Configuration Manager Application deployment type.

## Deploying Microsoft Office 2016: Overview and Prerequisites

I work for a large university in the midwestern United States, where part of my job is building operating system images and application packages for deployment with Microsoft System Center Configuration Manager. It is a lot of work to plan and build a high-quality, reliable deployment, and so I thought I would start my blog by documenting the process of building a set of Configuration Manager application packages for the latest version of one of the most commonly deployed applications on the planet: Microsoft Office. Numerous blogs have helped me to do my job, and it is my hope that this blog will be a worthy gift back to the online software deployment community.

Although Microsoft Office 2016 has been available for several months, there has not been an outcry for upgrades in my organization. We avoid making changes while classes are in session, so major upgrades tend to be scheduled in the downtime between the summer and fall semesters. I suspect, therefore, that the university will move to the new version in summer 2016, which gives me the time to document the required planning and testing here. We have licensed Microsoft Office Professional Plus 2016; we are not using the Office 365 offering.

# Application Packaging Guidelines

Goal: Build a reliable Microsoft Office Professional Plus 2016 application package in System Center Configuration Manager for deployment across multiple operating system versions.

I will explain my philosophy of application packaging and deployment fully in a later post, but for now, I will just list these brief rules for applications deployed through Configuration Manager’s Software Center:

• Installation must be silent.
• The application package must account for all possible dependencies.
• The installation must be reversible.
• First-run prompts must be minimized or preferably eliminated.

# Hardware Requirements and Prerequisite Software

Let’s start by taking a look at the System requirements for Office 2016. This will tell us the hardware requirements, which we will need later when building our application package, and any prerequisite software. We must either test for the presence of prerequisite software or build separate application packages for that software. My university has licensed Office Professional Plus, so I will focus on that edition’s requirements. Here they are:

From <https://products.office.com/en-us/office-system-requirements>
COMPONENT REQUIREMENT
Computer and processor 1 gigahertz (GHz) or faster x86-bit or x64-bit processor with SSE2 instruction set
Memory 2 GB RAM
Hard disk 3.0 GB available disk space
Display 1280 x 800 screen resolution
Graphics Graphics hardware acceleration requires a DirectX 10 graphics card.
Operating system
Windows 10, Windows 8.1, Windows 8, Windows 7 Service Pack 1, Windows 10 Server, Windows Server 2012 R2, Windows Server 2012, or Windows Server 2008 R2
For the best experience, use the latest version of any operating system.
Browser The current or immediately previous version of Internet Explorer; the current version of Microsoft Edge, Safari, Chrome, or Firefox.
.NET version
.NET 3.5 required. Some features may require .NET 4.0, 4.5, or 4.6 CLR to also be installed.
Other Internet functionality requires an Internet connection. Fees may apply.
A touch-enabled device is required to use any multi-touch functionality. But, all features and functionality are always available by using a keyboard, mouse, or other standard or accessible input device. Note that touch features are optimized for use with Windows 8, Windows 8.1 or Windows 10.
Product functionality and graphics may vary based on your system configuration. Some features may require additional or advanced hardware or server connectivity.

I highlighted the portions that interest me right now; we’ll come back to the hardware requirements later.

At my university, there is little top-down direction regarding which operating system version should be used, and so I must plan to support all of the listed operating systems in order for my application package to be useful to the entire organization. Unfortunately, that means I have to ensure compatibility with ten client operating systems and three server operating systems:

• Windows 7 SP1 (huge installed base in my organization) (64-bit and 32-bit)
• Windows 8 (hopefully no one is running this, but we need to support it anyway) (64-bit and 32-bit)
• Windows 8.1 (small installed base in my organization) (64-bit and 32-bit)
• Windows 10 RTM (hopefully no one is running this, but we need to support it anyway) (64-bit and 32-bit)
• Windows 10 November Update v1511 (small installed base, but our platform of choice for all new installations and reinstallations beginning in summer 2016) (64-bit and 32-bit)
• Windows Server 2008 R2
• Windows Server 2012
• Windows Server 2012 R2

I only worry about software that has actually been released, so the next version of Windows Server is irrelevant at the time of this writing. Also, yes, I know that installing Office on Windows Server is a terrible idea, but Microsoft supports it, so my application package will support it.

You may be wondering why I am so concerned about the operating systems when the Office team has taken care of operating system support. The answer lies in the prerequisites. The various versions of the .NET Framework are installed differently on different operating systems. Each of the required .NET Framework versions must have its own application package in Configuration Manager to act as a prerequisite to the main Office 2016 package. I will cover building the .NET application packages in future posts.

Browser support is less of an issue. Windows 10, 8.1, and Server 2012 R2 have Internet Explorer 11 built in; Windows 8 and Server 2012 have Internet Explorer 10 built in. Both of these IE versions satisfy the requirements. For Windows 7 and Server 2008 R2, we’ll either have to build an IE11 application package or set a condition that checks for IE10 or IE11. My initial thought is to just set a condition because if any Windows installation is on an old version of IE at this point (January 2016), then the user or administrator has specifically blocked it from being installed in Windows Update as well as in the settings of IE itself, and so we should respect that decision and just fail the Office installation. (If I change my mind about this, you’ll find out in a future post.)

# Coming Up

The .NET Framework packages are large and complex. They are also applicable to other applications besides Office, so I will cover them first. Next time, we’ll build a single .NET Framework 3.5 SP1 package that works for all 13 platforms listed above. After that, we’ll build a .NET 4.6.1 package. Finally, because Office’s .NET 4.x version requirement is flexible—any version that starts with ‘4’ is OK—we’ll build a package that does the minimum amount of work for a given platform in order to satisfy that requirement, and we will make use of the .NET 4.6.1 package source for platforms that don’t have .NET 4.x included as an OS component.