从命令行PowerShell 7.2传递Hashtable参数

jk9hmnmh  于 2023-10-18  发布在  Shell
关注(0)|答案(1)|浏览(197)

我正在尝试创建一个PowerShell脚本,脚本的参数之一是Hashtable。我在这个项目中使用PowerShell 7.2,每当我试图通过命令行传递Hashtable时,它都会将其作为字符串System.Collections.Hashtable而不是Hashtable本身传递。这将导致脚本抛出一个错误,因为参数是作为Hashtable类型的。
这是我写的剧本的一个简短版本。

#requires -version 7.2

[CmdletBinding(PositionalBinding = $False)]
param ([hashtable] $TestTable)

$TestTable

我在PowerShell命令行中尝试了以下命令。
pwsh .\ScriptName.ps1 -TestTable @{Test = "This is a test"}
pwsh -Command .\ScriptName.ps1 -TestTable @{Test = "This is a test"}
还有许多变体尝试逗号、引号、括号和@符号的不同组合。
当我运行上面列出的两个命令之一时,我得到错误ScriptName.ps1: Cannot process argument transformation on parameter 'TestTable'. Cannot convert the "System.Collections.Hashtable" value of type "System.String" to type "System.Collections.Hashtable".
我想在这个项目中坚持使用PowerShell 7.2。当我删除7.2的要求并在不使用Pashsh的情况下运行该命令时,它可以完美地工作,但我还没有找到适用于7.2的解决方案。如果有人知道如何做到这一点,我将非常感谢一个解释。

jdzmm42g

jdzmm42g1#

我在 PowerShell命令行 * 中尝试了以下命令。
通常没有充分的理由从PowerShell
调用pwsh(PowerShell(Core)CLI)*,因为您可以直接在进程中 * 调用.ps1文件 *:

.\ScriptName.ps1 -TestTable @{Test = "This is a test"}

如果您想通过CLI调用(例如,要将脚本可能进行的任何会话级更改限制在 * 子进程 * 中,请使用script block{ ... })进行调用:

pwsh { .\ScriptName.ps1 -TestTable @{Test = "This is a test"} }

注意事项:

  • 传递一个 * 脚本块 * 只能在PowerShell* 内部工作,
  • 在这里,它的使用 * 意味着 * -Command-c)CLI参数
  • 但是,从 * 外部 * PowerShell -在这种情况下,要执行的命令必须作为 * 字符串 *(见下文)-使用-Command-c)是 * 必需的 *,因为-FilePowerShell (Core) 7+中的默认值(与 Windows PowerShell 不同)。
  • 如果要将 arguments 传递给脚本块(通常基于 *caller的 * 值),则在脚本块参数之后添加--args参数,该参数是脚本块应该看到的位置参数数组,默认情况下通过自动$args变量;例如:
pwsh { "$($args.Count) args received."; $args } -args foo, bar
  • 从 * 外部 * PowerShell调用需要遵守 * 调用shell* 的语法要求,以便传递"字符。这是PowerShell命令的一部分,通过以下方式执行:
  • cmd.exe(Windows)
pwsh -Command ".\ScriptName.ps1 -TestTable @{Test = \"This is a test\"}"
  • 从POSIX兼容的shell,如Bash(在类Unix平台上):
pwsh -Command '.\ScriptName.ps1 -TestTable @{Test = "This is a test"}'
  • 请注意,虽然"...\"...\"..."方法原则上也可以工作,但包含$字符的命令。将要求这些也被\转义,以便通过。有利的一面是,* 不 * 转义它们允许您在命令中 * 嵌入 * 来自调用者 * 的变量值 *(Windows上的cmd.exe的等效方法是使用%...%变量引用)。
  • 至于PowerShell的CLI的 caller 接收到的输出:
  • 当使用 script blockinside PowerShell 调用时:
  • 类型保真度是 * 保持 * 的,但 * 有限制 *,即PowerShell的 * 跨进程序列化 * 所施加的限制:请参见this answer
  • 否则(从PowerShell外部调用 * /使用 string 传递命令时):
  • 所有输出都是 * 字符串 *(文本),使用控制台窗口的代码页所暗示的字符编码(如PowerShell中的[Console]::OutputEncoding所反映的)。
  • 复杂对象-例如Get-ChildItem输出的System.IO.FileSystemInfo-由它们的 for-display 字符串表示形式表示,因为它们将从交互式PowerShell会话内部打印到显示器。
  • 生成 * 结构化 * 文本输出的唯一方法是传递-OutputFormat xml-of xml),这将导致CLIXML输出,即PowerShell本身用于跨进程序列化的基于XLM的格式;但是,在PowerShell之外,没有任何知名库可以使用这种格式。

相关问题