繁体   English   中英

如何从脚本中提升 Powershell 脚本

[英]How to elevate a Powershell script from within a script

我是 Powershell 的新手,但在很多方面都非常喜欢它。 由于某些原因,我创建了一个脚本,该脚本从硬盘驱动器上的文件加载一组本地管理员凭据,并创建一个 PSCredential 对象 $MyCred。

我想使用 $MyCred 来提升一个单独的脚本(对注册表进行一些更改以打开 RDP 连接)。 我尝试将 $MyCred 传递给 Start-Process cmdlet:

Start-Process Powershell.exe -Credential $MyCredential

然后我收到以下错误:

Start-Process :此命令无法运行,因为错误:目录名称无效。

如果我使用 -credential 和一个空变量运行 Start-Process,系统会提示我输入用户名和密码。 当我输入它们时,我会得到一个提升的 powershell 提示,没有任何问题,并且能够在注册表中对我的测试系统进行更改。

我已经验证了 $myCred 的内容,并且它正确存储了 U/N 和 P/W(与我手动输入的内容相同)。 使用 New-PSSEssion 之类的

New-PSSession -Credential $MyCredential

返回访问被拒绝,我读过的很多系统默认情况下也禁用了访问。

在理想的世界中,代码如下所示:

Start-Process Powershell.exe -Credential $MyCredential -File C:\\MyScript.ps1

这应该启动一个提升的 powershell,它在第二个脚本中运行一些命令,然后终止。 我在这里想念什么?

感谢我能得到的所有帮助,谢谢! 我可能是完全显而易见的。


背景是,我们有一些我们自己无法使用的计算机,也无法通过 RDP 访问。 我们在站点上确实有可以为我们运行脚本的用户。 但重要的是他们没有获得本地管理员密码。 因此,我们想创建一个脚本来读取加密的密码文件,生成本地管理员 PSCredential 对象,并将其传递给一个脚本,该脚本进行必要的注册表更改以允许 RDP 访问。

有很多关于这个主题的用例文章。 使用“PowerShell 自提升脚本”进行快速网络搜索将显示它们。 甚至直接来自 MS

一个自提升的 PowerShell 脚本

# 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"
    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
    exit
    }

 # Run your code that needs to be elevated here
 Write-Host -NoNewLine "Press any key to continue..."
 $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

此代码来自有用的指南: 如何自我提升 PowerShell 脚本

它会检查当前脚本的安全性,如果需要提升,脚本将以管理员身份重新启动。 如果启用了 UAC,它会提示您确认。 重新启动后,它将拥有必要的访问权限并在检查后运行代码。

# Self-elevate the script if required
if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
 if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
  $CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments
  Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine
  Exit
 }
}

# Remainder of script here

更新:我发现这不会在提升后维护当前的工作目录。

您在这里缺少 NoExit 参数。

Start-Process -Filepath "Powershell.exe" -ArgumentList "-NoExit -File "C:\myscript.ps1" -Credential $MyCredential 

这只是对@mbomb007 答案的增强,由网络上的其他示例和我自己努力传递所有<\/em>原始参数(包括命名参数和位置参数)拼凑而成。 请注意,添加的函数不会对参数值中可能使用的特殊字符进行编码。 大多数帖子奇怪地没有传递论点。

function Pass-Parameters {
    Param ([hashtable]$NamedParameters)
    return ($NamedParameters.GetEnumerator()|%{"-$($_.Key) `"$($_.Value)`""}) -join " "
}

# Self-elevate the script if required
if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
 if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
  $CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + (Pass-Parameters $MyInvocation.BoundParameters) + " " + $MyInvocation.UnboundArguments
  Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine
  Exit
 }
}

# Remainder of script here

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM