Resolving .NET Framework 2.0 setup error related to the ALLUSERS property

I have heard from a couple of customers who ran into an interesting error while attempting to install the .NET Framework 2.0 on their systems.  The error message in the verbose MSI log file looks like the following:

MSI (s) (18!84) [14:41:46:857]: Product: Microsoft .NET Framework 2.0 -- 1: ALLUSERS property is not 1 - this MSM cannot be used for a per-user or fallback-to-per-user install 2:

How to workaround this error

After some digging through verbose MSI log files, we were able to figure out that this was caused by a previous Group Policy advertised installation of the .NET Framework 2.0 that was done on a per-user basis.

The customers I worked with were able to resolve this issue by going to Add/Remove Programs, uninstalling the Microsoft .NET Framework 2.0 item listed there, and then downloading and installing the full packaged version of the .NET Framework 2.0 on their own from this location (rather than relying on Group Policy to automatically install it for them).

More details about the root cause

The .NET Framework 2.0 inherits some behavior from the VC runtime redistributable MSMs that it consumes and does not support per-user installation.  The underlying issue in the VC runtime files was reported via this bug - https://connect.microsoft.com/feedback/viewfeedback.aspx?FeedbackID=98736&siteid=210, and it has been fixed in the Visual Studio 2005 SP1 version of these MSMs.  Unfortunately, because these MSMs are a part of .NET Framework 2.0 setup, there is not a way to avoid this error without repackaging the setup with newer versions of the MSMs.

How to find the root cause from a verbose MSI log file

For those of you interested in how to diagnose this type of error on your own, here is how Carolyn (the Windows Installer development lead) taught me to determine the exact root cause of this issue.  We started by looking at various sections of the verbose MSI log file.  The following are the relevant snippets:

MSI (c) (2C:40) [14:41:13:580]: Package name retrieved from configuration data: 'netfx.msi'
MSI (c) (2C:40) [14:41:13:580]: Determined that existing product (either this product or the product being upgraded with a patch) is installed per-user.
MSI (c) (2C:40) [14:41:13:580]: Note: 1: 2729
MSI (c) (2C:40) [14:41:13:661]: Note: 1: 2729
MSI (c) (2C:40) [14:41:13:661]: Note: 1: 2729
MSI (c) (2C:40) [14:41:13:661]: Note: 1: 2729
MSI (c) (2C:40) [14:41:13:661]: Note: 1: 2729
MSI (c) (2C:40) [14:41:13:661]: Note: 1: 2729
MSI (c) (2C:40) [14:41:13:661]: Note: 1: 2729
MSI (c) (2C:40) [14:41:13:661]: Note: 1: 2729
MSI (c) (2C:40) [14:41:13:661]: Note: 1: 2729
MSI (c) (2C:40) [14:41:13:661]: Note: 1: 2729
MSI (c) (2C:40) [14:41:13:661]: Note: 1: 2729
MSI (c) (2C:40) [14:41:13:661]: Note: 1: 2262 2: AdminProperties 3: -2147287038
MSI (c) (2C:40) [14:41:13:661]: PROPERTY CHANGE: Deleting ALLUSERS property. Its current value is '1'.

The information marked in bold above indicates that the .NET Framework 2.0 was already installed on the system, but it was installed per-user instead of per-machine.  In addition, some later information in the verbose MSI log file shows that it is assigned (most likely by Group Policy):

MSI (c) (2C:40) [14:41:13:661]: Product {7131646D-CD3C-40F4-97B9-CD9E4E6262EF} is admin assigned: LocalSystem owns the publish key.
MSI (c) (2C:40) [14:41:13:661]: Product {7131646D-CD3C-40F4-97B9-CD9E4E6262EF} is managed.
MSI (c) (2C:40) [14:41:13:661]: Running product '{7131646D-CD3C-40F4-97B9-CD9E4E6262EF}' with elevated privileges: Product is assigned.

...
MSI (c) (2C:40) [14:41:13:671]: PROPERTY CHANGE: Adding Privileged property. Its value is '1'.

Finally, another way to narrow down this behavior is to check the value of the ProductState property in the verbose MSI log file.  In the cases I have seen so far where this ALLUSERS error appears, the ProductState property is set to 1 like in the following log snippet:

MSI (s) (18:50) [14:41:34:199]: PROPERTY CHANGE: Adding ProductState property. Its value is '1'.

The value of 1 means the product is advertised but not installed. That is the standard method for Group Policy installation where advertisement occurs first (to grant elevated privileges) and then the install occurs afterwards.