【问题标题】:Powershell being too cleverPowershell太聪明了
【发布时间】:2010-10-29 03:58:47
【问题描述】:

抱歉,这可能是一个新问题。

我正在编写一些针对 AD 运行各种查询的 Powershell 脚本。它们通常会返回一堆结果,这些结果很容易处理,即:

$results = myQuery
write-host "Returned " + $results.Count + " results."
foreach ($result in $results) { doSomething }

不用担心。但是,如果只有 1 个结果,Powershell 会自动将该结果转换为单个对象,而不是包含 1 个对象的数组。所以上面的代码会在 Count 和 foreach 处中断。我确定 0 结果也会出现同样的问题。

有人可以提出一种优雅的方式来处理这个问题吗?也许某种方式可以转换结果,使它们始终是一个数组?

【问题讨论】:

    标签: powershell


    【解决方案1】:

    这也困扰着我。关于如何修复 $results.Count 没有聪明的想法,但可以通过切换到管道来修复 foreach。

    $scalar = 1
    $list = (1,2)
    $list | % { $_ }
    

    打印 1 2

    $scalar | % { $_ }
    

    打印 1

    【讨论】:

      【解决方案2】:

      将第一行代码改为

      $results = @(myQuery)
      

      这将始终返回一个数组。请参阅this blog entry 了解更多详情。

      【讨论】:

      • 你能告诉我为什么它是这样设计的吗?我的同事问我不知道..
      • 上面引用的博客条目解释了一些细节。
      • @ 在 C# 中表示“字符串文字”。我猜这里的意思是“数组字面量”。
      • 可以肯定它不是 Powershell - 我认为它本身就是 AD。当我在 VBScript 中进行 LDAP 查询时,它返回一个包含多个值的数组、一个用于单个用户的单个对象以及(我认为)一个用于空值的空字符串。很烦人。确保检查如果查询不匹配会发生什么。
      • @ChristianLinnell:这当然是 PowerShell。你可以试试(1..5|?{$_-eq3}).count。关键是在PowerShell中通常在分配查询时只产生一个你想要赋值的值,而在返回集合时你使用管道来处理它们。事实上,到目前为止,我很少在 PowerShell 中编写 foreach 循环,我主要是从有 C# 或 Java 经验并尝试将逐字代码转换为 PS 的人那里看到的。在我看来$x=foo; foreach($y in $x){...} 是单一的,正常的方式是foo|foreach{...}。你有一个管道。使用它!
      【解决方案3】:

      实际上,foreach 工作得很好。 foreach 的所有使用(foreach 关键字、Foreach-Object cmdlet 和 Foreach-Object 的别名“foreach”和“%”)都具有相同的行为,即在需要时将相关对象“包装”在一个数组中。因此,foreach 的所有用法都适用于标量值和数组值。

      令人讨厌的是,这意味着它们也可以使用空值。说我愿意:

      $x = $null
      foreach ($y in $x) {Write-Host "Hello world 1"}
      $x | Foreach-Object {Write-Host "Hello world 2"}
      

      我会得到的

      "Hello world 1"
      "Hello world 2"
      

      除此之外。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-25
        • 1970-01-01
        • 2021-06-29
        • 2011-10-29
        • 2017-09-13
        • 1970-01-01
        • 1970-01-01
        • 2011-04-10
        相关资源
        最近更新 更多