Tanium: PowerShell MSI Uninstall

Overview

By now, you've probably heard that VBScript (VBS) is on its way out. Microsoft has announced that the VBScript Feature on Demand (FoD) will be disabled by default as part of its phased retirement. For many organizations, this means dusting off years-old login scripts, automation, and deployment tools that have been quietly running in the background for decades.

Rather than waiting until the change is enforced, now is the time to inventory your existing VBScript usage, validate business-critical workflows, and begin migrating to modern alternatives like PowerShell.

In my environment, that process started with an existing Uninstall MSI script used by Tanium packages. While the original script had served us well, it was time to modernize it, improve its flexibility, and ensure it would continue to work in a post-VBScript world.

In this post, I'll walk through how I converted the script to PowerShell, made it more dynamic for use with Tanium package parameters, and highlight a few lessons learned along the way. Let's jump in.

The Details

I already have an existing function that has served me well in the past (Get-App). However, with Tanium, I needed to modify it to support dynamic input and allow parameters to be passed through the command line.

This script is focused specifically on MSI-based installations. In the traditional Tanium workflow, you first use the Installed Applications sensor to retrieve the uninstall string, and then leverage the built-in Uninstall MSI package to execute the removal based on that registry data.

That approach works, but it still relies on VBScript and on querying the sensor before taking action. In my case, I wanted more flexibility. My version can be deployed directly to a known list of endpoints without relying on sensor data, as long as you already know the systems have MSI-based installs. This removes a dependency on VBScript while making the process more direct and dynamic.

For my use case, the dynamic approach allows the user to input the application name and define a search pattern—whether that’s Exact, Wildcard, Regex, or Contains.

One issue I ran into was handling spaces and special characters. PowerShell does not automatically decode URL-encoded parameters. While some versions of Tanium allow you to disable URL encoding for package parameters, this behavior is not consistent across all package types and environments. When that option isn’t available, decoding directly in PowerShell is the most reliable approach.

To handle this, I added the following line:

$Application = [System.Uri]::UnescapeDataString($Application)

This ensures common encoded values are properly translated, for example:

  • %2A*
  • %20 → space
  • %28(
  • %29)

…and importantly, it leaves any non-encoded parameters untouched.

This pattern is fairly common when scripts are executed through deployment or orchestration tools that automatically URL-encode command-line arguments, so accounting for it early avoids a lot of unexpected matching issues later on.

The complete code can be found here: MSI-ApplicationRemoval

Once you have that download, navigate over to your Tanium console and create a new package. Within the package, provide the follow details.

Package Details

Package Name:
PowerShell MSI Uninstall

Display Name:
PowerShell MSI Uninstall

Description:
(Not populated)

Content Set:
End-User Notifications


Command

cmd.exe /d /c powershell.exe -NoLogo -NonInteractive -ExecutionPolicy Bypass -File MSI-ApplicationRemoval.ps1 -Application $1 -SearchType $2

Execution Settings

  • Command Timeout: 15 Minutes
  • Download Timeout: 30 Minutes
  • Ignore Action Lock: Not enabled
  • Launch this package command in a process group: Enabled

Files

  • MSI-ApplicationRemoval.ps1

Notes

  • The command supports sensor variables (via the “Add sensor variables” option) to dynamically pass:
    • $1 → Application name
    • $2 → Search type (Exact, Wildcard, Regex, Contains)







Once you've created your package, deploy it to your target devices. You can monitor the deployment by reviewing the deployment results. If you'd like additional information displayed during execution, feel free to add any Write-Host (or other output) commands that meet your needs. I intentionally kept the script generic to provide a flexible starting point and plan to enhance it over time as new requirements arise.

Code Repository

Github

Post a Comment

0 Comments