Windows Administration with PowerShell #6: Enforcing Absence of an Application
If you have been following along with this series, you are likely now familiar with a lot of the foundational components that are used when developing PowerShell scripts. Today we will be using what we have learned to work with Automox Custom Policies. More specifically, we will be creating a policy that can be used to enforce the absence of an Application.
Real World Scenario #4: Ensuring an App is Not Installed
Most of us have been in this situation at some point or another. Imagine you are skimming through a list of installed applications in your environment and something jumps out at you: software that should have no business being installed on a work computer. In our particular scenario, it’s the Steam application. Luckily, with your new PowerShell skills, you can easily script something up to uninstall it.
Similar to our ‘Clear-TempFiles’ solution, the first step is evaluation. We talked a bit last week about how we could use WMI to do this, specifically the ‘Win32_Product’ class. The catch is that not all products will create instances here. The more accurate method is to use the same source that Add Remove Programs uses: the registry.
The registry key above contains entries for all applications that show in Add Remove Programs. To enumerate them in PowerShell, use the Get-ItemProperty cmdlet:
As you can see, this will return the properties of each child key. The one we are interested in for our scenario is DisplayName. Using Where-Object, we can filter our results as follows:
We now have the information we need to trigger an uninstall. There is, however, one caveat. If you have a 64-bit endpoint, there are actually two registry hives that you need to consider. Since Automox runs x86 PowerShell, you will have to spawn off a second PowerShell process from your script that uses x64 bit PowerShell to look at the second hive. Specifically, we are looking for the UninstallString property. This will contain the cmdline you can use to trigger the uninstall of your desired product. Let’s write a function to take care of all this for us:
It’s important to note that the function will return a null value if no application is found. For our evaluation script, you will want to use this to tell Automox whether or not remediation is needed. Remember: exit 0 tells Automox no remediation is needed while exit 1 indicates the opposite.
Now that we have our evaluation script, all that’s left to do is remediation. Luckily, we can use the same function from above to get the uninstall command line. All that is left to do after that is determine any arguments you may need to pass to the uninstaller. Since these arguments are specific to the application you want to uninstall, there is a little research that is required. In our case, we want to pass the ‘/S’ argument to our Steam uninstaller to ensure a silent uninstall of the application. This will minimize any disturbance to the user.
Before returning a success to the Automox console, you will need to verify that the application was actually uninstalled. You can do this by running the same function we wrote again and checking the return value. If the result is null, our uninstall was successful. It’s important to note that uninstallations will not always be quick. Depending on the application you are uninstalling, the length of required time may be longer.
This particular scenario is made a little more difficult by a variety of factors. The main difficulty is that standardization across vendors servicing the Windows environment has notoriously been a pain. As such, the most accurate way to determine the presence of an application is also the ugliest way. If you are working specifically with MSI installations then there are methods that can be used which accomplish the desired outcome in a much cleaner way.
The second pain point is the way Windows implements 64-bit and 32-bit applications. While necessary, there are various challenges that are introduced with the need to traverse the architectures. You probably noticed some weird looking commands in our solution that utilize the ‘&’ character. This essentially tells PowerShell that any code on the rest of the line should be executed as a command. In our case, we are using this to spawn a 64-bit instance of PowerShell which we then use to scan the 64-bit registry to determine the presence of our application. This is another issue that is mitigated when working with MSI installs due to the methodology involved.
As mentioned above, MSI Installations are much easier to work with. Unfortunately, there is no guarantee that every Application you will need uses the MSI installer. That said, there is still a large variety of vendors that prefer it. Next week, we will dive into what exactly an MSI installer is and how to work with them. We will also demonstrate how much simpler the above exercise would have been if working with an application that utilizes MSI technology.
Facing growing threats and a rapidly expanding attack surface, understaffed and alert-fatigued organizations need more efficient ways to eliminate their exposure to vulnerabilities. Automox is a modern cyber hygiene platform that closes the aperture of attack by more than 80% with just half the effort of traditional solutions.
Cloud-native and globally available, Automox enforces OS & third-party patch management, security configurations, and custom scripting across Windows, Mac, and Linux from a single intuitive console. IT and SecOps can quickly gain control and share visibility of on-prem, remote and virtual endpoints without the need to deploy costly infrastructure.
Experience modern, cloud-native patch management today with a 15-day free trial of Automox and start recapturing more than half the time you're currently spending on managing your attack surface. Automox dramatically reduces corporate risk while raising operational efficiency to deliver best-in-class security outcomes, faster and with fewer resources.