Documentation

Enterprise Deployment

Deploy TontonTools across your fleet with SCCM/Configuration Manager and Microsoft Intune. Silent install and uninstall, version-independent detection, and a single procedure that applies to both MSI packages. This guide is deliberately version-agnostic: you extract every identifier from your own copy of the MSI, so it never goes stale when a new build ships.

Overview & scope

TontonTools ships as two independent MSI packages. The deployment procedure is identical for both — you simply apply it twice, once per MSI. Nothing in this guide depends on a specific version: every product code, upgrade code and version number is read from your own downloaded MSI using the snippets below. MSI packages are rebuilt on every release and the product code changes each time, so hard-coding those values would make any guide wrong at the next update.

MSI packageContentsLicensing
Suite MSIAll nine suite tools in a single installer. The MSI always lays down all nine binaries; the license unlocks the tools your tier covers at runtime.Essentials / Pro / Enterprise subscription.
App Migrator MSIThe SCCM to Intune App Migrator, shipped as its own dedicated installer.Sold separately as an annual subscription.
  • Architecture All tools are WPF applications on .NET Framework 4.7.2.
  • Per-user data User settings live in %APPDATA%\TontonTools\ on the logged-on profile.
  • Machine license License files live in %ProgramData%\TontonTools\licenses\ (machine-wide).
  • No telemetry Nothing is phoned home except license validation. Every administrative operation goes directly from the workstation to Microsoft.

Prerequisites

  • Operating system Windows 10 or Windows 11, 64-bit.
  • Runtime .NET Framework 4.7.2 or later (present by default on supported Windows builds).
  • Deployment rights Install in the SYSTEM / machine context with administrative privileges — the same as any per-machine MSI.

Find your MSI's identifiers

Before you build a deployment, extract the identifiers from the exact MSI you downloaded. Three values matter:

  • ProductCode A GUID that uniquely identifies one specific version of a product. It changes with every published build — this is the value SCCM and Intune use for MSI detection.
  • UpgradeCode A GUID that stays constant for the lifetime of the product across all versions. Use it to build version-independent uninstall scripts.
  • ProductVersion The version string, useful for "greater than or equal to" detection rules.

Before deployment — read directly from the .msi file

This reads the MSI database without installing anything, so there is no risk to the machine you run it on. Run it against every MSI you download.

Get-MsiProps — extract ProductName, ProductCode, ProductVersion, UpgradeCode, Manufacturer and ALLUSERS from an MSI file.
function Get-MsiProps {
    param([Parameter(Mandatory)][string]$Path)
    $names = 'ProductName','ProductCode','ProductVersion','UpgradeCode','Manufacturer','ALLUSERS'
    $wi = New-Object -ComObject WindowsInstaller.Installer
    $db = $wi.GetType().InvokeMember('OpenDatabase','InvokeMethod',$null,$wi,@($Path,0))
    foreach ($n in $names) {
        $q = "SELECT Value FROM Property WHERE Property='$n'"
        $v = $db.GetType().InvokeMember('OpenView','InvokeMethod',$null,$db,$q)
        $v.GetType().InvokeMember('Execute','InvokeMethod',$null,$v,$null) | Out-Null
        $r = $v.GetType().InvokeMember('Fetch','InvokeMethod',$null,$v,$null)
        $val = if ($r) { $r.GetType().InvokeMember('StringData','GetProperty',$null,$r,1) } else { '<not set>' }
        [pscustomobject]@{ Property = $n; Value = $val }
        $v.GetType().InvokeMember('Close','InvokeMethod',$null,$v,$null) | Out-Null
    }
}
Get-MsiProps "C:\path\to\downloaded.msi" | Format-Table -AutoSize

After a pilot install — confirm from the registry

Once you have installed on a pilot machine, confirm the values your detection rules will target by reading the uninstall registry keys.

Read the installed product entry from the uninstall registry (32- and 64-bit hives).
Get-ItemProperty `
  'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
  'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' -EA SilentlyContinue |
  Where-Object { $_.DisplayName -like '*<product name>*' } |
  Select-Object DisplayName, DisplayVersion, InstallLocation, UninstallString, PSChildName
  • PSChildName is the {ProductCode} of the installed product — the exact value a registry-based detection rule keys on.
  • WOW6432Node On a 64-bit OS, a 32-bit MSI appears under the WOW6432Node hive — check both, as shown above.

Silent install and uninstall (msiexec)

These commands are generic. Substitute your own MSI filename and the ProductCode you extracted above — no GUID is hard-coded here.

Silent install with verbose logging.
msiexec /i "<your.msi>" /qn /norestart /l*v "%TEMP%\install.log"
Silent uninstall by product code (the code of the version actually deployed).
msiexec /x <ProductCode> /qn /norestart
  • /qn Fully silent, no UI.
  • /norestart Suppresses any reboot the package might request — let your deployment tool own reboot policy.
  • /l*v Verbose logging to the path you specify. Keep this on for fleet rollouts; it is your first stop when something fails.

Because the ProductCode changes every release, an uninstall script that hard-codes a GUID breaks at the next version. Resolve the current ProductCode at run time from the UpgradeCode — which is constant across all versions — so the same script keeps working forever.

Resolve and uninstall every installed version sharing one UpgradeCode.
$upgradeCode = "<UpgradeCode from Get-MsiProps>"   # constant across all versions
$wi = New-Object -ComObject WindowsInstaller.Installer
$related = $wi.GetType().InvokeMember('RelatedProducts','GetProperty',$null,$wi,@($upgradeCode))
foreach ($pc in $related) { Start-Process msiexec.exe -ArgumentList "/x $pc /qn /norestart" -Wait }

Detection methods (robust to rebuilds)

Detection tells SCCM or Intune whether the app is already installed. Pick a method that survives a rebuild rather than one you have to re-edit every release.

  • Recommended Let SCCM/Intune auto-detect the product code from the MSI you upload. Each uploaded MSI carries its own ProductCode, so detection is correct for that version automatically — the right level of granularity with zero manual editing.
  • Robust alternative Key on the registry DisplayVersion ≥ x.y.z, or on the file version of the installed executable ≥ x.y.z. This survives rebuilds where only the build metadata changed.
  • Avoid Re-using a single hard-coded product code across versions. It changes on every release, so the rule silently goes stale and reports "not installed" after an upgrade.

Deploy with SCCM / Configuration Manager

Use the Application model (not the legacy Package model). Create one Application per MSI.

  1. 1

    Create the Application

    In the Configuration Manager console: Software Library → Application Management → Applications → Create Application. Point it at the MSI; the wizard reads the ProductCode automatically.

  2. 2

    Set the deployment type to Windows Installer (*.msi)

    The wizard creates a Windows Installer deployment type. Review the auto-generated install command, and set the uninstall command to "msiexec /x <ProductCode> /qn /norestart" (or use the version-independent script above for the uninstall program).

  3. 3

    Install for system, regardless of sign-in state

    In the deployment type: Installation behavior = Install for system; Logon requirement = Whether or not a user is logged on. TontonTools installs per machine.

  4. 4

    Detection method

    Keep the auto-detected MSI product code, or switch to a registry DisplayVersion ≥ x.y.z rule if you prefer the rebuild-robust approach.

  5. 5

    Requirements

    Add OS = Windows 10/11 64-bit and a .NET Framework 4.7.2 requirement so the app only targets eligible machines.

  6. 6

    Distribute and deploy

    Distribute the content to your distribution points, then deploy the Application (Required or Available) to a device or user collection.

Deploy with Microsoft Intune

Intune offers two relevant app types for an MSI. For a managed fleet, the Win32 app is the better choice in current Intune; the line-of-business (LOB) app is simpler but limited.

Option A — Line-of-business app (MSI)

Apps → All apps → Create → Windows platform → Line-of-business app, then select the .msi. Intune reads the product code automatically. This is the quickest path, but it carries real limitations.

  • Per-machine MSI, single file only — no companion files or transforms.
  • No dependencies and no supersedence relationships.
  • Only one command-line argument can be supplied; anything more requires the Win32 app type.
  • LOB MSIs are handed straight to msiexec by the built-in MDM agent and do not run through the Intune Management Extension (IME).

Package the MSI into an .intunewin file with the Microsoft Win32 Content Prep Tool (IntuneWinAppUtil.exe), then add it via Apps → All apps → Create → Windows platform → Windows app (Win32). Win32 apps run through the Intune Management Extension, which is what unlocks the richer controls.

  • Install / uninstall Use the msiexec commands from the section above for the install and uninstall programs.
  • Detection rule Choose MSI product code (auto-filled for this version) or a file/registry rule for the rebuild-robust approach.
  • Install behavior System context, 64-bit, with a minimum OS requirement.
  • Richer controls Win32 supports custom detection and requirement rules, up to 100 dependencies, and supersedence for clean upgrades — none of which LOB offers.
  • Assignment Assign Required or Available to your device or user groups.

Microsoft Learn has the authoritative, current step-by-step for both types: Add a Win32 app and Add a line-of-business app. Verify the screens against Microsoft Learn before finalizing, as the Intune admin center evolves.

Licensing your deployed instances

Deployment and licensing are independent. Pushing the MSI silently (as described above) installs the binaries; it does not activate a license.

  • Per-machine activation Each installation activates on its own machine with the license key at first launch.
  • Where it is stored License files live in %ProgramData%\TontonTools\licenses\ (machine-wide); user settings live in %APPDATA%\TontonTools\ on the logged-on profile.

For volume license provisioning across many machines, contact support. Self-service mass licensing is a post-launch evolution. For the complete activation, validation, offline grace and read-only behavior reference, see Licensing.

Verification & post-install checks

  • Detection Confirm SCCM/Intune reports the app as detected (the product code matched).
  • Launch Launch a tool on a pilot machine and confirm it opens and reaches the license / credentials dialog.
  • Logs Review the verbose install log you captured under %TEMP% (or your chosen path) for warnings.

Upgrade & uninstall

  • Upgrade Deploy the new MSI. Because it shares the same UpgradeCode, Windows Installer replaces the previous version in place. In Intune Win32, model this with a supersedence relationship for a clean transition.
  • Uninstall Use the version-independent uninstall script above so you do not depend on a specific ProductCode.
  • Order The Suite MSI and the App Migrator MSI are independent products; you can install, upgrade or remove them in any order.

Troubleshooting

Start with the verbose msiexec log (/l*v). The most common Windows Installer return codes are:

CodeMeaningWhat to do
0Success.Nothing — the install completed.
3010Success, but a reboot is required.Treat as success; let your deployment tool handle the reboot. With /norestart this is expected.
1618Another installation is already in progress.Serialize installs. Common when Win32 and LOB apps collide during Autopilot — deploy MSIs consistently as Win32.
1603Fatal error during installation.Open the /l*v log and search for "return value 3" to find the failing action. Often a permissions or prerequisite issue.
  • Detection errors If the app installs but reports "not installed", your detection rule is stale — most often a hard-coded product code from an older build. Switch to auto-detection from the uploaded MSI or to a DisplayVersion ≥ x.y.z rule.