我试图在Powershell中复制这个Self-Elevating脚本,但是作为一个函数而不是整个脚本,以便分解代码以获得更好的流程。原始代码可以在这里找到。
http://blogs.msdn.com/b/virtual_pc_guy/archive/2010/09/23/a-self-elevating-powershell-script.aspx
但是,当我将相同的代码重写为函数时,它会出错。知道是什么导致了这个错误吗?这是新的错误代码。
function SelfElevation
{
# Get the ID and security principal of the current user account
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal ($myWindowsID)
# Get the security principal for the Administrator role
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
# Check to see if we are currently running "as Administrator"
if ($myWindowsPrincipal.IsInRole($adminRole))
{
# We are running "as Administrator" - so change the title and background color to indicate this
$Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
$Host.UI.RawUI.BackgroundColor = "DarkBlue"
$Host.UI.RawUI.ForegroundColor = "White"
clear-host
}
else
{
# We are not running "as Administrator" - so relaunch as administrator
# Create a new process object that starts PowerShell
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
# Specify the current script path and name as a parameter
$newProcess.Arguments = $myInvocation.MyCommand.Definition;
# Indicate that the process should be elevated
$newProcess.Verb = "runas";
# Start the new process
[System.Diagnostics.Process]::Start($newProcess)
# Exit from the current, unelevated, process
Stop-Process -Id $PID
}
}
# We call the self elevation here
SelfElevation
# Run your code that needs to be elevated here
Write-Host -NoNewLine "Press any key to continue..."
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
这段代码工作正常,因为我将其截断,直到它命中Start $ newProcess的部分,它似乎不喜欢在一个函数中执行新进程。但是,为什么呢?
提前感谢您的时间!
答案 0 :(得分:3)
您的脚本所采用的参数可能与Powershell.exe所采用的略有不同。试试这种方法:
[string[]]$argList = @('-NoProfile', '-NoExit', '-File', $MyInvocation.MyCommand.Path)
$argList += $MyInvocation.BoundParameters.GetEnumerator() | Foreach {"-$($_.Key)", "$($_.Value)"}
$argList += $MyInvocation.UnboundArguments
Start-Process PowerShell.exe -Verb Runas -WorkingDirectory $pwd -ArgumentList $argList
答案 1 :(得分:1)
修复"路径中的空格"问题以及用于将新PowerShell进程路径设置为实际脚本位置的其他代码 脚本位于映射网络驱动器时的另一个错误修复
#region Self-Elevating
Set-Location ( Get-Item $script:MyInvocation.MyCommand.Path ).Directory
$myWindowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal = new-object System.Security.Principal.WindowsPrincipal( $myWindowsID )
$adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator
if ( !$myWindowsPrincipal.IsInRole( $adminRole )) {
# This fixes error wen script is located at mapped network drive
$private:scriptFullPath = $script:MyInvocation.MyCommand.Path
if ( $scriptFullPath.Contains([io.path]::VolumeSeparatorChar )) { # check for a drive letter
$private:psDrive = Get-PSDrive -Name $scriptFullPath.Substring(0,1) -PSProvider 'FileSystem'
if ( $psDrive.DisplayRoot ) { # check if it's a mapped network drive
$scriptFullPath = $scriptFullPath.Replace( $psdrive.Name + [io.path]::VolumeSeparatorChar, $psDrive.DisplayRoot )
}
}
[string[]]$argList = @( '-NoLogo', '-NoProfile', '-NoExit', '-File', "`"$scriptFullPath`"" )
$argList += $MyInvocation.BoundParameters.GetEnumerator() | % { "-$( $_.Key )", "$( $_.Value )" }
$argList += $MyInvocation.UnboundArguments
Start-Process PowerShell.exe -Verb Runas -WorkingDirectory $PWD -ArgumentList $argList -PassThru
Stop-Process $PID
}
#endregion
感谢基思希尔和兰迪在马林