关于powershell:将AD与CSV进行比较

Compare AD against CSV

我正在尝试创建一个脚本,将我们的广告与CSV中的所有用户进行比较。我们的HR部门拥有所有员工的主数据库,但是当他们进行更改时,他们很少通知我们,因此他们现在将所有用户从HR数据库导出到CSV。

我需要将此与我们的广告进行比较,并修改已发现已更改的任何人员或任何新员工。

我有以下脚本,但它只输出所有人员,我只希望通过电子邮件发送已更改的人员或不在AD中的新人员。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
write-host"Using default CSV file or C:\\scripts\\csv\\StaffChanges.csv"
$StaffCSVUPath ="C:\\scripts\\csv\\StaffChanges.csv"

$logfile ="C:\\scripts\\logs\\ADvsCMIS.csv"

if(test-path $logfile) {
    remove-item $logfile -force
}

function Email {
    #Send an email, called with recipient email address and message body
    param(
        [string] $emailaddress="",
        [string] $bodymsg=""
    )
    $bodymsg +="<p>"
    $bodymsg += Get-Content($logfile)
    Send-MailMessage -To $emailaddress -From"[email protected]" -Subject"(AD-CMIS_errors) Errors found between Active Directory and CMIS" -Body $bodymsg -BodyAsHTML -SMTPServer"exchserver"
}


function CheckOutputFile {
    #Called with folder\\filename and type of file
    param(
        [string]$outputfilename ="",
        [string]$type =""
    )
    if(test-path($outputfilename)) {
    } else {
        write-host"Creating $outputfilename"
        $msg ="Forename,Surname,Username,ID"
        $msg | out-file($outputfilename)
    }
}

#Snap-ins needed to use the commands within the script
if((Get-pssnapin -Name Microsoft.Exchange.Management.Powershell.E2010 -ErrorAction SilentlyContinue) -eq $null){Add-PSSnapin  Microsoft.Exchange.Management.PowerShell.E2010}
if((Get-pssnapin -Name Quest.activeroles.admanagement -ErrorAction SilentlyContinue)-eq $null){Add-pssnapin Quest.activeroles.admanagement}

#import users from csv file
$users = (import-Csv $StaffCSVUpath)
$count=0
$countAD=0

Get-QADUser -searchroot"domain/Users/Staff" -SizeLimit 0 -includedproperties employeeid,displayname | ForEach-Object ($_.samaccountname) {
    $found = 0
    $countAD+=1
    ForEach ($user in $users) {
        $count+=1
        $inital = $user.forename.substring(0,1)
        $name = $user.forename+""+$user.surname
        $dispname = $inital+""+$user.surname
        if ($user.id -eq $_.employeeid) {
            if ($user.surname -eq $_.lastname) {
                if ($inital -eq $_.firstname) {
                    if ($name -eq $_.name) {
                        if ($dispname -eq $_.displayname) {
                            $found = 1
                        }
                    }
                }
            }
        }
        if ($found -eq 1){break}
    }
    if ($found -eq 0) {
        if(($_.company -ne"testing") -band ($_.company -ne"service")) {
            CheckOutputFile $logfile"LOG"
            $msg ="<p>" + $_.firstname +"" + $_.lastname +"" + $_.samaccountname +""+$_.employeeid +"<p>"
            $msg | Out-File $logfile -append
        }
    }
}

if (test-path $logfile) {
    #If there is anything to report
    write-host"Emailing Log file to ict"
    #Email file if $outputB exists
    $email ="[email protected]"
    $body ="Action Required: The users below do not exist within HR.  Contact HR Data manager to resolve issue, delete users manually if required."
    #email ict
    Email $email $body
}


我设法通过更改搜索字段来使其工作

1
2
3
    if($user.firstname -eq $_.firstname)
    if($user.surname -eq $_.sn)
    if($user.ID -eq $_.employeeID)

这现在将对照CSV检查AD,通过电子邮件发送任何差异,并排除所有名称为" test"或" careers"的电子邮件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
write-host"Using default CSV file or C:\\scripts\\csv\\StaffChanges.csv"
$StaffCSVUPath ="C:\\scripts\\csv\\StaffChanges.csv"

$logfile ="C:\\scripts\\logs\\ADvsHR.csv"

if(test-path $logfile) {
    remove-item $logfile -force
}

function Email {
    #Send an email, called with recipient email address and message body
    param(
        [string] $emailaddress="",
        [string] $bodymsg=""
    )
    $bodymsg +="<p>"
    $bodymsg += Get-Content($logfile)
    Send-MailMessage -To $emailaddress -From"[email protected]" -Subject"(AD-CMIS_errors) Errors found between Active Directory and CMIS" -Body $bodymsg -BodyAsHTML -SMTPServer"exchserver"
}


function CheckOutputFile {
    #Called with folder\\filename and type of file
    param(
        [string]$outputfilename ="",
        [string]$type =""
    )
    if(test-path($outputfilename)) {
    } else {
        write-host"Creating $outputfilename"
        $msg ="Forename,Surname,Username,ID"
        $msg | out-file($outputfilename)
    }
}

#Snap-ins needed to use the commands within the script
if((Get-pssnapin -Name Microsoft.Exchange.Management.Powershell.E2010 -ErrorAction SilentlyContinue) -eq $null){Add-PSSnapin  Microsoft.Exchange.Management.PowerShell.E2010}
if((Get-pssnapin -Name Quest.activeroles.admanagement -ErrorAction SilentlyContinue)-eq $null){Add-pssnapin Quest.activeroles.admanagement}

#import users from csv file
$users = (import-Csv $StaffCSVUpath)
$count=0
$countAD=0

Get-QADUser -searchroot"domain/Users/Staff" -SizeLimit 0 -includedproperties employeeid,displayname | ForEach-Object ($_.samaccountname) {
    $found = 0
    $countAD+=1
    ForEach ($user in $users) {
        $count+=1
        if ($user.firstname -eq $_.firstname) {
            if ($user.surname -eq $_.sn) {
                if ($user.ID -eq $_.employeeID) {
                            $found = 1
                }
            }
        }
        if ($found -eq 1){break}
    }
    if ($found -eq 0) {
        if(($_.firstname -ne"careers") -band ($_.firstname -ne"test")) {
            CheckOutputFile $logfile"LOG"
            $msg ="<p>" + $_.firstname +"" + $_.lastname +""+$_.employeeid +"<p>"
            $msg | Out-File $logfile -append
        }
    }
}

if (test-path $logfile) {
    #If there is anything to report
    write-host"Emailing Log file to ict"
    #Email file if $outputB exists
    $email ="[email protected]"
    $body ="Action Required: The users below do not exist within HR.  Contact HR Data manager to resolve issue, delete users manually if required."
    #email ict
    Email $email $body
}

我不使用Quest AD cmdlet,所以我的答案将基于内置的cmdlet。另外,我将假设任何给定雇员的(唯一)雇员ID都不会更改,并且没有用户帐户具有空的employeeId属性。

首先,准备数据如下:

1
2
3
4
5
6
7
8
9
10
11
12
Import-Module ActiveDirectory

$hrUsers = @{}
Import-Csv 'C:\\path\\to\\your.csv' |
  select id, firstname, surname,
         @{n='inital';e={$_.forename.substring(0,1)}},
         @{n='name';e={$_.forename+""+$_.surname}},
         @{n='dispname';e={$_.forename.substring(0,1)+""+$_.surname}} |
  % { $hrUsers[$_.id] = $_ }

$adUsers = Get-ADUser -Filter * -Property employeeid |
           ? { 'testing', 'service' -notcontains $_.company }

这将创建一个哈希表,将每个员工ID映射到具有相应用户属性(包括派生属性initialnamedispname)和AD用户列表(不包括服务和测试帐户)的对象。

使用上述方法,您可以像这样确定新用户:

1
2
$employeeIDs = @($adUsers | select -Expand employeeId)
$hrUsers.Values | ? { $employeeIDs -notcontains $_.id }

这样的过时帐户:

1
$adUsers | ? { $hrUsers.Keys -notcontains $_.employeeId }

和这样的修改用户:

1
2
3
4
5
6
$adUsers | ? {
  $hrUsers[$_.employeeid].surname -ne $_.lastname -or
  $hrUsers[$_.employeeid].inital -ne $_.firstname -or
  $hrUsers[$_.employeeid].name -ne $_.name -or
  $hrUsers[$_.employeeid].dispname -ne $_.displayname
}