首页 > 解决方案 > Powershell Get-ADUser 过滤器以排除列表中的特定 OU

问题描述

我正在尝试更改以下 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 过滤器?

标签: powershellscriptingactive-directorypowershell-4.0windows-scripting

解决方案


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

$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子句。

PS for cmdlet 之类的Send-MailMessage带有很多参数的我建议使用Splatting来保持代码的可读性。

希望有帮助


推荐阅读