PowerShell script with admin rights doesn't modify registry entries when executed through Start-Process
I have a PowerShell script that modifies registry entries related to autologin settings. When I execute the script directly from an elevated PowerShell session, the registry entries are modified successfully. However, when I create a temporary file and try to execute it using Start-Process within the ExecuteProcessNativeWaitOnExit function, the script runs with admin rights but fails to modify the registry entries.
Here's the relevant code:
# The function that executes the temporary file, takes the path to the file as an argument.
function ExecuteProcessNativeWaitOnExit($strScriptPath) {
$procInfo = New-Object System.Diagnostics.ProcessStartInfo
$procInfo.FileName = "powershell.exe"
$procInfo.Arguments = "-File `"$strScriptPath`""
# Hide the process window
#$procInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden
$proc = [System.Diagnostics.Process]::Start($procInfo)
# Wait for the process to exit
$proc.WaitForExit()
return $proc.ExitCode
}
# The content of the temporary file
Set-Location -Path 'C:\Users\ASM_Admin\Desktop\V23.x SIPLACE_Configurator_Win10_PS-Script\ConfigSiplaceWin10'
Start-Process powershell .\set_operator_autologin_station.ps1 -Verb RunAs > 'C:\Users\ASM_AD~1\AppData\Local\Temp\s4jq4pdp.4rt.outputfile' 2>&1
$LASTEXITCODE | Out-File -FilePath 'C:\Users\ASM_AD~1\AppData\Local\Temp\c5zk24o2.d05.ErrorLevelFile'
# The content of set_operator_autologin_station.ps1:
$WinlogonPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\"
try {
Set-ItemProperty -Path $WinlogonPath -Name "DefaultUserName" -Value "Operator"
Set-ItemProperty -Path $WinlogonPath -Name "AutoAdminLogon" -Value "1"
Set-ItemProperty -Path $WinlogonPath -Name "DefaultPassword" -Value "operator"
Write-Host "Autologin for Operator is generated"
} catch {
Write-Host "Autologin for Operator can't be generated"
}
read-host "Press enter to continue ..."
# If I open PowerShell with admin rights and execute set_operator_autologin_station.ps1, everything works correctly. The registry entries are changed and everything is fine.
# However, when I create the temporary file and try to execute it with ExecuteProcessNativeWaitOnExit, it shows Autologin for Operator is generated, which means it did not catch an error, but the registry entries are not changed. What could be the problem??
I have verified that the temporary file runs with admin rights, as it displays the expected output "Autologin for Operator is generated." However, the registry entries specified in set_operator_autologin_station.ps1 are not modified.
I would greatly appreciate any insights into why the registry modifications are not taking effect when executing the script through Start-Process within the ExecuteProcessNativeWaitOnExit function. Are there any additional considerations or changes needed to ensure the script successfully modifies the registry entries?
Thank you in advance for your help and suggestions!
Since you're running Windows PowerShell, this will predictably fail, because the elevated
powershell.exeprocess will look for the your*.ps1file inC:\Windows\System32, given that is the working directory it defaults to. (Fortunately, PowerShell (Core) 7+ now preserves the caller's working directory).Applying redirections to
Start-Processis pointless, because it produces no output. (Adding-PassThruwould make it output aSystem.Diagnostics.Processinstance describing the launched process, not the launched process' own output.)Start-Processnever sets the automatic$LASTEXITCODEvariable.To get the exit code of a process launched with
Start-Process, add-PassThru, and then query the returnedSystem.Diagnostics.Processinstance's.ExitCodeproperty - assuming you have first waited for the process to terminate, either by also passing-Waitto theStart-Processcall or by calling.WaitForExit()on theSystem.Diagnostics.Process.Therefore, rewrite your temporary script as follows:
Note:
The full script path is passed to
powershell.exe, without an attempt to set the working directory (your target script doesn't seem to rely on any specific working directory).`"...`"), and invoked via&, the call operator.-Waitand-PassThruare used to makeStart-Processwait for the elevated process to exit and to output aSystem.Diagnostics.Processinstance describing it, captured in variable$piCapturing (combined) output from the elevated target script is performed as part of the
powershell.execommand (*> ...), which happens to be only way for a non-elevated process to capture an elevated process' stdout and stderr output --RedirectStandardOutand-RedirectStandardErrordo not work with-Verb RunAs(and fundamentally wouldn't allow capturing the combination of these streams).$pi.ExitCodecontains the elevated process' exit code.