Powershell Get-ADUser 过滤器以排除列表中的特定 OU

Powershell Get-ADUser filter to exclude specific OU in the list

我正在尝试更改以下 Powershell 脚本,以便它不会从列表中搜索特定 OU 中的任何帐户。

将被报告的AD账户是没有以下任何属性的AD账户:

Phone Number
Mobile/Cellphone Number
Job Title
Email Address.
Company
City
office address

这是我目前拥有的脚本:

    $filter = "(Enabled -eq 'true') -and (mail -notlike '*') -and (company -notlike '*') -and "
$filter += "(l -notlike '*') -and (physicalDeliveryOfficeName -notlike '*') -and "
$filter += "(title -notlike '*') -and (telephoneNumber -notlike '*') -and (mobile -notlike '*')"

$properties = @('mail', 'physicalDeliveryOfficeName', 'Company', 'DisplayName', 'title', 'SamAccountName', 'CanonicalName', 'lastlogondate', 'mobile', 'telephoneNumber', 'l', 'Whencreated', 'DistinguishedName')
$domainDN = (Get-ADDomain).DistinguishedName

$excludeOUs = @(
'OU=Disabled Users,DC=GlobalCorp,DC=com'
    'OU=GlobalCorp Testing,DC=GlobalCorp,DC=com'
    'OU=Admin Accounts,OU=GlobalCorp Global,DC=GlobalCorp,DC=com'
    'OU=Service Accounts,OU=GlobalCorp Global,DC=GlobalCorp,DC=com'
    'OU=Shared Mailboxes,OU=GlobalCorp Global,DC=GlobalCorp,DC=com'
)

$reExcludeOUs = '(?:{0})$' -f ($excludeOUs -join '|')

Get-ADUser -Filter $filter -Properties $properties -SearchBase $domainDN |
    Where-Object {
        ($_.DistinguishedName -notmatch $reExcludeOUs) -and
        ($_.SamAccountName -notmatch '^(SM_|Temp|HealthMailbox)|SVC|Test|admin|$') -and
        ($_.DisplayName -notmatch 'Admin|Calendar|Room')
    } |
    Select-Object -Property `
        DisplayName,
        Company,
        Title,
        TelephoneNumber,
        Mobile,
        PhysicalDeliveryOfficeName,
        SamAccountName,
        Mail,
        @{n = 'OU'; e = { $_.CanonicalName.Remove($_.CanonicalName.LastIndexOf($_.Name) - 1) } },
        @{n = 'CN'; e = { Split-Path $_.CanonicalName -Parent } },
        @{n = 'ParentContainer'; e = { $_.DistinguishedName -replace '^CN=.*?(?=CN|OU)' } },
        LastLogondate,
        WhenCreated | 
        Sort-Object OU | 
        ConvertTo-HTML | 
        Set-Variable HTMLBody

Send-MailMessage -SmtpServer SMTP.GlobalCo.com -From "$env:COMPUTERNAME@$env:userdnsdomain" -To Admin@MSP.com -Subject "AD User Incomplete report as at $((Get-Date).ToString('dd-MM-yyyy'))" -Body ($HTMLBody -join '`n') -BodyAsHTML

如何修改上面的 Where-Object 过滤器?

您可以同时使用 -notcontains-notmatch,但这里的问题是您必须 select DistinguishedName 否则它不会应用该条件,因为它是 'invisible'

Get-ADUser -Filter $filter -Properties $properties -SearchBase $domainDN |
    Select-Object -Property `
        DisplayName,
        Company,
        Title,
        telephoneNumber,
        mobile,
        PhysicalDeliveryOfficeName,
        DistinguishedName,
        ...
        ...

首先,您说您只想报告 没有以下任何属性的用户 。在那种情况下,您的过滤器是错误的,应该更像是:

$filter =  "(Enabled -eq 'true') -and (mail -notlike '*') -and (company -notlike '*') -and "
$filter += "(l -notlike '*') -and (physicalDeliveryOfficeName -notlike '*') -and "
$filter += "(title -notlike '*') -and (telephoneNumber -notlike '*') -and (mobile -notlike '*')"

我将其分散在几行中以使其更具可读性

还有一种构建 $excludeOUs 的方法,即在每个 OU DN 后添加一个逗号。
我建议简单地将其声明为这样的字符串数组:

$excludeOUs = 'OU=Disabled Users,DC=GlobalCorp,DC=com', 
    'OU=GlobalCorp Testing,DC=GlobalCorp,DC=com',
    'OU=Admin Accounts,OU=GlobalCorp Global,DC=GlobalCorp,DC=com',
    'OU=Service Accounts,OU=GlobalCorp Global,DC=GlobalCorp,DC=com',
    'OU=Shared Mailboxes,OU=GlobalCorp Global,DC=GlobalCorp,DC=com'

为了稍后的测试,将它们组合起来创建一个正则表达式:

# create a regular expression string combining the OUs with the 'OR' pipe symbol and wrap that
# inside a non-capturing group. The $ means the match should end in any of the 'OR'-ed ou DNs
$reExcludeOUs = '(?:{0})$' -f ($excludeOUs -join '|')

有了它,你就可以做到

$properties = 'EmailAddress', 'Office', 'Company', 'DisplayName', 'Title', 'SamAccountName', 'DistinguishedName',
              'CanonicalName', 'LastLogonDate', 'MobilePhone', 'OfficePhone','City','Created'
$domainDN = (Get-ADDomain).DistinguishedName

$report = Get-ADUser -Filter $filter -Properties $properties -SearchBase $domainDN |
            Where-Object {
                ($_.DisplayName -notmatch 'Admin|Calendar|Room') -and
                ($_.SamAccountName -notmatch '^(SM_|HealthMailbox)|SVC|Test|admin|$') -and
                ($_.DistinguishedName -notmatch $reExcludeOUs)
            } |
            Select-Object -Property DisplayName, Company, Title, OfficePhone, MobilePhone,
                                    Office, SamAccountName, EmailAddress, City,
                                    @{n = "OU"; e = { $_.CanonicalName.Remove($_.CanonicalName.LastIndexOf($_.Name) - 1) } },
                                    @{n = 'CN'; e = { Split-Path $_.CanonicalName -Parent } },
                                    @{n = 'ParentContainer'; e = { $_.DistinguishedName -replace '^CN=.*?(?=CN|OU)' } },
                                    LastLogonDate, Created

在此之后,$report 变量应该包含您需要保存为 CSV、ConvertToHTML 等的所有信息。

Where-Object{}里面你可以使用正则表达式匹配(-notmatch在这种情况下),所以一个正则表达式可以在这里为你节省很多-notlike子句.

P.S。对于像 Send-MailMessage 这样有很多参数的 cmdlet,我建议使用 Splatting 来保持代码的可读性。

希望对您有所帮助