【问题标题】:Powershell - replacing codeblock with variablePowershell - 用变量替换代码块
【发布时间】:2012-10-02 22:12:03
【问题描述】:

我有一个关于语句中的代码块和变量的简单问题。我的脚本收集用户输入并创建一个字符串,以便稍后在 powershell 语句中使用。

$filter = @()
While ($filter[-1] -ne "end") {
  $filter += read-host 'Type the name of an OU you want to filter or type "end" to start the script'
  if ($filter[-1] -eq "end") {
    break
  }
  $strFilter += "`$_`.DistinguishedName -notlike `"*" + $filter[-1] + "*`" "
  $strFilter += "-and "
}
$strFilter = $strFilter.SubString(0,$strFilter.length-5)

基本上,用户会输入任意数量的单词,这些单词将被附加到字符串"$_.DistinguishedName -notlike "*<WORD>*"" 中,并与-and 放在一起,直到输入最后一个单词。

这部分工作正常,它使用这个生成的字符串来收集似乎不起作用的信息;我有一种感觉,我只是缺少一些非常简单的东西。

例如:

$computers = get-adcomputer -Filter 'ObjectClass -eq "Computer"' -properties "OperatingSystem","CanonicalName","Description"
$filteredComputers = $computers | where-object { $strFilter }

$filteredComputers 返回与 $computers 相同的结果,这让我相信带有我的字符串变量的 Where-object 语句没有做任何事情。

感谢任何帮助,谢谢。

【问题讨论】:

    标签: variables powershell active-directory


    【解决方案1】:

    Where-Object 脚本块应计算为布尔值(或可以强制为布尔值的东西)。您只提供了一个字符串,如果不是空的,PowerShell 将强制转换为布尔值 $true。试试这样的:

    $strFilter = @()
    while (...) { ...
        $strFilter += "*$($filter[-1])*"
    }
    
    $filteredComputers = $computers | 
       Where {$dn=$_.DistinguishedName; @($strFilter | Where {$dn -like $_}).Count -eq 0}
    

    这使用嵌套管道遍历每个过滤器术语并将其应用于当前对象的 DistinguishedName - 我们必须隐藏它,因为在嵌套管道中 $_ 采用当前 $strFilter 数组元素的值。如果其中任何一个通过了like 测试,那么计数将大于零并且不会通过管道传递。只有那些不匹配的(count == 0)才应该被传递到管道中。

    这是这种方法的一个示例:

    C:\PS> $strFilter = '*ba*','*bog*'
    C:\PS> 'foo','bar','baz','abba','boggle' | 
               Where {$dn=$_; @($strFilter | Where {$dn -like $_}).Count -eq 0}
    
    foo
    

    【讨论】:

    • ($strFilter | Where {$dn -like $_}).Count -eq 0 似乎将所有内容都标记为 false,例如,“域控制器”的输入字符串仍将返回 false,即使它不属于任何域控制器 OU。不应该是真的,因为有 0 场比赛吗?也许我误解了什么?
    • 这意味着它正在寻找与$strFilter 中的过滤条件之一匹配的内容。 $strFilter的内容是什么?也许你有一个不应该的过滤词 - 也许是**
    • 我不相信 ** 被匹配,如果您在第一个将实例收集到数组中的 while 循环中按 Enter 键,那么会出现 **,我会通常在尝试过滤我的结果之前检查这一点。当我复制粘贴上面的示例时,不会返回 foo。
    • 最后一个示例适用于 V3,但不适用于 V2。我更新了示例,因此它们应该适用于 V2 和 V3。另外,你能在while循环之后转储$strFilter的内容吗?
    • 所以我运行 while 循环并在出现提示时输入类似 domain controllers 的内容,然后输入 end 以完成 while 循环。调用 $strFilter 将返回:*domain controllers*,因为您编写了 $strFilter += "*$($filter[-1])*"。希望有帮助
    【解决方案2】:

    在您运行此代码的时间点:

    $filteredComputers = $computers | where-object { $strFilter }

    $strfilter 的值是多少?

    如果您回显 $strfilter 的值,请尝试在其位置手动输入该值,是否有效?如果是的话,那么话是对的,但是执行方法是错误的。

    【讨论】:

      【解决方案3】:

      例如,我们只需要从我们的用户文件夹中获取文件夹 Documents 或“我的文档”:

      [scriptblock]$filterBlock = { $_.Name -like '*ocum*' }
      dir | ?{ & $filterBlock }
      

      答案由两部分组成: 1)将您的字符串转换为 [ScriptBlock] 2) 使用 & 字符来调用你的字符串(即你的脚本块)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-24
        相关资源
        最近更新 更多