首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Powershell脚本的行为很奇怪(调用操作符与调用-表达式)

Powershell脚本的行为很奇怪(调用操作符与调用-表达式)
EN

Stack Overflow用户
提问于 2022-03-25 16:33:20
回答 1查看 307关注 0票数 1

我的一个powershell脚本表现得很奇怪。当命令与调用操作符(&)一起执行时,它将按照预期的方式工作。因为我不喜欢快捷方式,而且操作符也不容易阅读,所以我想用调用表达式代替。无论如何,这对我来说并不是什么问题,但我很想知道这是Powershell中的一个bug,还是我做错了什么。但是,这会导致错误:Invoke-表达式:没有找到与参数名称"file“匹配的参数。D:\Job_Monday.PS1:10字符:34个

  • 调用-表达式-Command $cmd1 -file $fil1 -wake $nas1 -close
    • Microsoft.PowerShell.Commands.InvokeExpressionCommand : CategoryInfo : InvalidArgument:(:)调用-表达式,ParameterBindingException + FullyQualifiedErrorId : NamedParameterNotFound,

剧本:

代码语言:javascript
复制
`   [String] $cmd1 = "C:\Tools\WOL2\WOL2.exe"
`   [String] $fil1 = "C:\Tools\WOL2\WOL2.profile4.xml"
`   [String] $nas1 = "SyBackup"
`   # wake-on-LAN with call operator
`   # & $cmd1 -file $fil1 -wake $nas1 -close
`   # Wake-On-LAN with Invoke expression
`   Invoke-Expression -command $cmd1 -file $fil1 -wake $nas1 -close
代码语言:javascript
复制
Many greetings from Aachen
inl1ner
EN

回答 1

Stack Overflow用户

发布于 2022-03-25 17:30:14

首先,强制性的警告

  • 由于Invoke-Expression (**iex**)固有的安全风险,通常应该避免使用,并将其作为最后的手段使用。通常都有更好的替代方案。如果真的没有其他选择,那么只在您自己提供或完全信任的输入上使用它--请参阅这个答案

Invoke-Expression只接受一个包含任意PowerShell代码的字符串,因此它与&无关,呼叫操作员接受多个参数,第一个参数是命令名或路径,其余的参数都传递给该命令。

因此,& 只是直接执行命令的语法变体,仅在以下两种情况下才需要:

  • 如果命令名(可执行路径)被引用或包含变量引用,则由于语法原因,必须使用& (呼叫操作员)调用它;有关详细信息,请参阅这个答案
  • 如果您正在调用的命令是以脚本块 ({ ... })的形式提供的。

例如,以下语句是等价的:

代码语言:javascript
复制
# Direct execution
C:\Tools\WOL2\WOL2.exe -command $cmd1 -file $fil1 -wake $nas1 -close

# Direct execution, of necessity via & in this case,
# because the executable path is *quoted*
& "C:\Tools\WOL2\WOL2.exe" -command $cmd1 -file $fil1 -wake $nas1 -close

# You can also use Invoke-Command, but that is *rarely useful*
# in *local* calls; also, inside the script block the rules re
# the & operator still apply.
Invoke-Command { & "C:\Tools\WOL2\WOL2.exe" -command $cmd1 -file $fil1 -wake $nas1 -close }

Direct 是目前为止最典型的调用形式,因为它保证:

  • 同步执行(用于控制台应用程序)
  • 在当前控制台中
  • 将被调用的命令的输出流直接连接到当前会话,从而可以捕获、中继或重定向/抑制输出。

相比之下,启动过程 仅在 exceptional 中才被调用。

  • 如果您想在新的控制台窗口中运行(默认情况下),默认情况下异步运行(除非通过-Wait)
  • 如果希望同步运行GUI应用程序,则使用-Wait (直接执行GUI应用程序异步启动)。
  • 如果您需要启动一个提升的命令(作为管理员),使用-Verb RunAs
  • 如果您需要以不同用户的身份使用-Credential启动命令

请注意,没有直接的方法来捕获Start-Process-launched进程的输出--您唯一的选择是使用-RedirectStandardOutput-RedirectStandardError重定向到文件。

请注意,还有Invoke-Command cmdlet,您可以将其看作等同于&操作符的cmdlet;但是:

  • 它在本地调用中很少有用;它的主要目的是远程执行命令--有关详细信息,请参阅这个答案
  • 从语法上讲,它需要传递一个封装在脚本块中的命令,如上面所示,在脚本块中应用通常的语法规则,因此可能也需要&
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71620269

复制
相关文章

相似问题

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