首页 > 解决方案 > 如何在Powershell中为变量分配多个“where”条件

问题描述

我正在开发一个 Powershell 脚本(带有 GUI),以帮助我的同事更轻松地找到冗余和禁用的 AD 帐户。

这是一个小预览......

$props = "Name, Enabled, PasswordExpired, Company,passwordNeverExpires, Office"

$propsAsArray = $props -split ',\s*'

Get-ADUser -filter * -properties $propsAsArray | where {$_.Enabled -eq $true} | where {$_.PasswordNeverExpires -eq $false}| where {$_.passwordexpired -eq $false} | Select-Object $propsAsArray | Export-csv -Path "C:\report.csv"

这一切正常并输出 CSV 报告。

但问题是如何将 AD 帐户状态的所有可能组合和排列分配给变量,然后将变量替换为Get-ADUsercmdlet(取决于用户在 GUI 中单击的单选按钮)。

我已经尝试了所有能想到的,但只能找回错误Expressions are only allowed as the first element of a pipeline

我确信$accountStatus = "where {$_.Enabled -eq $true} | where {$_.PasswordNeverExpires -eq $false}"(或微妙的变体)不是它的完成方式。

我对 Powershell 比较陌生,并且渴望获得经验。谢谢,威廉。

标签: windowspowershellactive-directory

解决方案


注意:此答案解决了所提出的问题,使用基于脚本块( )的基于广义Where-Object{ ... }的解决方案,但在手头的情况下,基于字符串的解决方案基于Get-ADUser's参数,它在源处-Filter有效过滤,如托马斯回答中的第二个命令更可取。


将表示条件的脚本块数组( { ... }) 存储在变量中,并使用索引数组根据用户的 GUI 选择来选择要应用的条件:

# All individual conditions to test, expressed as an array of script blocks.
# Note: No need for `-eq $true` to test Boolean properties, and
#       `-eq $false` is better expressed via the `-not` operator.
$blocks = 
  { $_.Enabled },
  { -not $_.PasswordNeverExpires },
  { $_.PasswordExpired }


# Select the subset of conditions to apply using AND logic, using 
# an array of indices, based on the GUI selections.
$indices = 0..2   # e.g., all 3 conditions (same as: 0, 1, 2)

Get-ADUser -Filter * -properties $propsAsArray | Where-Object { 
  # The following is equivalent to combining the conditionals of interest
  # with -and (AND logic):
  foreach ($block in $blocks[$indices]) { # Loop over selected conditionals
    if (-not (& $block)) { return $false } # Test, and return $false instantly if it fails.
  }
  $true # Getting here means that all conditions were met.
}

注意每个块是如何通过调用操作符&执行的。


推荐阅读