Arrays 如果包含多个字符串do“;这";否则";这";
如果存在名称相同的SCOM组,则尝试生成请求更多信息(组Id)的脚本:Arrays 如果包含多个字符串do“;这";否则";这";,arrays,powershell,if-statement,count,scalar,Arrays,Powershell,If Statement,Count,Scalar,如果存在名称相同的SCOM组,则尝试生成请求更多信息(组Id)的脚本: function myFunction { [CmdletBinding()] Param( [Parameter(Mandatory=$true)] [string[]]$ObjectName ) foreach ($o in $ObjectName) { $p = Get-SCOMGroup -DisplayName "$o" | sele
function myFunction {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[string[]]$ObjectName
)
foreach ($o in $ObjectName) {
$p = Get-SCOMGroup -DisplayName "$o" | select DisplayName
<#
if ($p contains more than one string) {
"Request group Id"
} else {
"do this"
}
#>
}
}
函数myFunction{
[CmdletBinding()]
Param(
[参数(必需=$true)]
[字符串[]]$ObjectName
)
foreach($ObjectName中的o){
$p=获取SCOMGroup-DisplayName“$o”|选择DisplayName
}
}
需要有关注释块功能的帮助。将值包装在数组子表达式
@()
中,并计算它有多少个条目:
if(@($p).Count -gt 1){"Request group Id"}
注:此答案是补充 计算命令返回的对象数:
- Mathias的回答显示了一个基于,
的健壮、与PowerShell v2兼容的解决方案@()
# @() ensures that the output of command ... is treated as an array, # even if the command emits only *one* object. # You can safely call .Count (or .Length) on the result to get the count. @(...).Count
- 在PowerShell v3或更高版本中可以像集合一样处理标量,因此只需
就足够了。(标量是单个对象,而不是对象的集合)(…).Count
- 选择
,如果:@(…)。计数
- 您必须保持PSv2兼容
- 您想计算多个命令的输出(用
或换行符分隔);
- 对于将整个集合作为单个对象输出的命令(这种情况很少见),您希望将此类集合计数为
object1
- 更一般地说,如果需要确保命令输出作为真正的数组返回,请注意,它的类型总是
;如果您需要特定的元素类型,请使用强制转换(例如,[object[]]
),但请注意,您不需要严格使用[int[]]
;e、 g.,@(…)
就可以了-除非您想阻止集合作为单个对象输出的枚举[int[]](…)
- 选择
,如果:(…)。计数
- 只能计算一个命令的输出
- 对于将整个集合作为单个对象输出的命令,需要计算此类集合的单个元素;也就是说,
强制枚举(…)
- 对于已存储在变量中的命令输出元素的计数,当然,您可以省略
并使用(…)
$var.Count
设置StrictMode(版本2
或更高版本)生效时,访问标量上的.Count
失败-在这种情况下使用@(…)
,但请注意,您可能必须强制枚举
要演示将集合作为单个对象输出的(罕见)命令的行为差异,请执行以下操作:
性能注意事项:
$arr = 1..1e6 # Create an array of 1 million integers.
{ (Write-Output $arr).Count }, { @(Write-Output $arr).Count } | ForEach-Object {
[pscustomobject] @{
Command = "$_".Trim()
Seconds = '{0:N3}' -f (Measure-Command $_).TotalSeconds
}
}
- 如果命令的输出是直接计数的,
和(…)
的执行方式大致相同:@(…)
$arr = 1..1e6 # Create an array of 1 million integers. { (Write-Output $arr).Count }, { @(Write-Output $arr).Count } | ForEach-Object { [pscustomobject] @{ Command = "$_".Trim() Seconds = '{0:N3}' -f (Measure-Command $_).TotalSeconds } }
- 来自单核Windows 10虚拟机的示例输出(绝对计时并不重要,只是数字几乎相同):
- 相反,对于已经存储在变量中的大型集合,
引入了大量开销,因为集合被重新创建为一个(新)数组(如前所述,您只需@(…)
):$arr.Count
- 样本输出;请注意,
解决方案的速度大约慢7倍:@(…)
Command Seconds ------- ------- ($arr).Count 0.009 @($arr).Count 0.067
- 样本输出;请注意,
编码风格注意事项:
$arr = 1..1e6 # Create an array of 1 million integers.
{ (Write-Output $arr).Count }, { @(Write-Output $arr).Count } | ForEach-Object {
[pscustomobject] @{
Command = "$_".Trim()
Seconds = '{0:N3}' -f (Measure-Command $_).TotalSeconds
}
}
以下内容适用于@(…)
和(…)
在功能上等效的情况(或者执行相同的操作,或者性能是次要的),即当您可以自由选择要使用的构造时
# @() ensures that the output of command ... is treated as an array,
# even if the command emits only *one* object.
# You can safely call .Count (or .Length) on the result to get the count.
@(...).Count
Mathias建议@(…)。计数
,在评论中说明:
在这个上下文中显式地包装它还有另一个原因——传达意图,即“我们不知道$p
是否是标量,因此这个构造”
我投票支持(…)。计数
:
$arr = 1..1e6 # Create an array of 1 million integers.
{ (Write-Output $arr).Count }, { @(Write-Output $arr).Count } | ForEach-Object {
[pscustomobject] @{
Command = "$_".Trim()
Seconds = '{0:N3}' -f (Measure-Command $_).TotalSeconds
}
}
一旦您了解PowerShell(v3或更高版本)将标量视为按需计数为1的集合,您就可以自由地利用这些知识,而无需在语法中反映标量和数组之间的区别:
- 编写代码时,这意味着您不必担心给定命令是否会返回标量而不是集合(这在PowerShell中很常见,在PowerShell中,使用单个输出对象捕获命令的输出会捕获该对象,而两个或多个输出对象会生成一个数组)
- 作为一种有益的副作用,代码变得更简洁(有时更快)
# Call Get-ChildItem twice, and, via Select-Object, limit the
# number of output objects to 1 and 2, respectively.
1..2 | ForEach-Object {
# * In the 1st iteration, $var becomes a *scalar* of type [System.IO.DirectoryInfo]
# * In the 2nd iteration, $var becomes an *array* with
# 2 elements of type [System.IO.DirectoryInfo]
$var = Get-ChildItem -Directory / | Select-Object -First $_
# Treat $var as a collection, which in PSv3+ works even
# if $var is a scalar:
[pscustomobject] @{
Count = $var.Count
FirstElement = $var[0]
DataType = $var.GetType().Name
}
}
上述收益率:
Count FirstElement DataType
----- ------------ --------
1 /Applications DirectoryInfo
2 /Applications Object[]
也就是说,即使是System.IO.DirectoryInfo
类型的标量对象也将其.Count
合理地报告为1
,并允许使用[0]
访问“其第一个元素”
有关标量和集合的统一处理的更多信息,请参阅