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:
Hive/Key:
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
    set ISODRIVEROOT=D:\
    
    robocopy %ISODRIVEROOT% "%OFFICEFOLDER%" /E /XJ /COPY:DAT /DCOPY:DAT LOG:"%OFFICEFOLDER%\OfficeCopyLog.txt"
  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.
    robocopy %ISODRIVEROOT% "%OFFICEFOLDER%" /E /XJ /COPY:DAT /DCOPY:DAT /XC /XN /XO /LOG:"%OFFICEFOLDER%\ProjectCopyLog.txt"
  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.
    robocopy %ISODRIVEROOT% "%OFFICEFOLDER%" /E /XJ /COPY:DAT /DCOPY:DAT /XC /XN /XO /LOG:"%OFFICEFOLDER%\VisioCopyLog.txt"
  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:

  • Root: HKEY_LOCAL_MACHINE
  • 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>

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.

Download the FixIt Programs

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.
  4. Download the “easy fix tool” into a folder named “2013-2016-O365-Win”.

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
(Shaded links aren’t needed for this blog post.)
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.