求PowerShell自动检查提权前缀脚本,验证现有实现是否最优(域环境)
域环境映射驱动器下的PowerShell自动提权前缀脚本
我需要一段可插入PowerShell命令前的前缀脚本,实现自动检查是否已获得管理员权限,若未获得则请求提升权限并继续执行脚本。执行环境为加入域的计算机,通过映射驱动器运行PowerShell脚本。已找到一段可用脚本,但不确定是否为最优实现,另外尝试过两段脚本但无效,因对PowerShell了解不足无法排查原因。
可用脚本
这段脚本可实现提权并保留当前工作目录:
#=================================================================================================== # 以管理员身份运行PowerShell并保留工作目录 if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$pwd'; & '$PSCommandPath';`""; exit; } # 在此处编写你的脚本
无效脚本及问题排查
第一段(批处理调用PowerShell提权)
#======================================================================================================================= # 批文件调用PowerShell并提权: @echo off set scriptFileName=%~n0 set scriptFolderPath=%~dp0 set powershellScriptFileName=%scriptFileName%.ps1 powershell -Command "Start-Process powershell \"-ExecutionPolicy Bypass -NoProfile -NoExit -Command `\"cd \`\"%scriptFolderPath%`\"; & \`\".\%powershellScriptFileName%`\"`\"\" -Verb RunAs"
问题原因:
- 嵌套引号的转义逻辑混乱,导致PowerShell无法正确解析传递的参数。
- 映射驱动器路径在管理员会话中默认不加载,
%scriptFolderPath%若为映射驱动器路径,提权后无法被识别,进而找不到目标脚本。
第二段PowerShell脚本
#======================================================================================================================= If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { #"无管理员权限,将弹出窗口请求管理员权限" $arguments = "& '" + $myinvocation.mycommand.definition + "'" Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments break } #"用户点击确定后,脚本将以管理员权限重新打开" #"在此处编写你的代码"
问题原因:
- 角色判断语法错误:
[Security.Principal.WindowsBuiltInRole] "Administrator"应改为[Security.Principal.WindowsBuiltInRole]::Administrator(用::访问枚举成员)。 - 映射驱动器路径不兼容:
$myinvocation.mycommand.definition返回的映射驱动器路径在管理员会话中无法识别,导致提权后找不到脚本。 - 退出逻辑错误:使用
break而非exit,会导致原非管理员进程残留,可能引发逻辑混乱。
针对域环境映射驱动器的优化版脚本
考虑到域环境中管理员会话默认不加载用户映射驱动器的问题,下面的脚本会自动将映射驱动器路径转换为UNC路径,确保提权后能正常访问脚本和工作目录:
# 检查当前是否拥有管理员权限 $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) $isAdmin = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { # 将脚本路径转换为UNC路径(若为映射驱动器) $scriptPath = $PSCommandPath if ($scriptPath -match '^[A-Z]:\\') { $driveLetter = $scriptPath.Substring(0, 2) $uncProvider = (Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='$driveLetter'").ProviderName if ($uncProvider) { $scriptPath = $scriptPath.Replace($driveLetter, $uncProvider) } } # 将工作目录转换为UNC路径(若为映射驱动器) $workingDir = $pwd.Path if ($workingDir -match '^[A-Z]:\\') { $driveLetter = $workingDir.Substring(0, 2) $uncDir = (Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='$driveLetter'").ProviderName if ($uncDir) { $workingDir = $workingDir.Replace($driveLetter, $uncDir) } } # 启动管理员权限的PowerShell会话并执行脚本 Start-Process powershell.exe -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$workingDir'; & '$scriptPath';`"" exit } # 在此处编写你的脚本逻辑
优化说明:
- 自动转换映射驱动器路径为UNC路径,解决管理员会话无法访问用户映射驱动器的问题。
- 语法规范,逻辑清晰,避免了原脚本中的潜在路径识别问题。
- 使用
exit明确退出原非管理员进程,避免残留。
内容的提问来源于stack exchange,提问作者Joshua
相关产品推荐
相关产品推荐

