Search code examples
c#powershellwindows-servicesregistrylocal-system-account

Setting Registry from windows service does not work


I am setting or reading reg key from a windows services which runs as local system. But when I read or set the values in the Registry Editor they are not the same as when i read and set them from the windows services.

If I execute the following command in powershell from the windows services or when i am logged in as a user the results differ as well. Why? Is there a different LocalMachine for a LocalSystem account?

$DefaultUserName = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "DefaultUserName").DefaultUserName
Write-Host $DefaultUserName 

I am using the following c# lines to execute the powershell script from the windows service:

var process = new Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = @"C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe";
process.StartInfo.Arguments = "\"&'" + cacheFile + "'\"";
process.StartInfo.Verb = "runas";
process.Start();

Solution

  • You need to be careful of bitness. On 64-bit Windows, 32-bit applications run using the 'Windows on Windows' subsystem, which by default uses different filesystem paths and registry paths. You are executing powershell from the SysWOW64 folder, which means you are executing the 32-bit version, which will use the 32-bit registry hive.

    If you open up regedit, the 32-bit hive for your registry key is: Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Winlogon. I suspect you are getting/setting this value.

    Please refer to How to access a 64Bit Registry key using 32Bit Powershell without Redirection to WOW6432Node for strategies you can take, including using the Sysnative rather than SysWOW64 version of powershell.

    If you need to support 32-bit and 64-bit operating systems, you will need to make sure you are using the appropriate technique.