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.
- Use an administrator's PowerShell. Installers and uninstallers always demand administrator rights. From an ordinary PowerShell, Windows refuses to start them, with "The requested operation requires elevation".
-
Pipe the output somewhere. Installers are windowed programs. PowerShell only waits for one, shows what it prints, and sets
$LASTEXITCODE, if you pipe it, for example toOut-String. - Any argument at all skips the window. Double-clicking, with no arguments, opens the window. With any argument, an installer runs without one.
-
Check the signature yourself. A command-line install prints nothing about a signature. Check the file with
Get-AuthenticodeSignaturebefore you run it.
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.
In order:
-
Room:how much room it needs on each drive, and how much is free. -
Sets up:how many things it sets up beyond files, then one line for each, asKind: name: what it does, the same as the window's list. Notes follow, asNote:lines. -
Reinstall applied.orReinstall previewed. -
Changes logged:with a count, thenWarnings:,Errors:, andRefused:, each with a count and one line per item. Each warning and error starts with a short code, such asservice_account_not_restored. -
Package hashes valid:and, after an install,Reinstall hashes valid:, eachtrueorfalse. -
Install id:the id of the install, which the uninstaller needs. - 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. -
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.
| 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. |
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-StringInstall, 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
$LASTEXITCODEWithout --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:
- services, tasks, and what ties an app into Windows stay another app's;
- outside the install location, no program goes into a folder that was already there without an install on record. A data file there is replaced.
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. |
- The installer prints it, as
Install id:, when it installs from a command line. - The app's entry in Settings holds the full command, in the registry values
UninstallStringandQuietUninstallString. For example, in an administrator's PowerShell:
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, QuietUninstallStringA 32-bit app's entry may be under WOW6432Node, a per-user app's under HKCU:, and the name may carry a version.
- Each install's folder under
%ProgramData%\WinAppMigrator\installsis named by its id, startingwam-.
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.
| 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.
& "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.
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 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.