首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么命令在Windows而不是PowerShell中工作?

为什么命令在Windows而不是PowerShell中工作?
EN

Stack Overflow用户
提问于 2017-11-10 04:29:46
回答 1查看 3.7K关注 0票数 1

我有一个脚本,可以将可执行文件和.ps1保存到远程计算机列表中。然后在每台计算机上运行可执行文件。我必须用.ps1调用可执行文件,因为它是在静默运行时设置的。

我注意到,我的一个命令从命令行快速运行,但似乎挂在我的脚本中。有什么原因会这样吗?

该命令是:

代码语言:javascript
运行
复制
psexec -s @C:\myscript\computers.txt cmd /c "Powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass && PowerShell -noninteractive -file "C:\Install.ps1""

这是我的整个剧本:

代码语言:javascript
运行
复制
cls #clear screen

function CopyFiles {

    # Get .exe from source and place at destination workstation
    $source2="\\mainserver\program.exe"
    $destination2="\\$line\c$\program.exe"           # place .exe on C:\ directory of worstation
    Copy-Item -Recurse -Filter *.* -path $source2 -destination $destination2 -Force

    # Get .bat from source and place at destination workstation
    $source3="\\fileserver\Install.ps1"
    $destination3="\\$line\c$\Install.ps1"  # place .bat on C:\ directory of worstation
    Copy-Item -Recurse -Filter *.* -path $source3 -destination $destination3 -Force
}

$a = Get-Content "C:\myscript\computers.txt"
foreach($line in $a)
{

  "These options must run in numbered order."
  " "
  " "
  "1. Copy installer to remote computer(s)."
  "2. Remove application from remote computer(s)."
  "3. Install application from remote computer(s)."
  "4. Quit."
  " "
  "Type number and press Enter." 
  $UI = Read-Host -Prompt ' '

  If ($UI -eq 1) {
    CopyFiles
  } ELSEIF ($UI -eq 2) {
  psexec @C:\myscript\computers.txt -c "\\fileserver\Remove.bat"
  } ELSEIF ($UI -eq 3) {
  psexec -s @C:\myscript\computers.txt cmd /c "Powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass && PowerShell -noninteractive -file "C:\Install.ps1""
  } ELSEIF ($UI -eq 4) {
  "Good Bye"
  }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-10 04:58:00

根本原因是PowerShell有一个更标准的规则来解析参数。与cmd不同。在PowerShell中,如果参数以引号开头,那么它也将以引号结尾。但是,在cmd中,如果在引号之后没有分隔符(如空格或选项卡),则参数将继续。这意味着"powershell someargs "another""是PowerShell中的两个参数,但在cmd中只有一个参数。尝试回显来自PowerShell的命令,您将立即看到这一点。

代码语言:javascript
运行
复制
PS D:\> echo psexec -s @C:\myscript\computers.txt cmd /c "Powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass && PowerShell -noninteractive -file "C:\Install.ps1""
psexec
-s
@C:\myscript\computers.txt
cmd
/c
Powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass && PowerShell -noninteractive -file
C:\Install.ps1

C:\Install.ps1被拆分为不同的参数,与cmd不同,在cmd中,它被识别为一个参数:

代码语言:javascript
运行
复制
D:\>type testparam.bat
@echo off
:loop
if [%1]==[] exit /b
echo [%1]
shift
goto :loop

D:\>testparam.bat psexec -s @C:\myscript\computers.txt cmd /c "ps -ExecutionPolicy Bypass AND ps -noninteractive -file "C:\Install.txt""
[psexec]
[-s]
[@C:\myscript\computers.txt]
[cmd]
[/c]
["ps -ExecutionPolicy Bypass AND ps -noninteractive -file "C:\Install.txt""]

如您所见,中间引号不是嵌套引号,而是保留给命令,然后cmd /c将有另一个奇怪的行为:去掉第一个和最后一个引号,然后将其余的内容作为一个命令运行。

PowerShell也是带双引号,但在传递给命令之前,它仅是每个参数中的外部一个。

现在,要修复必须在参数中包含双引号,请使用以下两种方法之一

代码语言:javascript
运行
复制
psexec -s @C:\myscript\computers.txt cmd /c "Powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass && PowerShell -noninteractive -file ""C:\Install.ps1"""
psexec -s @C:\myscript\computers.txt cmd /c "Powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass && PowerShell -noninteractive -file `"C:\Install.ps1`""
psexec -s @C:\myscript\computers.txt cmd /c '"Powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass && PowerShell -noninteractive -file "C:\Install.ps1"'
psexec -s @C:\myscript\computers.txt cmd /c --% "Powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass && PowerShell -noninteractive -file "C:\Install.ps1""

或者,如果文件路径没有任何空格,您可以简单地删除它们,这将在cmd和PowerShell中运行。

代码语言:javascript
运行
复制
psexec -s @C:\myscript\computers.txt cmd /c "Powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass && PowerShell -noninteractive -file C:\Install.ps1"

实际上,如果路径包含像"C:\some dir\Install.ps1"这样的空格,那么您的命令在cmd和PowerShell中都会失败,因为现在cmd还将空格后的部分拆分为一个新的参数。试试这个看看

代码语言:javascript
运行
复制
psexec -s @C:\myscript\computers.txt cmd /c "Powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass && PowerShell -noninteractive -file "C:\some dir\Install.ps1""
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47215705

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档