windows 将变量字符串命令传递给powershell -命令

e0bqpujr  于 2022-12-14  发布在  Windows
关注(0)|答案(2)|浏览(172)

我需要运行这个命令,它是从另一个脚本中读取的。

$command = "$arr = @($input)
$arr.count
Write-Host $arr[0]"

"Classical Music for When You are on a Deadline." | & cmd /C powershell -Command {$command}

所以我通过管道得到一些东西,然后在我的字符串命令中使用它。代码不起作用,因为$command没有扩展到调用内部的字符串,因此在启动的powershell命令中是未知的。
这些命令按预期工作,但命令不是从字符串中获取的:

"Classical Music for When You are on a Deadline." | & cmd /C powershell -Command {Invoke-Expression "Write-Host $input"}

# No:   System.Management.Automation.Runspaces.PipelineReader`1+<GetReadEnumerator>d__20[System.Object]
# "Classical Music for When You are on a Deadline." | & cmd /C powershell -Command {Write-Host $input}

"Classical Music for When You are on a Deadline." | & cmd /C powershell -Command {$arr = @($input)
    $arr.count
    Write-Host $arr[0]}
dwbf0jvd

dwbf0jvd1#

  • { $command } * 不会 * 将字符串$command的值转换为script block-它只是创建一个引用名为$command的变量的脚本块。
  • 从字符串创建脚本块,请使用**[scriptblock]::Create()**
  • 此外,* 不要 * 通过cmd /c调用powershell.exe-通常没有必要。

因此:

$command = '$arr = @($input)
$arr.count
Write-Host $arr[0]'

"Classical Music for When You are on a Deadline." | 
  powershell ([scriptblock]::Create($command))  # -Command is implied.

注:

  • 以上是您的问题中最后一个解决方案尝试的动态、基于变量的等效解决方案。
  • 在PowerShell的CLI中使用 * 脚本块 * 而不是 * 字符串 *(这只是PowerShell * 内部 * 的一个选项)通常更可取,原因如下:
    • 提供有限的类型保真度 *,使用与后台作业和远程处理相同的基于XML的序列化基础结构;也就是说,您可以从这样的CLI调用中返回对象 * 而不是字符串 *;类似地,这样的调用保留PowerShell的output streams的 * 全部 *。
  • 在后台使用Base64编码将脚本块的源代码安全地传递给目标PowerShell进程,从而避免了任何引用和转义问题。
  • 值得注意的是,由于PowerShell 7.2.x之前的一个长期存在的错误,将命令 * 作为字符串 * 传递需要将嵌入的"字符 * 手动转义为 * \"-请参见this answer

换句话说就是:虽然powershell -Command $command可以 * 与特定的示例字符串 * 一起工作,但如果字符串包含"字符,它将失败,这在Windows PowerShell中是不变的,并且至少是PowerShell(Core)7.2.x。
退一步说:由于您已经在PowerShell中运行,因此无需创建 * 另一个 * 示例作为 * 子进程 *,这样做开销很大。

$command = '$arr = @($input)
$arr.count
Write-Host $arr[0]'

# Invoke the dynamically created script block directly.
"Classical Music for When You are on a Deadline." | 
  & ([scriptblock]::Create($command))

注意事项:

  • &,调用运算符用于调用脚本块,该脚本块在 child 范围内运行。
  • 如果希望脚本块直接在调用方的作用域中运行,请使用.(点源运算符)。
  • Invoke-Expressioniex)--应该是generally be avoided--在这里不是一个选项,因为它不支持使用管道将数据传递给被评估的代码。
mdfafbf1

mdfafbf12#

您可以使用Invoke-Expression cmdlet将变量字符串作为命令在PowerShell中运行。例如:Invoke-Expression $commandString

相关问题