One of the biggest challenges in application deployment is modifying settings post-install. These “settings” can include customizing application preferences, tying the application to a data source, activating the software, or accepting the EULA. This article will explore where to find these settings and how to deploy them as part of your deployment. These processes are system-agnostic, meaning that they will work whether you use group policy for software deployment, System Center Configuration Manager, KACE, or any other desktop management solution.
As a disclaimer, please ensure that your license agreement allows you to accept the EULA for a product or activate it for multiple machines. If your agreement does not allow this, then do not automate these processes.
This article will contain numerous uses of phrases like “most of the time” or “for the most part”. No two installers are same. Some products store things in files, folders, or registry keys that you have no idea what the developers were thinking when they built it. When dealing with software installs, you must have patience and the time to root out these settings. Packaging software is more of an art form than anything else.
Most of the time, post-install settings will be located in four areas. These areas are the user’s AppData folder (C:\Users\\AppData), ProgramData (C:\ProgramData), HKEY_CURRENT_USER, or HKEY_LOCAL_MACHINE. If you’re lucky, settings will be stored in ProgramData or HKEY_LOCAL_MACHINE. These are the easiest areas to deploy too, because they exist for the machine and not the user. Deploying to these areas are normally simple file/folder copies or registry writes. If it is an MSI installer, you also have the option of creating an MST that contains the files, or even directly editing the MSI.
If settings are stored in the user’s AppData folder or in HKEY_CURRENT_USER, the process becomes a little more difficult. Normally, this involves copying the files/folders to the Default user directory (C:\Users\Default) or loading the Default user registry hive and writing the keys there. I will go into more detail on this later.
For the most part, it is a look-until-you-find-it process of finding these configurations. Normally, you need to look for folders, files, or registry keys that are named with either the manufacturer of the software or the software title. That is a good indication that you need to pick up those files.
Machine locations are far easier to deal with than user locations. As I said before, all you normally have to do for items saved in machine locations is copy them to your package directory. You can then use a script to first install the software, then copy down and files/folders, and then write any registry keys that are required.
I recommend using a simple batch file or a PowerShell script to do these installs. Always start with the program install first, then do any of your copies or registry changes. To copy files in a batch file, use the xcopy command. Here is the format: “xcopy /c /q /s /e /y /i”. To copy files using PowerShell, use the copy-item cmdlet. Here is the format: “copy-item \* -recurse”. Please note that in both of these commands, if the directory you are copying too is not already built, you can add the directory to the end of the destination path. For example, if I were wanting to copy files to “C:\Users\\AppData\Roaming\application1” and the folder application1 did not exist yet, my destination path for xcopy and copy-item would be “C:\Users\\AppData\Roaming\application1”.
To write registry keys with a batch file, use the reg command. The format will be like this: “reg add /v /t /d /f”. For PowerShell, there are two commands that you must run. First, we must create the key. To do that, you run: “New-Item -Path ”. Next, we have to create the values. To do that, run: “New-ItemProperty -path -name -PropertyType -Value ”. I know that some of the descriptions seem confusing, but that is what they are. In the example below, I show what is considered the key, the value, the type, and the data.
So if I were writing the above key using a batch file, the command would look like this:
reg add HKLM\SOFTWARE\7-Zip /v Path /t REG_SZ /d “C:\Program Files\7-Zip\” /f
If I were writing it with PowerShell, it would look like:
new-item -path HKLM:\SOFTWARE\7-Zip new-itemproperty -path HKLM:\SOFTWARE\7-Zip -name Path -propertytype string -value “C:\Program Files\7-Zip\”
Always remember to include your directory path in quotes if the path contains spaces. This applies to batch files and PowerShell scripts.
User locations are much harder to deal with. If the user account has already been created on the machine, you almost always have to run the installer as the user instead of as administrator. This can present problems if you do not run your users as machine administrators. For SCCM shops, this means setting the deployment to run as user instead of as administrator. I do not have a good solution for capturing these settings if the user account has already been created. One solution, though not ideal, is to do two programs / deployment types. One program will run as administrator and do the application install. The second program will be our script that copies the settings and will run as the user. You can chain these together by using “run another program first” or “dependences”, depending on if you are doing it as an application or package.
If the user account has not been created yet, you can copy all of the settings to the Default user profile, and those settings will be copied to every user that logs onto the machine. For file / folders, use the same xcopy command from above, but copy everything to C:\Users\Default. For registry settings, we have to mount the default user registry hive. From a batch file, run this command:
reg load HKLM\default C:\Users\Default\NTUSER.DAT
This will mount the hive to HKLM\default. From there, you can run normal reg add commands to the hive. When you are done, run:
reg unload HKLM\default
This will unmount the hive.
PowerShell, again, is more complicated. We have to create a new PowerShell drive to make this work, but first we have to use the above command to mount the hive. Here is the series of commands:
cmd.exe /c ‘reg load HKLM\default C:\Users\Default\NTUSER.DAT’ New-PSDrive -Name HKDU -PSProvider Registry -Root HKLM\default
These commands create the new drive, and we can write keys to it. To write the key, the path is “HKDU:\ ”. Other than that, use the same set-itemproperty command from above. To unmount the drive and hive, run this at the end of your script:
Remove-PSDrive HKDU [gc]::collect() Cmd.exe /c ‘reg unload HKLM\default’
The [gc]::collect() is very important. It clears the PowerShell drive from memory so that the reg unload command works.
If you cannot find any files, folders, or registry keys to deploy, you can use the Repackager that comes with AdminStudio to find what is modified after you change something. You can do the normal snapshot method in Repackager to analyze the entire system for changes. This will tell you what changed on the system. You can then either extract those changes and use a method listed above to deploy them, or compile the Repackager project into an MSI and deploy it. I would caution against using the MSI that Repackager can create for changes in user locations, as they usually do not deploy correctly.
For complete article on Repackager, go here: Application Deployment: Using AdminStudio Repackager
If you take anything away from this article, let it be that it takes patience to find and collect this changes and then write the scripts to deploy them. The PowerShell scripts included in this article appear challenging and long, but PowerShell is the better to go. It is very versatile and can be very detailed. As I stated at the beginning, packaging applications is an art. I have been doing this for years and discover new things about it every day.