PowerShell - 有没有办法创建一种包含验证集多个参数的“别名”?

如何解决PowerShell - 有没有办法创建一种包含验证集多个参数的“别名”?

下午好,

我最近创建了一个 PowerShell 脚本来自动化和测试 PowerCLI 脚本,然后再在 vCenters/ESXi 主机上运行它们。

目前,我使用验证集让用户选择他们想要在哪个服务器/集群上执行他们的脚本:

param(
    [string]$script = "help",[validateset("localhost","Server1","Server2")]
    [string]$server,[validateset("DC0_C0","DC0_C1","DC0_C2","Customer1")]
    [string[]]$cluster,[switch]$help
)

问题是,有时当你有大客户时,他们可能有多个集群,简单地输入“customer1”并让脚本在 cluster1/2 和 4 上运行会更方便,而不是手动输入所有集群:

./viexec vminfo localhost Cluster1,Cluster3,Cluster10

./viexec vminfo localhost Customer1 #And have the script run automatically on all the right clusters.

我已经尝试使用 if 来检查变量 $cluster 的值,如果它等于“Customer1”,那么它会用适当的集群替换他的值,但我觉得这个解决方案并不优雅。而且很难配置/维护,因为用户需要修改代码,所以如果这些参数可以从外部配置文件/用户输入创建,那就更好了。

我还想知道是否可以从文件/csv 中检索验证集的参数以避免用户自定义主 script.ps1,而是简单地在填充的 .CSV 中替换/写入他们的服务器和集群验证集参数。

希望清楚..

问候, 亚历山德罗

解决方法

这是一个概念证明,它实现了一个 Invoke-VI 函数,该函数展示了所需的制表符完成/验证行为,由在JSON 文件。

注意:

  • JSON 被选为 CSV 的更灵活替代方案,因为后者需要每个客户固定数量的集群(列)。最终,像 YAML 或 INI 文件这样的东西对最终用户来说会更方便,但 PowerShell 目前缺乏对这些格式的内置支持;见GitHub proposal #3607GitHub proposal #9035;但是,PowerShell Gallery 中提供了第三方模块,例如 powershell-yamlPSIni

  • 实现了函数而不是脚本,因为在使用所需的制表符完成和验证功能声明参数之前需要准备步骤。这意味着,不是直接运行您的 *.ps1 脚本,您需要dot-source 它 (. ./viexec.ps1) 然后调用 Invoke-VI 函数。或者,将函数定义为(自动加载)module 的一部分。

首先,创建一个包含 2 个客户及其关联集群的示例 JSON 文件:

# Create a sample JSON file that maps customer names to clusters.
# This will serve as the basis for tab-completion / argument validation.
@'
{
  "Customer1": [ "DC0_C0","DC0_C1","DC0_C2" ],"Customer2": [ "DC1_C0","DC1_C1" ]
}
'@ > CustomerToClusters.json

基于它的代码:

# Parse the JSON file,assumed to be located in the same dir.
# as this script.
$customerToClusterMapping = ConvertFrom-Json (Get-Content -Raw $PSScriptRoot/CustomerToClusters.json)

# Build the list of customer names and cluster names across all customers.
[string[]] $customerNames = $customerToClusterMapping.psobject.Properties.Name
[string[]] $allClusters = $customerToClusterMapping.psobject.Properties.Value

function Invoke-VI {
  param(
    # Tab-complete cluster names as well as customer names.
    [ArgumentCompleter({ param($cmd,$param,$wordToComplete) ($customerNames + $allClusters) -like "$wordToComplete*" })]
    # Ensure that only known customer / cluster names were specified.
    # NOTE: If validation fails,the (default) error message is unhelpful.
    #       Unfortunately,this cannot be helped in *Windows PowerShell*,but in
    #       PowerShell (Core) 7+,you can add an `ErrorMessage` property:
    #         [ValidateScript({ $_ -in ($customerNames + $allClusters) },ErrorMessage = 'Unknown customer/cluster name: {0}')]
    [ValidateScript({ $_ -in ($customerNames + $allClusters) })]
    [string[]] $Cluster
  )

  # Resolve the specified cluster arguments and remove duplicates from the
  # resulting list of cluster-only names.
  $resolvedClusters = $Cluster | ForEach-Object {
    # If a customer name was specified,eturn the list of clusters for the specified customer.
    if ($_ -in $customerNames) { $customerToClusterMapping.$_ } 
    else { $_ }
  } | Select-Object -Unique
  
  "Specified or implied clusters: $resolvedClusters"

}  

示例调用,在点源上面的代码之后:

PS> Invoke-VI Customer1    # Customer1 was tab-completed.
Specified or implied clusters: DC0_C0 DC0_C1 DC0_C2

注意如何将客户名称解析为关联的集群。

,

这是 JSON-based answer 的一个变体,它:

首先,创建一个包含 2 个客户及其关联集群的示例 CSV 文件:

# Create a sample CSV file that maps customer names to clusters.
# This will serve as the basis for tab-completion / argument validation.
# IMPORTANT: Be sure that you have enough headers (colum names) to cover 
#            the maximum number of columns values.
@'
Customer,Cluster1,Cluster2,Cluster3,Cluster4,Cluster5
Customer1,DC0_C0,DC0_C1,DC0_C2
Customer2,DC1_C0,DC1_C1
'@ > CustomersToClusters.csv

基于它的代码:

# Parse the CSV file,assumed to be located in the same dir.
# as this script.
$csvRows = Import-Csv $PSScriptRoot/CustomersToClusters.csv

# Build a hashtable of customer names mapped to their associated clusters.
$colCount = $csvRows[0].psobject.Properties.Name.Count
$htCustomersToClusters = [ordered] @{}
foreach ($row in $csvRows) {
  $htCustomersToClusters[$row.Customer] = $row.psobject.Properties.Value[1..($colCount-1)] -ne $null
}
# Build an array of all customer and cluster names.
[string[]] $allCustomersAndClusters = $htCustomersToClusters.Keys + $htCustomersToClusters.GetEnumerator().ForEach({ $_.Value })

# Define the custom class that implements the System.Management.Automation.IValidateSetValuesGenerator
# interface,to be passed to the [ValidateSet()] attribute.
class CustomerAndClusters : System.Management.Automation.IValidateSetValuesGenerator {
  [string[]] GetValidValues() { return $script:allCustomersAndClusters }
}

function Invoke-VI {
  param(
    # Provide tab-completion and validation based on the values
    # returned by a [CustomersAndClusters] instance's .GetValidValues() call.
    [ValidateSet([CustomerAndClusters])]
    [string[]] $Cluster
  )

  # Resolve the specified cluster arguments and remove duplicates from the
  # resulting list of cluster-only names.
  $resolvedClusters = $Cluster | ForEach-Object {
    # If a customer name was specified,resolve it to the list of associated clusters.
    if ($customerClusters = $htCustomersToClusters[$_]) { $customerClusters }
    else { $_ }
  } | Select-Object -Unique
  
  "Specified or implied clusters: $resolvedClusters"

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?