Powershell返回的数组类型混乱

Powershell返回的数组类型混乱,powershell,Powershell,下面显示返回的类型不同,具体取决于返回的行数。为什么它是这样设计的?很容易假设它总是返回一个数组并编写代码$a.Length$a |%{…},当它只返回一行时会产生错误,除非它被编写为$a=@(invoke-..),这很容易忘记 $a=调用Sqlcmd-ServerInstance服务器“选择1 a” $b=调用Sqlcmd-ServerInstance服务器“选择1 a联合所有选择2” $a.GetType() 大多数情况下,在PowerShell中,返回对象的函数/cmdlet只返回对象。

下面显示返回的类型不同,具体取决于返回的行数。为什么它是这样设计的?很容易假设它总是返回一个数组并编写代码
$a.Length
$a |%{…}
,当它只返回一行时会产生错误,除非它被编写为
$a=@(invoke-..)
,这很容易忘记

$a=调用Sqlcmd-ServerInstance服务器“选择1 a”
$b=调用Sqlcmd-ServerInstance服务器“选择1 a联合所有选择2”
$a.GetType()
  • 大多数情况下,在PowerShell中,返回对象的函数/cmdlet只返回对象。如果要返回多个对象,函数只会一直返回对象,直到完成为止。PowerShell处理所有返回的对象并为您提供一个数组
  • gm
    Get Member
    的别名。当您通过管道调用它时,
    $a | gm
    ,您将其作为管道调用。在这种情况下,
    $a
    中的每个对象都单独传递给
    Get Member
    ,因此它返回单个对象的类型。如果它们都是相同的,那么它只会显示一次,但实际上它会检查所有它们。您可以通过调用
    Get Member-InputObject$a
    来防止这种情况,如果它是一个数组,那么它应该显示数组类型
  • 与上面类似,
    .GetType()
    获取调用它的对象的类型,因此如果它是数组,则返回该类型;它不是看单个元素 我还想指出,
    %
    ForEach Object
    )和
    ForEach()
    在不用于数组时工作正常:
    “hello”|%{$}
    ForEach('hello'中的msg){$msg}

    要解决返回值为单个对象时,
    $a.Length
    不起作用的问题,它取决于您的powershell版本

    在版本2中,您将看到您正在看到的行为:您必须首先将其包装到数组中,或者使用以下内容测试数组:

    if($a-is[Array]){
    $itemCount=$a.Length
    }否则{
    $itemCount=1
    }
    

    但是,在powershell 3+中,您可以执行
    $a.Length
    ,即使
    $a
    只是某个对象而不是数组。它将返回1。长度可能不会在自动完成或intellisense中显示,但它会起作用。

    我希望我能回答这个问题,但我想我遗漏了一些关键参数。1.这可能取决于
    调用Sqlcmd
    ,也取决于您的PowerShell版本。2.Get成员作用于管道中传递的元素,而不是整个对象,这就是为什么3。返回它的功能。您使用的powershell版本是什么?对于
    $a |%{…}
    ,我的意思是
    $a.Length
    。我已经更新了这个问题。@dc7a9163d9 powershell的哪个版本?@Briantist:更正你关于PS 3+的最后一行:$a.Length将起作用,除非你使用严格模式,你应该:-)参见我最近的问题2。没错,我也是严格模式的粉丝(模块内部除外),我在其他答案中也写过。但至少在3+PowerShell中有能力按编写方式处理它,您可以选择不使用严格模式(与大多数情况一样),但在v2中,您没有这种选择。 IsPublic IsSerial Name BaseType -------- -------- ---- -------- True False DataRow System.Object IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Object[] System.Array