Cmdlets
他们自己
通常使用
不
输出中的集合类型
.
1.
:
他们
发出
单个对象
到
管道
,这可以
情境性
平均值:0、1或多个1。
这正是
Get-ADUser
做:
输出对象的具体数量取决于给定的参数
;这就是为什么
Get-AdUser
help topic
仅提及标量类型
ADUser
作为输出类型,并声明它“返回一个或多个”它们。
一般而言,
PowerShell管道被设计为
流动
物体
,其计数不需要提前知道
命令通常输出对象
逐一地
,一旦可用
,以及
接收
命令通常也会处理它们
逐一地
,一旦收到
(参见
about_Pipelines
).
PowerShell引擎本身
自动收集
为您提供多种输出
[object[]]
阵列
2.
如果需要
,特别是如果您通过
变量赋值
或通过以下方式使用命令调用
(...)
,the
grouping operator
(或
$(...)
,the
subexpression operator
3.
,或
@(...)
,the
阵列
子表达式运算符,下面将详细讨论),作为
表达
:
# Get-ChildItem C:\Windows has *multiple* outputs, so PowerShell
# collects them in an [object[]] array.
PS> $var = Get-ChildItem C:\Windows; $var.GetType().Name
Object[]
# Ditto with (...) (and also with $(...) and always with @(...))
PS> (Get-ChildItem C:\Windows).GetType().Name
Object[]
但是,如果给定的命令-可能
情境性
-仅输出a
单一的
对象,然后你会得到那个对象
它本身
-确实如此
不
包裹在数组中(除非您使用
@(...)
-见下文):
# Get-Item C:\ (always) returns just 1 object.
PS> $var = Get-Item C:\; $var.GetType().Name
DirectoryInfo # *not* a single-element array,
# just the System.IO.DirectoryInfo instance itself
可能会变得棘手的是,给定的命令可以
情境性
根据输入和运行时条件,产生一个或多个输出,因此引擎可以返回单个对象
或
阵列。
# !! What $var receives depends on the count of subdirs. in $HOME\Projects:
PS> $var = Get-ChildItem -Directory $HOME\Documents; $var.GetType().Name
??? # If there are *2 or more* subdirs: an Object[] array of DirectoryInfos.
# If there is only *one* subdir.: a DirectoryInfo instance itself.
# (See below for the case when there is *no* output.)
@(...)
,the
array-subexpression operator
,旨在消除这种歧义
,如果需要:
通过将命令包装在
@(...)
PowerShell确保其
输出为
总是
收集为
[对象[]]
-即使命令恰好生成
一
输出对象甚至
没有人
:
PS> $var = @(Get-ChildItem -Directory $HOME\Projects); $var.GetType().Name
Object[] # Thanks to @(), the output is now *always* an [object[]] array.
对于可变分配,
一个潜在的更有效的替代方案是使用
[array]
类型约束
以确保输出成为数组:
# Alternative to @(...)
# Note: You may also create a strongly typed array, with on-demand type conversions:
# [string[]] $var = ...
PS> [array] $var = Get-ChildItem -Directory $HOME\Documents; $var.GetType().Name
Object[]
注:
-
这可能更有效,因为如果RHS恰好是一个数组,则按原样分配,而
@(...)
事实上
列举
输出来自
...
然后
重新组装
元素变成a
新
(
[对象[]]
)阵列
.
-
[阵列]
蜜饯
输入数组的特定类型
通过它
(例如。,
[array] $var = [int[]] (1..3)
存储
[int[]]
按原样排列
$var
).
-
放置
[阵列]
“铸”到
左边
属于
$var = ...
-这就是它成为
类型约束
on变量-表示变量的类型为
已锁定
,并为其分配不同的值
$var
稍后将继续将RHS值转换为
[阵列]
(
[对象[]]
),如果需要(除非您指定
$null
或“无”(见下文)。
退一步:
确保收集的输出是一个数组通常
没有必要
,由于
PowerShell的
标量和集合的统一处理
在v3+版本中:
如果命令产生
不
输出,您将得到“无”
(严格来说:
[System.Management.Automation.Internal.AutomationNull]::Value
单例),其中
在大多数情况下,行为如下
$null
4.
:
# Get-Item nomatchingfiles* produces *no* output.
PS> $null -eq (Get-Item nomatchingfiles*)
True
# Conveniently, PowerShell lets you call .Count on this value, which the
# behaves like an empty collection and indicates 0.
PS> (Get-Item nomatchingfiles*).Count
0
[1] 它
是
可以输出整个集合
作为一个整体
到管道(在PowerShell代码中使用
Write-Output -NoEnumerate $collection
或者更简洁地说,
, $collection
),但这只是管道中的另一个对象,恰好是一个集合本身。将集合作为一个整体输出是
异常
但是,这会改变您管道命令的方式
到
查看输出,这可能是意外的;一个突出的例子是
ConvertFrom-Json
s unexpected behavior prior to v7.0
.
[2] a
System.Array
元素类型为的实例
System.Object
,允许您
混合不同类型的对象
在单个阵列中。
[3] 使用
(...)
通常就足够了;
$(...)
仅用于字符串插值(可扩展字符串)和嵌入整个语句或
倍数
更大的表达式中的命令;请注意
$(...)
,不像
(...)
其本身可以展开单个元素数组;比较
(, 1).GetType().Name
到
$(, 1).GetType().Name
;参见
this answer
.
[4] 在某些情况下,“无”的行为与
$null
,特别是在管道和
switch
声明,详见
this comment on GitHub
;相关问题是一个功能请求,使“无”更容易与
$null
,通过支持
-is [AutomationNull]
作为
测试。