【问题标题】:Is it possible to use a cmdlet as an input parameter for a dynamic PowerShell script?是否可以使用 cmdlet 作为动态 PowerShell 脚本的输入参数?
【发布时间】:2017-12-04 01:29:50
【问题描述】:

这是我正在尝试使用的测试脚本,我从一个单独的进程中调用它并尝试将参数传递给它。这个想法是我有一个用户界面,允许用户选择一个 CmdLet,然后使用该 CmdLet 的属性/方法填充另一个下拉列表。

我的问题似乎是脚本将输入参数呈现为字符串,因此正在创建一个文本文件,其中包含您已应用“Get-Member”的任意字符串的方法和属性,例如“克隆”或“比较对象”。唯一的属性是“Length”。

有什么方法可以将该输入参数作为可用的 CmdLet 而不是字符串引入?也许我错过了什么,或者我试图做的事情是不可能的。

param([string]$inputCmdLet = "Get-NetAdapter");

$wrkgDir = "D:\Distribution\Operational";

# Get Properties and Methods for CmdLet Input Parameter
$propertyNames = $inputCmdLet | Get-Member -MemberType Property;
$methodNames = $inputCmdLet | Get-Member -MemberType Method;

# Sort Arrays
$propertyNames = $propertyNames | Sort-Object Name;
$methodNames = $methodNames | Sort-Object Name;

# Output Results to Text Files
$propertyNames.Name | Out-File $wrkgDir\$inputCmdLet.Properties.txt;
$methodNames.Name | Out-File $wrkgDir\$inputCmdLet.Methods.txt;

编辑以获取更多信息:

在 Get-NetAdapter 的示例中,我希望的输出是一个输出文件中的属性列表和另一个输出文件中的方法。我现在得到的是这样的:

Left list is expected (partial) result, right list is actual result.

我不确定如何以编程方式实现左侧(图像中)的结果列表。我可以通过静态输入来获得正确的输出:

$mbrNameStatic = Get-NetAdapter | Get-Member;
$mbrNameStatic.Name | Out-File $wrkgDir\$inputCmdLet.Strings.txt;

但是当我使用输入参数时,它会将值合并为一个字符串,所以看起来实际的运行时代码看起来更像这样:

$propertyNames = "Get-NetAdapter" | Get-Member -MemberType Property;

因此,添加引号会将 cmdlet 呈现为字符串(我想这是有道理的,因为我的输入参数是字符串),它返回字符串而不是 cmdlet 的属性和方法。有没有办法让 cmdlet 不带引号呈现?

如果我的描述或这个想法没有任何意义,请告诉我。

谢谢!

【问题讨论】:

  • 您所描述的是Show-Command cmdlet 的作用。它显示 cmdlet 的 UI。是否有理由重写内置 cmdlet?或者,Get-Command 可用于检索表示基于名称的给定 cmdlet、函数或脚本的对象。
  • 嗨@mikez,感谢您的回复。我试图实现的目的是为完全不熟悉 powershell 或脚本的用户提供易用性。这个想法是将此功能包装到现有的多用途 UI 中,但提供可扩展性和可重用代码。在我的情况下,我应该如何使用 Get-Command?我试过这个: param([string]$inputCmdLet = "Get-NetAdapter"); $targetCmdLet = 获取命令 $inputCmdLet;但是,这并没有让我获得输入的 cmdlet 的成员属性和方法。谢谢!

标签: powershell


【解决方案1】:

为了执行name(仅)存储在变量中或名称用单引号或双引号指定的命令,您必须使用&调用运算符.

# WRONG: The token is interpreted as an *expression* that outputs a *string*
"Get-NetAdapter"  # outputs the [string] literal

# WRONG: ditto, via a variable
$name = "Get-NetAdapter"
$name  # outputs the contents of the [string] variable

# OK: Use of & tells Powershell to interpret the next token as a *command* to *invoke*.
& "Get-NetAdapter"
& $name

至于你的一般做法:

  • 请注意,并非所有 cmdlet 在调用时都会产生输出不带参数,因此您当前的代码(即使使用 &)将无法与所有 cmdlet 一起使用。

    李>
  • 相反,那些在没有给定参数时确实产生输出的 cmdlet 可能会产生 很多 个,这是不必要的,所以考虑像 & $inputCmdlet | Select-Object -First 1 这样的东西。

    李>
  • 通常,您可以使用(Get-Command Get-NetAdapter).OutputType 之类的内容来获取 cmdlet 的输出类型,但请注意:

    • 声明输出类型是可选,因此并非所有 cmdlet 都可以返回值。

    • 如果您从 type 评估者开始,而不是该类型的 instance,则无法使用 Get-Member 发现 instance 成员 em>(只能通过-Static获取static成员)。

【讨论】:

  • & 符号成功了。这仍然是一个正在形成的想法,所以我期待像你描述的那样遇到警告。我对powershell还是新手,并且缺乏一些诸如此类的基础知识;我认为这可能是一些我还不熟悉的简单事物。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多