【问题标题】:How to Run Long Powershell script from Windows Command Prompt (CMD)如何从 Windows 命令提示符 (CMD) 运行长 Powershell 脚本
【发布时间】:2018-05-10 23:11:42
【问题描述】:

我尝试从命令提示符启动一个名为“long name here.ps1”的长 powershell 脚本。但我也试图确保它在 powershell 中作为管理员命令运行。我在 powershell 中设置了所有执行策略,因此我使用了ss64 set-executionpolicy command guide for powershell 来让 powershell 工作。但我正在尝试使用来自another stackoverflow question 的解决方案,该解决方案涉及以管理员身份运行命令。我正在运行一个批处理脚本,该脚本需要以管理员身份执行 powershell 脚本 (.ps1),我不介意 UAC 提示用户还是输入密码。我目前正在使用以下命令:

powershell.exe -command "&{ Start-Process powershell -ArgumentList '-noprofile -file "C:\long name here.ps1"' -verb RunAs}"

我在底部的https://ss64.com/ps/powershell.html 找到了这个命令,那里有关于如何以管理员身份运行powershell 命令的详细信息。该代码的问题在于我的 powershell 脚本 1. 有参数,而 2. 有一个长名称。我已经尝试了这个命令的许多不同的迭代,但都没有成功,下面列出了那些不起作用的:

powershell.exe -command "&{ Start-Process powershell -ArgumentList '-noprofile -file C:\long` name` here.ps1' -verb RunAs}"

powershell.exe -command "&{ Start-Process powershell -ArgumentList '-noprofile -file:"C:\long name here.ps1' -verb RunAs}"

另外,我完全不知道如何将参数发送到实际脚本。

【问题讨论】:

  • This link 可能是相关的
  • 我没有达到我的命令的最大长度。问题是 powershell 的 -file 选项。它无法识别我的文件名,因此根本不运行它。
  • 我知道任务计划程序有 256 个字符的限制,但我通过以与 OP 尝试运行他的文件相同的方式将 291 个字符参数传递给 PowerShell 脚本来测试它,它工作正常。如果有限制,那将是不合理的。

标签: powershell cmd command-prompt command-line-arguments windows-nt


【解决方案1】:

如果我正确阅读了您的问题 - powershell 不会找到该文件,因为它在遇到空格时停止读取路径名?

给定的示例here 指定;以管理员身份从命令提示符运行的 powershell 命令应具有以下语法:

powershell.exe -noprofile -command "&{ start-process powershell -ArgumentList '-noprofile -file MyScript.ps1' -verb RunAs}"

实现您的目标的几种方法。但最简单的方法是使用 ` 字符转义引号。所以类似于;

powershell.exe -noprofile -command "&{ start-process powershell -ArgumentList '-noprofile -file `"C:\long file name.ps1`"' -verb RunAs}"

也可能值得查看其他答案here

【讨论】:

  • 你为什么使用带有脚本块的调用操作符?
  • 使用转义文件名运行示例命令仍会导致命令提示符在 -file `" 之后结束对“-command”行的解析。我也尝试过该方法,命令提示符只看到 @ 987654325@
  • 可能是由于命令提示符修剪掉了双引号,因为它将它们解释为字符串的起点和终点。看我的回答。
【解决方案2】:

使用免费的第三方实用程序

如果允许使用免费的第三方可执行文件,您可以使用我编写的名为 elevate32.exe(32 位)和 elevate64.exe(64 位)的简短工具以管理员身份使用 @987654324 启动 powershell.exe @ 参数和要使用的脚本参数:

elevate64 -- powershell.exe -File "<path>\<long script name>.ps1" -Arg "<long script argument>"

您可以从www.westmesatech.com 获得该工具(受版权保护的免费软件,可在任何地方免费使用,无需安装)。

使用 WSH 脚本

如果您不能使用外部可执行文件,您也可以使用 Windows 脚本宿主 (WSH) 脚本 @ 987654327@:

var args = WScript.Arguments;
if ( args.Length >= 1 ) {
    var exec = args.Item(0);
    var cmdLine = "";
    for (var i = 1; i < WScript.Arguments.Length; i++ ) {
      cmdLine += cmdLine == "" ? '"' + args.Item(i) + '"' : ' "' + args.Item(i) + '"';
    }
    var shellApp = new ActiveXObject("Shell.Application");
    shellApp.ShellExecute(exec, cmdLine, "", "runas");
}

你可以这样调用:

wscript.exe "d:\path\elevate.js" powershell.exe -File "C:\long path\script name.ps1" "long script argument"

自行提升您的 PowerShell 脚本

另一种选择是编写一个自我提升的 PowerShell 脚本。您可以在脚本中检查海拔;如果没有提升,它可以启动自身提升并运行您需要的任何命令。示例:

$isElevated = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

if ( -not $isElevated ) {
  Start-Process powershell.exe "-File",('"{0}"' -f $MyInvocation.MyCommand.Path) -Verb RunAs
  exit
}

& "d:\long path name\script name.ps1" "Long Argument 1" "Long Argument 2"

【讨论】:

  • 我不理解反对意见,但我不想使用第 3 方工具来执行此操作,因为我希望此批处理文件可移植。
  • 您可以忽略任何反对意见,因为许多人都非常成功地使用了免费软件工具。但无论如何,我用 WSH 脚本解决方案和 PowerShell 自提升解决方案更新了我的答案。
【解决方案3】:

当您使用PowerShell.exe -Command 时,您不需要使用引号。例如,您可以运行以下命令:

PowerShell.exe -Command Get-Service 'wuauserv'

-Command 之后的所有内容都被解释为命令。另请注意,CMD 中的双引号需要用反斜杠转义。因此:

powershell.exe -Command Start-Process PowerShell -ArgumentList '-NoProfile -File \"C:\long name here.ps1\"' -Verb RunAs

如果你的文件有参数:

powershell.exe -Command Start-Process PowerShell -ArgumentList '-NoProfile -File \"C:\long name here.ps1\" \"Arg1\" \"Arg2\"' -Verb RunAs

【讨论】:

  • 为我工作。我设法使用此处描述的方法传入 2 个参数。
  • 比尔,如果你不逃避它们,CMD 会消耗它们。在您传递给 PowerShell 的参数中的任何地方都是如此,
  • 此技术不适用于 PowerShell。从我粗略的调查来看,这似乎是因为 powershell.exe 当前使用的是CommandLineToArgvW。由于这种复杂性,除非您确定解析器不会误解您的意图,否则我不推荐此解决方案。
  • 无论它是否在 PowerShell 中工作都无关紧要,OP 明确声明他们是从命令提示符运行它,因此这就是我们需要对其进行格式化的原因,并且如果您希望将引号解释为发送到 PowerShell 的参数需要转义。
  • 是的,我的意思是这只能“有效”,因为 PowerShell 使用该 Win32 API。 (如果他们决定更改为不同的 API 或以不同的方式解析,此解决方案可能会中断。)
猜你喜欢
  • 1970-01-01
  • 2021-09-13
  • 2013-08-29
  • 2018-03-14
  • 1970-01-01
  • 2012-05-02
  • 1970-01-01
  • 2018-05-05
  • 1970-01-01
相关资源
最近更新 更多