SOLVED

Win32 App Powershell 64bit registry access issue

Copper Contributor

Hello to all.

Coming from SCCM to Intunes i started to recreate Application packages, with installers based on MSI, Batch, EXE and PowerShell. However i found an issue with PowerShell installations, that i am not able to overcome.
Powershell is not accessing 64 bit registry, due to Intune agent running the script in 32 bit mode.

For example when i try to write a key (or value) to HKEY_LOCAL_MACHINE\SOFTWARE\Test, it stores the key in HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Test

 

I am partially able to go around the issue by importing .reg files or adding keys/values in batch or PS using reg.exe with operator /reg:64  For example:

reg import "%~dp0import.reg" /reg:64 /f

reg add "HKLM\SOFTWARE\Test" /reg:64 /f

This is OK when i want to just write keys and values.

 

However when trying to read current registry and create new, or modify existing values i am not able to read/write the registry due to powershell running in 32bit mode and redirected to HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node

For Example installing draftsight that uses the same  license manager client as solidworks. 

If solidworks is installed, license server registry entry is added, if not present. If solidworks is not installed  key and value is created:

 

$flexreg = (Get-ItemProperty "HKLM:\Software\FLEXlm License Manager").SW_D_LICENSE_FILE
Start-Process -Wait -NoNewWindow "msiexec" -ArgumentList "/i","$pwd\DraftSight.msi","/qb","LICENSETYPE=3"
if (!$flexreg) {
    New-Item -Path "HKLM:\Software" -Name "FLEXlm License Manager" -Force
    New-ItemProperty "HKLM:\Software\FLEXlm License Manager" -Name "SW_D_LICENSE_FILE" -Value 'portnr@servername' -PropertyType STRING -Force
} elseif ($flexreg -like '*portnr@servername*') {
Exit
} else  {
    New-ItemProperty "HKLM:\Software\FLEXlm License Manager" -Name "SW_D_LICENSE_FILE" -Value $flexreg';portnr@servername' -PropertyType STRING -Force
}

 

I was searching the web for few days now and i am not able to find a solution.

 

I have found few articles for using SysNative, but that is not present in Windows 10 anymore

 

I tried to use 64bit powershell to start the program: %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File registry.ps1

Same outcome , powershell is forced to 32 bit mode.

 

I tried to force the path:

 

New-Item -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\ -Name "Test" -Force
New-ItemProperty Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Test\  -Name "testproperty" -Value 'testvalue0000' -PropertyType STRING -Force

 

Which does not even write to HKEY_LOCAL_MACHINE\SOFTWARE\Test or  HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Test.

 

Running the scripts as local admin on the PC works off course.

 

I hope someone can point me to a solution. Thanks in advance for your donated brain power.

 

 

11 Replies
best response confirmed by Ondrej_SK (Copper Contributor)
Solution

Hi,

Please take a look at


Sysnative | Intune | 64 VS 32 Bits | Registry Keys (call4cloud.nl)

 

What happens when you run a script with setting this option to yes instead of no

 

Rudy_Ooms_0-1619435688102.png

 

Hi, thank you for the links, however i have read those articles already.

And as i wrote, SysNative directory is not present Windows 10 anymore.

 

I cannot use a Powershell script as it is not bringing any files for installation an cannot be published for the user to install.

 

However i have tested the script to be run in 64 bit host and it correctly created the key and value.

I cannot use the script as a dependency for a win32 app however.

Hi

I have got one idea, after my lunch i will test it out and let you know

Hi,

You could create something like this and convert it (with the msi) to a intunewin file
Just like i I did with a win32 app to disable the oobe stage (for when you don't use autopilot)
:
https://call4cloud.nl/2020/10/the-curious-cage-of-hiding-the-oobe-stage/

I uploaded the app just a few seconds ago,first I need to spin up a clean windows 10 test vm. I will let you know the outcome. UPDATE 14:05: The registry keys were succefully created. Of course, I skipped the msi part but I this something you could use?
-----
$content = @'
$flexreg = (Get-ItemProperty "HKLM:\Software\FLEXlm License Manager").SW_D_LICENSE_FILE
#Start-Process -Wait -NoNewWindow "msiexec" -ArgumentList "/i","$pwd\DraftSight.msi","/qb","LICENSETYPE=3"
if (!$flexreg) {
New-Item -Path "HKLM:\Software" -Name "FLEXlm License Manager" -Force
New-ItemProperty "HKLM:\Software\FLEXlm License Manager" -Name "SW_D_LICENSE_FILE" -Value 'portnr@servername' -PropertyType STRING -Force
} elseif ($flexreg -like '*portnr@servername*') {
Exit
} else {
New-ItemProperty "HKLM:\Software\FLEXlm License Manager" -Name "SW_D_LICENSE_FILE" -Value $flexreg';portnr@servername' -PropertyType STRING -Force
}
'@

Out-File -FilePath $(Join-Path $env:ProgramData CustomScripts\testreg.ps1) -Encoding unicode -Force -InputObject $content -Confirm:$false

# register script as scheduled task
$Time = New-ScheduledTaskTrigger -AtLogOn
$User = "SYSTEM"
$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ex bypass -file `"C:\ProgramData\CustomScripts\testreg.ps1`" -Verb RunAs"
Register-ScheduledTask -TaskName "testreg" -Trigger $Time -User $User -Action $Action -Force
Start-ScheduledTask -TaskName "testreg"

Woah. So you pack the script to a file, register a Scheduled task and execute it so that a new instance is executed in 64 bit. Is task scheduler using %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe due to system default?

This is quite a stretch to get it working. Registering a scheduled task for each powershell installation that needs to work with registry and cleanup the scheduled task (with detection script for example)
Don't take me wrong you seem to have a workaround, but its quite complicated.

But you gave me an idea. i have to test to call %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe from a batch file with start command.
Hi

Yes it's a little bit complicated... I just used this script which I had to control the oobe settings before the user logged on. Maybe it could be a little bit stripped down but it does the job :) . The schedule part was meant for scheduling :)
If the schedule part is only for scheduling, i do not understand how can i use it without it, to go around the problem of starting powershell in 64 bit mode to access the registry. Could you please explain?
Hi,

I guess my reply is/was missing the last part.

The schedule part was meant for scheduling :). But you don't need to schedule it to run at each user login, just let it run once and delete it after the task was run.

Unregister-ScheduledTask -TaskName testreg -Confirm:$false
OK, so i understood correctly.
Thank you for your help. I will continue to search for a more native resolution for this issue. Could be i need to fall back to your solution :)

@Rudy_Ooms_MVP So once Rudy pointed out that the sysnative is only accessible from 32bit consoles, i have tested and voila, the script is working like a charm! I have used a separate one line script to start the install script:

Start-Process -FilePath "$ENV:WINDIR\SysNative\WindowsPowershell\v1.0\PowerShell.exe" -ArgumentList "-File `"$($PSScriptRoot)\registry.ps1`" " -Wait -NoNewWindow

Happy ending of a thread :D

You can directly use this in Intune command line to launch powershell as x64:
%windir%\SysNative\WindowsPowershell\v1.0\PowerShell.exe -NoProfile -ExecutionPolicy ByPass -File .\MyScript.ps1
1 best response

Accepted Solutions
best response confirmed by Ondrej_SK (Copper Contributor)
Solution

Hi,

Please take a look at


Sysnative | Intune | 64 VS 32 Bits | Registry Keys (call4cloud.nl)

 

What happens when you run a script with setting this option to yes instead of no

 

Rudy_Ooms_0-1619435688102.png

 

View solution in original post