gpt4 book ai didi

arrays - 返回多个对象的cmdlet,它是什么收集类型? [电源外壳]

转载 作者:行者123 更新时间:2023-12-02 22:57:26 25 4
gpt4 key购买 nike

Get-ADuser cmdlet的示例:

$Users = Get-ADuser -Filter *

在大多数情况下,它将返回多个ADuser对象,但是它是什么“集合”类型?
该文档仅说它将返回Microsoft.ActiveDirectory.Management.ADUser的一个或多个用户对象。

尝试使用例如 ($Users -is [System.Collections.ArrayList]),但是我不能固定“collection”类型?

最佳答案

Cmdlet本身通常在其输出中不使用任何收集类型。[1]:
它们向管道发出单独的对象,这在情况上可能意味着:0(无),1或多个。
这正是Get-ADUser所做的:输出对象的具体数量取决于给定的参数。这就是 Get-AdUser help topic仅提及标量类型 ADUser 作为输出类型并指出它“返回一个或多个”的原因。
通常,PowerShell管道是指不需要预先知道其特定长度(对象计数)的对象流,后续管道段中的命令会在接收到前一段的输出对象时一一处理(参见about_Pipelines)。

但是,是PowerShell引擎,如果需要的话,PowerShell引擎会自动为您收集[object[]]数组[2]中的多个输出,特别是如果您通过变量赋值捕获输出或通过(...)grouping operator(或$(...)subexpression operator [3]),作为表达式:

# 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 DirectoryInfo instances.
# If there is only *one* subdir.: a DirectoryInfo instance itself.
# (See below for the case when there is *no* output.)
@()(即array-subexpression operator)旨在消除这种歧义,如果需要的话:
通过将命令包装在 @(...)中,PowerShell确保将其 输出始终收集为[object[]] -即使该命令恰好只产生一个输出对象,甚至不产生任何输出对象:
PS> $var = @(Get-ChildItem -Directory $HOME\Projects); $var.GetType().Name
Object[] # Thanks to @(), the output is now *always* an [object[]] array.
对于变量分配, 一个可能更有效的替代方法是使用[array]类型约束以确保输出成为数组:
# Alternative to @(...)
PS> [array] $var = Get-ChildItem -Directory $HOME\Documents; $var.GetType().Name
Object[]
注意:
  • 这可能会更有效,因为如果RHS已经碰巧是一个数组,则按原样分配它,而@(...)实际上枚举...的输出,然后将元素重新组装成一个新的([object[]])数组。
  • [array]通过简单地传递输入数组来保留输入数组的特定类型(例如,[array] $var = [int[]] (1..3)[int[]]数组按原样存储在$var中)。

  • [array]“cast”放置在$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

    [1]可以将整个集合作为一个整体输出到管道(在PowerShell代码中使用 Write-Output -NoEnumerate $collection或更简单地说是 , $collection),但是那只是管道中的另一个对象,它恰好是一个集合本身。从整体上输出集合是一个异常,但是,这改变了您通过管道传输以查看输出的命令的方式,这可能是意外的。一个著名的例子是 ConvertFrom-Json s unexpected behavior prior to v7.0
    [2]一个 System.Array 实例,其元素的类型为 System.Object ,您可以在一个数组中混合使用不同类型的对象。
    [3]使用 (...)通常就足够了; $(...)仅在字符串插值(可扩展字符串)以及将整个语句或多个命令嵌入较大的表达式中时才需要;请注意, $(...)(...)本身不同,它会解包单元素数组;比较 (, 1).GetType().Name$(, 1).GetType().Name;参见 this answer
    [4]在某些情况下,“什么都没有”与 $null的行为不同,尤其是在管道和 switch语句中,如 this comment on GitHub所述;链接的问题是一项功能请求,通过将 $null支持为,使“nothing”与 -is [AutomationNull]更加容易区分
    一个测试。

    关于arrays - 返回多个对象的cmdlet,它是什么收集类型? [电源外壳],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60018623/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com