HomeKb › Win32 64 bit toggle syswow64
Knowledge base · Windows

Win32 PowerShell installers silently ran 32-bit despite the 64-bit toggle

Your install script works perfectly in a local console, then fails when the Intune Management Extension runs it — files land in SysWOW64, registry writes hit WOW6432Node, and the 64-bit toggle you set did nothing. Here is why it happens, and the short guard that makes the problem impossible regardless of agent version.

The problem

You package a PowerShell-driven installer as a Win32 app (.intunewin), set Run installation and uninstall as 64-bit process (64-bit clients) to Yes, and deploy. The script that ran cleanly on your admin workstation now misbehaves from Intune — and there is no error message pointing at the cause. Typical symptoms:

Patch My PC documented the underlying defect: even with the 64-bit option enabled on the Win32 app policy, "the installer script still launches under 32-bit PowerShell inside the Intune Management Extension" — "the switch appears functional from a configuration perspective, but the underlying process launch does not enforce the architecture choice at the operating system level." Anyone deploying PowerShell-based Win32 installers on agent builds prior to IME 1.101.103.0 hit this, and many scripts written without an architecture guard still carry the latent assumption today.

Why it happens

Two Windows mechanisms combine here, and both are silent by design.

WOW64 redirection

64-bit Windows runs 32-bit processes through the WOW64 compatibility layer. To keep legacy applications working, WOW64 transparently redirects certain paths for any 32-bit process: requests for C:\Windows\System32 are served from C:\Windows\SysWOW64 (the 32-bit system directory, despite the name), and HKLM\SOFTWARE is mapped to HKLM\SOFTWARE\WOW6432Node. This is not an error condition — no exception is thrown, no warning is logged. The process simply reads and writes somewhere other than where the script author intended.

The agent is 32-bit

The Intune Management Extension (IME) is a 32-bit service — it lives under C:\Program Files (x86). When a 32-bit parent process starts powershell.exe from the System32 path, WOW64 redirects that launch too, and the child is the 32-bit PowerShell host from SysWOW64. The 64-bit toggle in the Win32 app policy was meant to force the 64-bit host, but as the Patch My PC analysis showed, the setting was recorded in configuration without the process launch enforcing it at the operating-system level — the agent's own attempt to reach the 64-bit binary was itself redirected. Microsoft resolved this in IME 1.101.103.0, which disables WOW64 file-system redirection (the Wow64DisableWow64FsRedirection mechanism) around the launch so the toggle genuinely produces a 64-bit host.

This is also why the failure is so confusing: when you test the script yourself, you almost certainly run it in a 64-bit console, ISE or VS Code session where no redirection occurs. "Works on my machine" is literally true — the machine is not the variable, the bitness of the parent process is.

The fix

1. Add a sysnative relauncher to the top of every script

Windows exposes a virtual directory, %WINDIR%\Sysnative, that is visible only to 32-bit processes and always points at the real 64-bit System32. A guard at the top of the script detects the 32-bit host and re-executes itself in the 64-bit one:

if (Test-Path "$env:WINDIR\SysNative\WindowsPowerShell\v1.0\powershell.exe") {

& "$env:WINDIR\SysNative\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -ExecutionPolicy Bypass -File "$PSCommandPath" @args; exit $LASTEXITCODE

}

Because Sysnative does not exist for 64-bit processes, the Test-Path is false when the script is already 64-bit and execution simply continues. The relaunch preserves arguments and propagates the exit code, so Intune's success/failure reporting still works. This is belt and braces: correct behaviour whatever the IME version and whatever the toggle says. It also works on ARM64 devices, where Sysnative resolves the same way.

2. Or call the 64-bit host in the install command itself

In the Win32 app's install command field you can invoke the 64-bit engine directly, because the command is launched by the 32-bit agent:

%windir%\sysnative\WindowsPowerShell\v1.0\powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\install.ps1

The in-script guard is still worth keeping — it protects the script wherever it is reused, not just in this one deployment.

3. Guard detection and requirement scripts too

Custom detection and requirement scripts are launched by the same agent and are subject to the same redirection rules — the install-time toggle does not govern them. Give them the identical guard, or make their registry reads architecture-explicit (see below), otherwise a correctly installed app can be reported as missing.

4. If a script must stay 32-bit, address the 64-bit hives deliberately

Use reg.exe with the /reg:64 switch, or in .NET, [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, [Microsoft.Win32.RegistryView]::Registry64), to read and write the real 64-bit registry from a 32-bit process.

5. Verify rather than assume

How Decolla handles it

Decolla cannot change which PowerShell host the Intune Management Extension launches — only Microsoft can, and did, in IME 1.101.103.0. What Decolla does instead is remove the dependency on that fix ever being present.

Every PowerShell-delivered item in Decolla's pre-built library carries the sysnative architecture guard as standard, and each script is tested in both the 32-bit and 64-bit host contexts before it enters the catalogue. Behaviour is therefore identical whatever the agent version on the device and whatever the toggle state in the policy — files land in the real System32, registry writes land in the real HKLM\SOFTWARE, and the customer never has to know WOW64 exists.

Two other parts of the model matter here. First, the written plan you approve before anything runs states the delivery method for every item, so you can see exactly which items execute as PowerShell under the agent. Second, per-item rollback targets the changes Decolla itself made — and because the scripts are architecture-guarded, those changes were made in the intended 64-bit locations, so rollback removes them from where they actually are rather than from a redirected shadow copy. Rollback covers Decolla's own changes only, not third-party or pre-existing state.

Decolla is pre-launch and waitlist-only, and it runs entirely against your own Intune/Autopilot tenant.

Sources

See it on a real device.

Decolla is in private build — early-access members see a build defined, deployed and rolled back first.

Get early access