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.