如何获取PowerShell脚本的原生命令行(特权提升场景下一致调用)
获取PowerShell脚本的完整原始调用命令行
要拿到启动当前脚本的完整未处理的原生命令行,从而在提权后以完全一致的方式重新调用,这里有几个可靠的实践方法:
方法1:利用$MyInvocation内置变量(简单直接)
脚本内部的$MyInvocation对象保存了调用上下文的关键信息,能快速获取参数部分:
# 拼接出包含PowerShell启动程序的完整命令行 $originalCommandLine = "powershell.exe $($MyInvocation.Line)" # 若是PowerShell 7+(pwsh.exe启动),替换为: # $originalCommandLine = "pwsh.exe $($MyInvocation.Line)"
注意:
$MyInvocation.Line返回的是调用脚本时的参数部分(不含powershell.exe本身),手动补上启动程序名即可还原完整命令。这个方法适合直接由用户启动的脚本场景,嵌套调用时可能会有偏差。
方法2:通过WMI/CIM读取进程原始命令行(最可靠)
如果需要完全还原系统层面记录的启动命令(包含所有原始引号、空格和参数),可以直接读取当前PowerShell进程的底层信息:
# 获取当前进程ID,再查询对应进程的命令行 $currentPid = $PID $processDetails = Get-CimInstance Win32_Process -Filter "ProcessId = $currentPid" $originalCommandLine = $processDetails.CommandLine
这种方式拿到的是系统内核记录的原始启动命令,完全没有经过PowerShell的处理,是最精确的还原方式。
提权后原样调用脚本示例
拿到原始命令行后,用以下方式提权重新执行:
# 基于WMI获取的完整命令拆分执行(自动适配powershell/pwsh) $processDetails = Get-CimInstance Win32_Process -Filter "ProcessId = $PID" $exePath = $processDetails.ExecutablePath # 从完整命令行中剥离出启动程序后的参数部分 $arguments = $processDetails.CommandLine -replace "^`"$([regex]::Escape($exePath))`"\s*", "" # 提权启动 Start-Process -FilePath $exePath -ArgumentList $arguments -Verb RunAs
关键注意点
- 脚本路径包含空格时,原始命令行的引号会被完整保留,确保路径解析不会出错。
- PowerShell 7+环境下无需修改逻辑,系统会自动识别
pwsh.exe作为启动程序。
内容的提问来源于stack exchange,提问作者Alexander Martin
相关产品推荐
相关产品推荐

