まず、従業員のアカウントに対して行う必要がある要件について説明します。 そして、ユーザーのニーズに基づいてこれらの要件を推定しようとします。 Active Directory認証を使用して管理者に表示し、作業中に多くの企業システムがADアカウントのさまざまなフィールドを使用することはよく知られています。これらはSharepoint、Citrix、その他多数です。 このようなシステムの例として、MS Outlookを取り上げますが、これは誰にもよく知られていますが、完全ではなく、Active Directoryから直接データを取得するアドレス帳のみです。
ユーザーは何を使用しますか? 私たちの組織では、彼はよく電話の名前、メールアドレス、ユニットの名前を検索します。 もちろん、住所情報も入力しておくと便利ですが、抽象的な人事システムとのバンドルに関するトピックがあるため、住所と電話番号は括弧の外に残します。
最初に、人事システムから取得するフィールドのリストを書き出します。
- 姓名パトロニミック
- 役職
- 組織
- 部門
- 郵便番号
- 雇用形態
メカニズム
人事システムの人とActive Directoryの人をリンクするには、これらの2つのエントリを接続する識別子が必要であることは言うまでもありません。 通常、このような識別子は従業員の従業員番号であり、仕事に応募するときに割り当てられ、二度と変わることはありませんが、従業員番号が静的ではない状況に遭遇しました。その場合、そのような識別子を発明する必要があります。
Active Directoryユーザーに関する情報は、Active Directoryユーザーとコンピュータースナップイン(ADUCの確立された略語)で見ることができる情報に限定されず、使い尽くすにはほど遠いです。 実際、ユーザーオブジェクトには1兆個の属性があり、これらの属性はスキーマ管理者が追加することもできます。 たとえば、運転免許証に関する情報を含むcarLicenseや、ユーザーのお気に入りの飲み物を特徴付けるdrinkなどの属性があります。 一般的に、この意味でマイクロソフトは多くを提供しています。
この例では、 employeeID属性を使用してユーザーIDとflagsを保存します。そのため、少し後で報告します。
また、ユーザーフィールドに入力するために、次の属性を使用します。
- 氏名を保存するためのdisplayNameとCN
- ユニットを保管する部門
- 組織ストレージの会社
- ポストストレージのタイトル
- 従業員タイプを格納するemployeeType
- インデックスストレージ用のpostalCode
したがって、アプリケーションは次のように機能します。
- employeeIDでアカウントを列挙する
- 変更されたデータの各アカウントの人事システムを検索します
- Active Directoryのデータを更新する
- ログファイルの変更
ビジネスへ
最初のステップは、従業員番号を表すemployeeIDをすべてのユーザーに記録することです。 ユーザーが少ない場合、 ADSI Editを使用してこれを行うのが最も簡単です。もう少しあれば、 このように 、処方用のスクリプトを固定できます。 そして、多くのユーザーがいる場合、識別子の配置を委任する必要があり、素敵なインターフェイスと追加のつまらないものを使用したい場合は、ADUCでそのような追加のタブを作成できます。
ただし、このようなタブの作成自体は、別のトピックのトピックです。
2つ目の微妙な点は、特定の属性のみを変更する必要がある人もいることです。 たとえば、私たちには従業員がいます。彼をKudrymunbekov Sadruddin Fathullarovichと呼びましょうが、誰もが単にSan Sanychと呼びます。 そして、人事における役職は、長距離宇宙通信のオープン合資会社「ホーンズアンドホーヴズ」のジェネラルディレクターとしてのみ記録されるゼネラルディレクターがいます。 したがって、アプリケーションのロジックにいくつかの例外を入れる必要があり、これらの例外を同じ場所のActive Directory属性フラグに保存します。 この属性の値は4バイトです。つまり、このビットを1つまたは別の値に設定することにより、必要に応じて最大32個の例外を記憶できます。 ただし、まだ6つだけを使用します。
PowerShellの実装に渡します。
# Active Directory # param($strServer, $strContainer, $strUserName, $strPassword, $strFileName, $strLogName) function Write-LogFile([string]$logFileName) { Process { $_ $dt = Get-Date $str = $dt.DateTime + " " + $_ $str | Out-File -FilePath $logFileName -Append } } # , # . 1, # , Oracle e-Buisness suite, # csv-. # , Import-CSV , # , - , function Get-Employee($employeeID, $fileName, [ref]$title, [ref]$department, [ref]$displayName, [ref]$company, [ref]$postalCode, [ref]$employeeType) { $records = $fileName | Import-CSV -Delimiter ";" $employee = $records | where-object {$_.EmployeeID -eq $employeeID} if ($employee -eq $null) {return $false} $title.Value = [string]$employee.Title $department.Value = [string]$employee.Department $displayName.Value = [string]$employee.Name $company.Value = [string]$employee.Company $postalCode.Value = [string]$employee.PostalCode $employeeType.Value = [string]$employee.EmployeeType return $true } # "---" | Write-LogFile $strLogName " :" | Write-LogFile $strLogName ": " + $strServer | Write-LogFile $strLogName ": " + $strContainer | Write-LogFile $strLogName " : " + $strUserName | Write-LogFile $strLogName ": " + $strPassword | Write-LogFile $strLogName " : " +$strFileName | Write-LogFile $strLogName " : " + $strLogName | Write-LogFile $strLogName # , # , 000001, 000010, 000100, 001000, 010000 100000 # . , , # New-Variable -Option constant -Name C_COMPANY_FLAG -Value 1 New-Variable -Option constant -Name C_POSTALCODE_FLAG -Value 2 New-Variable -Option constant -Name C_TITLE_FLAG -Value 4 New-Variable -Option constant -Name C_DEPARTMENT_FLAG -Value 8 New-Variable -Option constant -Name C_NAME_FLAG -Value 16 New-Variable -Option constant -Name C_EMPLOYEETYPE_FLAG -Value 32 # title. title # http://msdn.microsoft.com/en-us/library/windows/desktop/ms680037(v=VS.85).aspx # 64 Windows Server 2003 # 128 Windows Server 2008 # , New-Variable -Option constant -Name C_PARAMETERS_LENGTH -Value 64 # (!userAccountControl:1.2.840.113556.1.4.803:=2) " " $strFilter = "(&(objectClass=user)(!objectClass=computer)(employeeID=*)(!userAccountControl:1.2.840.113556.1.4.803:=2))" # , , Active Directory Windows Server 2008 # http://blogs.msdn.com/adpowershell # Windows Server 2003 Windows XP, # $objDomain = New-Object System.DirectoryServices.DirectoryEntry("LDAP://"+$strServer+"/"+$strContainer) $objSearcher = New-Object System.DirectoryServices.DirectorySearcher $objSearcher.SearchRoot = $objDomain $objSearcher.PageSize = 1000 $objSearcher.Filter = $strFilter $objSearcher.SearchScope = "Subtree" $colProplist = "employeeID","postalCode","title","department", "displayName", "cn", "employeeType" foreach ($i in $colPropList) { $objSearcher.PropertiesToLoad.Add($i) } $colResults = $objSearcher.FindAll() # colResults $startTime = Get-Date $totalCount = $colResults.Count $i = 0 foreach ($objResult in $colResults) { $objItem = $objResult.Properties $aDEmployeeID = $objItem.employeeid # , flags, # , , $flagProtectCompany = $false $flagProtectPostalCode = $false $flagProtectTitle = $false $flagProtectDepartment = $false $flagProtectName = $false $flagProtectEmployeeType = $false if (!($objItem.flags -eq $null)) { $flags = $objItem.flags if (($flags[0] -band $C_COMPANY_FLAG) -ne 0) {$flagProtectCompany = $true} if (($flags[0] -band $C_POSTALCODE_FLAG) -ne 0) {$flagProtectPostalCode = $true} if (($flags[0] -band $C_TITLE_FLAG) -ne 0) {$flagProtectTitle = $true} if (($flags[0] -band $C_DEPARTMENT_FLAG) -ne 0) {$flagProtectDepartment = $true} if (($flags[0] -band $C_NAME_FLAG) -ne 0) {$flagProtectName = $true} if (($flags[0] -band $C_EMPLOYEETYPE_FLAG) -ne 0) {$flagProtectEmployeeType = $true} } # , $cSVName = "" $cSVTitle = "" $cSVDepartment = "" $cSVCompany = "" $cSVPostalCode = "" $cSVEmployeeType = "" # PowerShell, # , $rc = Get-Employee $aDEmployeeID $strFileName ([ref]$cSVTitle) ([ref]$cSVDepartment) ([ref]$cSVName) ([ref]$cSVCompany) ([ref]$cSVPostalCode) ([ref]$cSVEmployeeType) if ($rc) { # , # . , # , , # $objDirectoryEntry = new-object System.DirectoryServices.DirectoryEntry($objItem.adspath, $strUsername, $strPassword, [System.DirectoryServices.AuthenticationTypes]::Secure) $oTitle = $cSVTitle if ($oTitle.Length -gt $C_PARAMETERS_LENGTH) {$oTitle = $oTitle.Substring(0,$C_PARAMETERS_LENGTH)} $oDepartment = $cSVDepartment if ($oDepartment.Length -gt $C_PARAMETERS_LENGTH) {$oDepartment = $oDepartment.Substring(0,$C_PARAMETERS_LENGTH)} $newEmployeeType = $cSVEmployeeType # , , , , # ( ). if (($newEmployeeType -ne $objItem.employeetype) -and -not $flagProtectEmployeeType) { " EmployeeType """ + $objDirectoryEntry.name + """" | Write-LogFile $strLogName " """ + $objDirectoryEntry.employeetype + """ """ + $newEmployeeType + """" | Write-LogFile $strLogName $objDirectoryEntry.employeetype = [string]$newEmployeeType $objDirectoryEntry.CommitChanges() } if (($cSVCompany -ne $objItem.company) -and -not $flagProtectCompany) { " """ + $objDirectoryEntry.name + """" | Write-LogFile $strLogName " """ + $objDirectoryEntry.company + """ """ + $cSVCompany + """" | Write-LogFile $strLogName $objDirectoryEntry.company = [string]$cSVCompany $objDirectoryEntry.CommitChanges() } if (($cSVPostalCode -ne $objItem.postalcode) -and -not $flagProtectPostalCode) { " """ + $objDirectoryEntry.name + """" | Write-LogFile $strLogName " """ + $objDirectoryEntry.postalCode + """ """ + $cSVPostalCode + """" | Write-LogFile $strLogName $objDirectoryEntry.postalCode = $cSVPostalCode $objDirectoryEntry.CommitChanges() } if (($oTitle -ne $objItem.title) -and -not $flagProtectTitle) { " """ + $objDirectoryEntry.name + """" | Write-LogFile $strLogName " """ + $objDirectoryEntry.title + """ """ + $cSVTitle + """" | Write-LogFile $strLogName if ($title.Length -gt $C_PARAMETERS_LENGTH) { $objDirectoryEntry.title = $cSVTitle.Substring(0,$C_PARAMETERS_LENGTH) } else { $objDirectoryEntry.title = $cSVTitle.ToString() } $objDirectoryEntry.CommitChanges() } if (($oDepartment -ne $objItem.department) -and -not $flagProtectDepartment) { " """ + $objDirectoryEntry.name + """" | Write-LogFile $strLogName " """ + $objDirectoryEntry.department + """ """ + $cSVDepartment + """" | Write-LogFile $strLogName if ($department.Length -gt $C_PARAMETERS_LENGTH) { $objDirectoryEntry.department = $cSVDepartment.Substring(0,$C_PARAMETERS_LENGTH) } else { $objDirectoryEntry.department = $cSVDepartment.ToString() } $objDirectoryEntry.description = $cSVDepartment.ToString() $objDirectoryEntry.CommitChanges() } if ((($cSVName -ne $objItem.displayname) -or ($cSVName -ne $objItem.cn)) -and -not $flagProtectName) { " """ + $objDirectoryEntry.name + """" | Write-LogFile $strLogName " """ + $objDirectoryEntry.displayname + """ """ + $cSVName + """" | Write-LogFile $strLogName $objDirectoryEntry.displayName = $cSVName $objDirectoryEntry.CommitChanges() $objDirectoryEntry.Rename("cn="+$cSVName) } $i++ # , # , , , $status = $i.ToString() + " of " + $totalCount.ToString() + " complete - " + $objDirectoryEntry.name $currentTime = Get-Date $diffTime = [int][System.Math]::Round(($currentTime - $startTime).Ticks / $i) $delta = $diffTime*$totalCount $endTime = $startTime.Add([int64]($delta)) $activityString = " . " + $endTime Write-Progress -Activity $activityString -Status $status -PercentComplete (($i / $totalCount) * 100) } } " " | Write-LogFile $strLogName # , Write-Host `a
テスト環境を作成し、アカウントに絶対にランダムに名前を割り当てます。
次に、パラメーターを指定してスクリプトを実行します。 もちろん、チートしてスケジュールどおりに実行できます。タスクを実行するアカウントを忘れずに、 バッチタスクとしてログインする権利を割り当ててください。
ご覧のとおり、実行後、読みやすい名前、優れた投稿、素晴らしい会社名が得られました。
もちろん、スクリプトを少し変更するだけで、電話や住所から悪名高いお気に入りの飲み物まで、すべてをユーザーに入力できます。 また、一定の規則でスクリプトを実行すると、すべてのユーザーデータが最新であることを確認できます。
upd小さなエラーを修正し、リセットフラグをループの内側に移動しました