如何在PowerShell脚本中获取SYSTEM权限执行RunAsUser模块
问题概述
需要执行一段PowerShell脚本完成两个操作:为当前用户修改GlobalProtect的注册表项,重启需要管理员权限的PanGPS服务。使用RunAsUser模块的Invoke-AsCurrentUser时,本地管理员权限运行报错,错误信息如下:
invoke-ascurrentuser : Not running with correct privilege. You must run this script as system or have the SeDelegateSessionUserImpersonatePrivilege token. At C:\Temp\MoveFromVPN2toVPN.ps1:30 char:1 + invoke-ascurrentuser -scriptblock $scriptblock + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Invoke-AsCurrentUser
已通过psexec.exe -i -s powershell.exe获取SYSTEM权限Shell并成功运行脚本,希望在脚本内以编程方式自动获取SYSTEM权限执行。
解决方案
方法1:通过Windows计划任务自动以SYSTEM权限执行核心逻辑
利用Windows计划任务可指定SYSTEM账户运行的特性,脚本内自动创建临时任务、执行逻辑后清理,无需手动调用psexec:
# 安装必要依赖(确保脚本以管理员权限启动) Install-PackageProvider -Name "NuGet" -RequiredVersion "2.8.5.201" -Force -Confirm:$False Install-Module RunAsUser -Confirm:$False -Force # 定义核心执行逻辑 $coreScriptContent = @' # 修改当前用户GlobalProtect注册表项 Set-ItemProperty -Path "HKCU:\Software\Palo Alto Networks\GlobalProtect\Settings\" -Name LastUrl -Value "vpn.xxx.yyy" # 重启PanGPS服务 Restart-Service -Name PanGPS -Force '@ # 创建临时脚本文件 $tempScriptPath = Join-Path $env:TEMP "GP_VPN_Config.ps1" Set-Content -Path $tempScriptPath -Value $coreScriptContent -Encoding UTF8 # 配置计划任务参数 $taskName = "GP_VPN_Config_Temp_Task" $taskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$tempScriptPath`"" $taskPrincipal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest $taskSettings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -Hidden # 注册并启动任务 Register-ScheduledTask -TaskName $taskName -Action $taskAction -Principal $taskPrincipal -Settings $taskSettings -Force | Out-Null Start-ScheduledTask -TaskName $taskName # 等待任务执行完成(可根据实际情况调整等待时长) Start-Sleep -Seconds 5 # 清理临时资源 Unregister-ScheduledTask -TaskName $taskName -Confirm:$False Remove-Item -Path $tempScriptPath -Force
方法2:脚本自启动为SYSTEM权限(依赖PsExec)
如果坚持使用RunAsUser模块,可在脚本开头判断当前权限,若不是SYSTEM则调用PsExec重新启动自身,后续逻辑将在SYSTEM权限下执行:
# 检查当前是否为SYSTEM账户 $currentIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name if ($currentIdentity -ne "NT AUTHORITY\SYSTEM") { # 获取当前脚本路径,若为交互式运行则生成临时脚本 $scriptPath = $MyInvocation.MyCommand.Path if (-not $scriptPath) { $scriptPath = Join-Path $env:TEMP "temp_gp_script.ps1" Get-Content $MyInvocation.MyCommand.Definition | Set-Content $scriptPath -Encoding UTF8 } # 调用PsExec以SYSTEM权限启动脚本(确保PsExec在PATH中或指定全路径) Start-Process -FilePath "psexec.exe" -ArgumentList "-s -i powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`"" -Wait -NoNewWindow exit } # 原脚本逻辑(已在SYSTEM权限下执行) Install-PackageProvider -Name "NuGet" -RequiredVersion "2.8.5.201" -Force -Confirm:$False Install-Module RunAsUser -Confirm:$False -Force $scriptblock = { Set-ItemProperty -Path "HKCU:\Software\Palo Alto Networks\GlobalProtect\Settings\" -Name LastUrl -Value "vpn.xxx.yyy" } Invoke-AsCurrentUser -scriptblock $scriptblock Restart-Service -Name PanGPS -Force
注意事项
- 方法1无需额外工具依赖,是更推荐的原生方案;
- 方法2需要PsExec工具,需确保脚本能访问到PsExec;
- 两种方法都需要脚本以管理员权限启动,否则无法创建计划任务或调用PsExec。
内容的提问来源于stack exchange,提问作者YaKs
相关产品推荐
相关产品推荐

