How to run 64bit Powershell from 32bit Powershell with Workspace One Sensors

Workspace ONE Sensors is an awesome new feature (released in WS1 console version 1904) that enables an admin to put together any Powershell script and use that as inventory data to build reports and even do automation with WS1 Intelligence. Right now though, sensors run in 32bit context and don’t yet have a way to do automatic 64bit redirection. Most of the time this doesn’t matter as you are often querying WMI or checking for running services that don’t do any redirection. But you can run into issues if you need to query the registry or certain system file paths as Windows will automatically re-direct to WOW64. Here’s an example:

Recently, I needed to query a few registry keys to find out the email address or UPN of the user that is enrolled on the device. First, I need to find the GUID of my enrollment and then use that to query a different key. Like this:

$guid = (Get-ItemProperty -Path "HKLM:SOFTWARE\Microsoft\Provisioning\OMADM\Accounts\*" -ErrorAction SilentlyContinue).PSChildname
$upn = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Enrollments\$GUID" -ErrorAction SilentlyContinue).upn
return $upn
In 64 bit powershell it runs great

However, when I try this in 32bit powershell (which is done by launching it from C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell_ise.exe) as well as turning off the “-ErrorAction SilentlyContinue” parameter so you can see the error, it can’t find the key:

This is because Windows automatically redirects the request of HKLM\Software\Microsoft\Provisioning… to HKLM\SOFTWARE\WOW6432Node\Microsoft\Provisioning. But in this location, the keys I need don’t exist. This can be extremely frustrating if you don’t realize this is happening. The easiest way I found to get around this is to call the 64bit powershell exe and just pass it a here-string like this:

@'
$guid = (Get-ItemProperty -Path "HKLM:SOFTWARE\Microsoft\Provisioning\OMADM\Accounts\*" ).PSChildname
$upn = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Enrollments\$GUID" ).upn
return $upn
'@ | &"$env:windir\Sysnative\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -Command -
Voila! It works!

Some other examples are a bit simpler, like doing a get-childitem on a filepath:
Get-Childitem C:\Windows\System32\WinBioDatabase

To workaround this, we simply call $env:windir\sysnative like this: get-childitem $env:windir\sysnative\WinBioDatabase
Here are some other tips regarding 32bit and 64bit Powershell that might be helpful:

  1. How to check which version your script or session is running in:
$Arch = (Get-Process -Id $PID).StartInfo.EnvironmentVariables["PROCESSOR_ARCHITECTURE"];
if ($Arch -eq 'x86')
{
	Write-host 'Running 32-bit PowerShell'
}
elseif ($Arch -eq 'amd64')
{
	Write-host 'Running 64-bit PowerShell'
}

2. To manually run the exes of each version of powershell:

32 Bit powershell path
C:\Windows\SysWOW64\WindowsPowerShell\v1.0

64 bit powershell path
C:\Windows\System32\WindowsPowerShell\v1.0

Create Sensor

Now let’s create our sensor and deploy to our device.
In the WS1 UEM console, navigate to Devices > Provisioning > Custom Attributes > Sensors

Click Add > Windows

For name ensure you start with a lowercase letter and then use underscores for spaces.
Also set your trigger (on an event or per your sampling schedule). Next.

Paste the powershell script. You can also upload a .ps1 file you prefer, but I like to paste it directly into the window.
Execution context: System

Click Finish. Now we need to assign this to our devices.
Find your sensor in the list (will be alphabatized). Check the box and click “Assign”.

Search for your smart group. Select it and then click Assign.

That’s it! For more sensor examples as well as where you can contribute additional sensors, go to our github page.

Leave a Reply