Get-ADuser
cmdlet的示例:
$Users = Get-ADuser -Filter *
在大多数情况下,它会返回多个AD用户对象,但这是什么“集合”类型呢?文档只说它将返回一个或多个Microsoft.ActiveDirectory.Management.ADUser用户对象。
尝试使用例如
($Users -is [System.Collections.ArrayList])
,但我无法确定“集合”类型是什么?Get-ADuser
cmdlet的示例:
$Users = Get-ADuser -Filter *
($Users -is [System.Collections.ArrayList])
,但我无法确定“集合”类型是什么?Get-AdUser
帮助主题只提到标量类型ADUser
作为输出类型,并声明它“返回一个或多个”对象。# 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[]
# 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.)
@(...)
,数组子表达式运算符,旨在消除这种歧义,如果需要的话:
通过将命令包装在@(...)
中,PowerShell确保其输出始终被收集为[object[]]
- 即使命令只产生一个输出对象甚至没有输出对象:
PS> $var = @(Get-ChildItem -Directory $HOME\Projects); $var.GetType().Name
Object[] # Thanks to @(), the output is now *always* an [object[]] 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[]
@(...)
实际上会枚举...
的输出,然后将元素重新组装成一个新的([object[]]
)数组。
[array]
通过简单地将输入数组传递给它来保留输入数组的特定类型(例如,[array] $var = [int[]] (1..3)
将[int[]]
数组原样存储在$var
中)。@(...)
和[array]
的行为可能不同:@($null)
返回一个只有一个元素为$null
的单项数组,而[array] $null
没有任何效果(仍然是$null
)。类似地,对于不产生输出的命令,例如& {}
,@(& {})
变成一个空数组,而[array] $arr = & {}
则将$null
赋值给$arr
(除非在禁用变量优化的上下文中,这通常适用于全局范围:此时将意外赋值为特殊的“nothing”值(参见下文),请参阅GitHub问题#20275)。@(...)
的结果进行盲目索引(假设严格模式关闭,这是默认情况下的情况,或者至多在版本2
),而不能对[array] (...)
进行索引;例如:@(Get-ChildItem nosuch*)[0]
返回$null
,而([array] (Get-ChildItem nosuch*))[0]
失败,因为你不能对$null
进行索引。感谢Walter A。[array]
强制转换放在$var = ...
的左侧,也就是将其作为变量的类型约束,意味着变量的类型被锁定,以后将不同的值赋给$var
仍然会将RHS值转换为[array]
([object[]]
),如果需要的话(除非你赋值为$null
或“nothing”(参见下文))。
[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
Write-Output -NoEnumerate $collection
或更简洁地使用, $collection
),但这只是管道中的另一个对象,恰好是一个集合。然而,将整个集合输出是一个异常情况,它会改变您将命令传递给的管道中的输出,这可能会出乎意料;一个著名的例子是在v7.0之前ConvertFrom-Json
的行为异常。System.Array
实例,其元素的类型为System.Object
,允许您在一个数组中混合不同类型的对象。
[3] 使用(...)
通常就足够了;$(...)
只在字符串插值(可扩展字符串)和在较大表达式中嵌入整个语句或多个命令时才需要;请注意,与单独的(...)
不同,$(...)
会解开单元素数组;将(, 1).GetType().Name
与$(, 1).GetType().Name
进行比较;请参见this answer。
$null
的行为不同,尤其是在管道和switch
语句中,详见GitHub上的这条评论。GitHub问题#13465是一个已经批准的改进,旨在通过支持-is [System.Management.Automation.AutomationNull]
作为测试,使“nothing”与$null
更容易区分;然而,截至PowerShell(Core)7.3.8,还没有人着手实施它。Usually it's just an object array:
$Users.gettype()
$Users.count
$Users -is [object[]]
$error是一个ArrayList数组列表:$error -is [collections.arraylist]
var = @(Get-Item nomatchingfiles*); $var[0].count
是有效的,而[array] $var = Get-Item nomatchingfiles*; $var[0].count
则会显示错误。 - undefined