WinAppMigrator

Command Line

Installers and uninstallers can run with no window, for scripts, for installing on many PCs, or on a PC without Direct3D 12. The app itself has no command line: it always opens its window.

Everything on this page is taken from the code at version 0.6.0. The README has the same in Automating the installer.

Before You Start

The Installer

Fabrikam_Data_Sync_installer.exe [--target-root <DIR>] [--dry-run | --apply] [--force]
                                 [--restore-user-data] [--no-restore-license] [--log <FILE>]
Flag What it does
--target-root <DIR> Where to install, as a full path. Without it, --apply and --dry-run use where the app was on the old PC, or for an app from a 32-bit Windows, the same folder under Program Files (x86), if the same checks the window makes allow that. If they do not, it stops and asks for a --target-root.
--apply Install for real. Without it, nothing is installed: the package is unpacked to a temporary folder, the changes are worked out and printed, and the folder is removed.
--dry-run Preview, said plainly. This is what happens anyway without --apply. It cannot be used together with --apply.
--force Use a folder that has files in it and no install on record, and replace files, registry values, services, tasks, shortcuts, and environment variables that are already there. See What --force does.
--restore-user-data Put user data in the real AppData, Documents, Saved Games, and ProgramData folders of whoever is signed in. Without it, user data goes under the install location.
--no-restore-license Leave out the license data in the installer. Without it, license data is restored.
--log <FILE> Also write the log to this file. The file must not exist yet.
--help Print the flags.
--version Print the version.

With arguments that do not say what to do, such as --force on its own, it prints a short usage note and exits with 0.

The window and the command line put user data in different places by default. The window's User Data box starts ticked, so user data goes to its real folders. On the command line, user data goes under the install location unless you add --restore-user-data. License data is restored by both, unless you untick License or add --no-restore-license.

They also differ on what is already there. Once the window has checked its folder, it replaces a file, registry value, service, task, shortcut, or variable of the same name, as --force does. On the command line without --force, a file it would write that is already there, such as an AppData file with --restore-user-data, stops the install before anything changes.

What It Prints

In order:

  1. Room: how much room it needs on each drive, and how much is free.
  2. Sets up: how many things it sets up beyond files, then one line for each, as Kind: name: what it does, the same as the window's list. Notes follow, as Note: lines.
  3. Reinstall applied. or Reinstall previewed.
  4. Changes logged: with a count, then Warnings:, Errors:, and Refused:, each with a count and one line per item. Each warning and error starts with a short code, such as service_account_not_restored.
  5. Package hashes valid: and, after an install, Reinstall hashes valid:, each true or false.
  6. Install id: the id of the install, which the uninstaller needs.
  7. If the install failed: The install failed, so what it changed was put back., then what was undone, what could not be, and what was left.
  8. Log: the path of the log.

If it stops before installing anything, it prints error: and why, on the error output, with the log's path if there is one.

Exit Codes

Code Meaning
0 It worked: the package's hashes were valid, every installed file checked out, and there were no errors. Also for --help, --version, and the usage note.
1 It did not work. It was refused before it started, or it failed and put back what it did, or a hash did not match. Read what it printed.
2 The arguments were wrong, such as an unknown flag, or --apply with --dry-run. Nothing was done.
Any other It stopped part-way. The next install from any installer built by WinAppMigrator puts back what was done first.

Examples

Preview, to see what an install would do at a location:

.\Fabrikam_Data_Sync_installer.exe --target-root "C:\Program Files\Fabrikam Data Sync" | Out-String

Install, keep what it printed, and act on the exit code:

$installer = ".\Fabrikam_Data_Sync_installer.exe"
$output = & $installer --target-root "C:\Program Files\Fabrikam Data Sync" --apply | Out-String
$code = $LASTEXITCODE
$output
if ($code -eq 0 -and $output -match 'Install id: (\S+)') {
    "Installed. Install id: $($Matches[1])"
} else {
    Write-Warning "The install did not work (exit code $code). See the output above."
}

To keep the error: line in $output as well, add 2>&1 before the pipe.

Install with the user data going to its real folders, without the license, and with a log of your own:

.\Fabrikam_Data_Sync_installer.exe --target-root "D:\Apps\Fabrikam Data Sync" --apply --restore-user-data --no-restore-license --log "C:\Logs\fabrikam-install.log" | Out-String
$LASTEXITCODE

What --force Does

Without --force, an install stops before changing anything if the location has files in it and no install of this project is on record there, whether or not any would be replaced, and also if a file it would write already exists. The window will not use such a folder at all, and replaces what is in a folder it does use.

With --force, it replaces existing files, registry values, services, tasks, shortcuts, and environment variables. A file it replaces comes back when you uninstall.

Only use it for a folder you know is this app's. A file of the same name is replaced, and another app's service could be running that file. Even with --force:

The Uninstaller

Each install leaves an uninstaller at a fixed place: %ProgramData%\WinAppMigrator\installs\<id>\uninstall.exe. It only ever reads the record in that place.

uninstall.exe --uninstall <ID> [--quiet] [--remove-user-data] [--log <FILE>]
Flag What it does
--uninstall <ID> Which install to undo. Required.
--quiet No window. It prints what it did instead.
--remove-user-data Also remove the app's user data and license data, which otherwise stay. In the window, this ticks the box to start with.
--log <FILE> With --quiet, also write the log to this file, which must not exist yet.
--help Print the flags. Give it after --uninstall and an id, such as uninstall.exe --uninstall wam-abc123 --help. On its own it only says the file is the installer stub.

Finding the ID

Get-ItemProperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*',
                 'HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*',
                 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*' -ErrorAction SilentlyContinue |
    Where-Object DisplayName -like 'Fabrikam Data Sync*' |
    Select-Object DisplayName, QuietUninstallString

A 32-bit app's entry may be under WOW6432Node, a per-user app's under HKCU:, and the name may carry a version.

What It Prints

With --quiet: Uninstalling and the app's name, then Undone:, Could not be undone:, Left in place:, and Left behind:, each with a count and one line per item, then Log: and the log's path.

Exit Codes

Code Meaning
0 With --quiet: it finished. Without --quiet: the window opened and closed normally, whatever it did.
1 With --quiet: something could not be undone, part of it is on a drive that is not connected, or it could not start, for example because the id is wrong or another install is running. Without --quiet: the window could not open.
2 The arguments were wrong, such as --uninstall with no id.

When it does not finish, the entry in Settings stays, so you can run it again.

Example

& "C:\ProgramData\WinAppMigrator\installs\wam-abc123\uninstall.exe" --uninstall wam-abc123 --quiet | Out-String
if ($LASTEXITCODE -ne 0) { Write-Warning "The uninstall did not finish (exit code $LASTEXITCODE)." }

Here wam-abc123 stands for the real id.

When the Window Cannot Open

If an installer's window cannot open, it shows a message ending: "It can still install without one: run this file from an administrator's command prompt with --apply, and --target-root followed by a folder to choose where."

If an uninstaller's window cannot open, its message gives the exact command, with --quiet, for that install.

Logs

Logs are kept in %ProgramData%\WinAppMigrator\logs, which only administrators can read. The last 20 are kept. A preview from the command line starts no log of its own there. Logs hold paths and key names, and never what a registry value, license file, or environment variable holds. See Files it keeps on a PC.

Last changed 2026-11-11. Describes WinAppMigrator as of its latest release, 0.6.0.