Created
April 16, 2015 16:05
-
-
Save strike/89e31bd4d92c93b0f6a9 to your computer and use it in GitHub Desktop.
SyncADWith1C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.DESCRIPTION | |
This script sync AD (tree and users) with csv files (exported from 1c) | |
.AUTHOR Zubarev Alexander aka Strike ([email protected]) | |
.LINK | |
http://... | |
#> | |
#config file | |
Set-Location ($MyInvocation.MyCommand.Definition | split-path -parent) #move to cur dir | |
[xml]$CF = Get-Content "Config.xml" | |
$Patch = $CF.cfg.patch | |
Import-Module ActiveDirectory | |
$PatchFolder = Get-ChildItem -Path "$Patch" | Select-Object Name | |
$date = Get-Date -Format 'dd.MM.yyyy' | |
$date = '07.04.2015' | |
#create temp dir | |
$TempDir = [System.Guid]::NewGuid().ToString() | |
Set-Location $env:temp | |
New-Item -Type Directory -Name $TempDir | |
Set-Location $TempDir | |
#create header for file | |
echo "UserLogin`tLastUserLogin`tAccountId" > "DuplicateLogin.csv" | |
echo "Detailedname`tUserLogin`tPassword`tDepartament`tOU" > "Login.csv" | |
echo "OU`tUserLogin`tPassword" > "Error.csv" | |
echo "" > "Log.txt" | |
#пути в AD | |
$root = "OU=Staff,DC=ad,DC=guu,DC=ru" | |
$group = "OU=Группы,$root" | |
$dismissed = "OU=Уволенные,$root" | |
$withOutGUID = "OU=Без подразделения,$root" | |
#Настройка SMTP | |
$smtp = New-Object System.Net.Mail.SmtpClient($CF.cfg.smtp.server, $CF.cfg.smtp.port); | |
$smtp.EnableSSL = $true | |
$smtp.Credentials = New-Object System.Net.NetworkCredential($CF.cfg.smtp.username, $CF.cfg.smtp.password); | |
$message = New-Object System.Net.Mail.MailMessage | |
$message.subject = "AD Sync script ($date)" | |
$message.from = $CF.cfg.message.from | |
foreach ($mailTo in $CF.cfg.message.to.ChildNodes ){ | |
$message.to.add($mailTo.InnerText) | |
} | |
$messageBody = "" | |
function log { | |
$txt = $args[0] | |
$timestamp = (Get-Date).ToString() | |
echo "$txt" | |
echo "${timestamp}: $txt" >> Log.txt | |
} | |
Function Get-Seed{ $RandomBytes = New-Object -TypeName 'System.Byte[]' 4 $Random = New-Object -TypeName 'System.Security.Cryptography.RNGCryptoServiceProvider' $Random.GetBytes($RandomBytes) [BitConverter]::ToInt32($RandomBytes, 0) | |
} | |
function genPassword { | |
$MinPasswordLength = 8 | |
$MaxPasswordLength = 10 | |
$InputStrings = @('abcdefghijkmnpqrstuvwxyz', 'abcdefghijkmnpqrstuvwxyz', 'ABCDEFGHIJKMNPQRSTUVWXYZ', 'ABCDEFGHIJKMNPQRSTUVWXYZ', '23456789', '23456789', '!@#$') | |
$Count = 1 | |
[char[][]]$CharGroups = $InputStrings | |
[int[]]$UsedGroups = for($i=0;$i -lt $CharGroups.Count;$i++){0} | |
if($MinPasswordLength -eq $MaxPasswordLength) { $password = New-Object -TypeName 'System.Char[]' $MinPasswordLength } else { $password = New-Object -TypeName 'System.Char[]' (Get-Random -SetSeed $(Get-Seed) -Minimum $MinPasswordLength -Maximum $($MaxPasswordLength+1)) } | |
for($i=0;$i -lt $password.Length;$i++){ | |
if($i -ge ($password.Length - ($UsedGroups | Where-Object {$_ -eq 0}).Count)) { | |
$CharGroupIndex = 0 | |
while(($UsedGroups[$CharGroupIndex] -ne 0) -and ($CharGroupIndex -lt $CharGroups.Length)) { $CharGroupIndex++ } } else { $CharGroupIndex = Get-Random -SetSeed $(Get-Seed) -Minimum 0 -Maximum $CharGroups.Length } $password[$i] = Get-Random -SetSeed $(Get-Seed) -InputObject $CharGroups[$CharGroupIndex] | |
$UsedGroups[$CharGroupIndex] = $UsedGroups[$CharGroupIndex] + 1 | |
} | |
$script:Password = $password -join ''} | |
log("Init sync") | |
$isErrors = $false | |
$isDuplicateLogin = $false | |
try { $FileTree = ($PatchFolder | Select-String -pattern "\bOU_$date.*" | % { $_.Matches } | % { $_.Value }).Replace("}","") } catch {} | |
try { $FileStaffs = ($PatchFolder | Select-String -pattern "\b$date.*" | % { $_.Matches } | % { $_.Value }).Replace("}","") } catch {} | |
try { | |
$Tree = Import-Csv -Delimiter "`t" -Path "$Patch\\$FileTree" | |
} catch { | |
log("Tree file not found!") | |
$message.subject = "AD Sync script ($date) file ERROR" | |
$message.body = "Tree file not found!" | |
$smtp.send($message) | |
exit | |
} | |
try { | |
$Staffs = Import-Csv -Delimiter "`t" -Path "$Patch\\$FileStaffs" | |
} catch { | |
log("Staffs file not found!") | |
$message.subject = "AD Sync script ($date) file ERROR" | |
$message.body = "Staffs file not found!" | |
$smtp.send($message) | |
exit | |
} | |
#Create new OU | |
log("Check and creating new OU..") | |
$someAdd = $true | |
$OUAddCount = 0; | |
for ($i=0; $i -le 10; $i++){ | |
if (!$someAdd){ | |
break; | |
} | |
$someAdd = $false | |
$allOU = Get-ADOrganizationalUnit -Filter * -SearchBase "$root" -Properties Description | |
foreach ($ou in $Tree) | |
{ | |
echo $ou | |
if (![bool]::Parse($ou.NotRelevant)){ | |
$thisOU = $allOU | Where {$_.Description -cmatch $ou.OUGUID} | |
if ($thisOU){ | |
continue | |
} | |
$normalOU=$ou.OU.Replace(",","\,").Replace("""","") | |
if($normalOU.Length -ge 60){ | |
$normalOU = $normalOU.Substring(0,60); | |
} | |
$normalOU = $normalOU.Trim(); | |
if ($ou.OUParrent -eq ""){ | |
$addOU = "OU=" + $normalOU + ",$root" | |
} else { | |
$allOU = Get-ADOrganizationalUnit -Filter * -SearchBase "$root" -Properties Description | |
$pOu = $allOU | Where {$_.Description -cmatch $ou.OUParrentGUID} | |
if ($pOu){ | |
$addOU = "OU=" + $normalOU + "," + $pOu.DistinguishedName + "" | |
$allOU = Get-ADOrganizationalUnit -Filter * -SearchBase "$root" -Properties Description | |
$addDuplicateOU = $allOU | Where {$_.DistinguishedName -eq $addOU} | |
if ($addDuplicateOU){ | |
$desc = $addDuplicateOU.Description + "," + $ou.OUGUID | |
Set-ADObject -Identity $addDuplicateOU.DistinguishedName -Description "$desc" | |
log("!DuplucateOU (with one GUID): $addDuplicateOU.DistinguishedName") | |
continue | |
} | |
} else { | |
continue | |
} | |
} | |
log("Added OU: $addOU") | |
$OUAddCount++ | |
dsadd ou "$addOU" -desc $ou.OUGUID | |
$someAdd = $true | |
} | |
} | |
} | |
log("Check, add, activate and deactivate USERS") | |
$UserAddCount = 0; $UserUpdCount = 0; $UserDisableCount = 0; | |
$allou = Get-ADOrganizationalUnit -Filter * -SearchBase "$root" -Properties Description | |
foreach ($User in $Staffs) { | |
if (![bool]::Parse($User.MainJob)){ | |
continue | |
} | |
if ( ([bool]::Parse($User.MainJob)) -and (![bool]::Parse($User.Enabled)) ){ | |
continue | |
} | |
$AccountId = $User.Id | |
$UserLogin = $User.Login | |
$OUGUID = $User.OUGUID | |
$Enabled = [bool]::Parse($User.Enabled) | |
$Detailedname = $User.LastName + " " + $User.FirstName + " " + $User.MiddleName | |
$UserFirstname = $User.FirstName.Trim(); | |
$UserLastName = $User.LastName.Trim(); | |
$Title = $User.JobTitle.Trim(); | |
$Password = "" #use genPassword | |
$Department = $User.OU | |
if($Department.Length -ge 60){ | |
$Department = $Department.Substring(0,60); | |
} | |
$Department = $Department.Trim(); | |
#search manager | |
$ManagerGUID = $User.ManagerGUID | |
$Manager = (Get-ADUser -Filter 'EmployeeNumber -eq $ManagerGUID').SamAccountName | |
$Company = "ФГБОУ ВПО «Государственный университет управления»" | |
$UserGroup = $User.GroupType | |
#preambule end | |
#if user alryedy exist in AD | |
$ExistUser = Get-ADUser -Filter 'EmployeeNumber -eq $AccountId' -Properties DisplayName, Surname, Title, Department, Manager, Company, EmployeeNumber | |
echo $AccountId | |
echo $ExistUser | |
echo $Detailedname | |
if ($ExistUser){ | |
$upd = $false | |
$UserLogin = $ExistUser.SamAccountName | |
#check OU | |
$OU = ($ExistUser | select *,@{l='Parent';e={([adsi]"LDAP://$($_.DistinguishedName)").Parent}}).Parent.Replace("LDAP://","") | |
$OU = Get-ADOrganizationalUnit $OU -Properties Description | |
if (!($OU.Description -cmatch $User.OUGUID)){ | |
$upd = $true | |
log("$UserLogin change OU: $($OU.Description) -> $($User.OUGUID) ($($OU.Name) -> $($User.OU))" ) | |
$ou = $allou | Where {$_.Description -cmatch $User.OUGUID} | |
if ($ou) { | |
$OU = $ou.DistinguishedName | |
} else { | |
$OU = $withOutGUID | |
} | |
$ExistUser | Move-ADObject -TargetPath "$OU" | |
} | |
#check Name (CN) | |
if ($ExistUser.Name -ne $Detailedname){ | |
$upd = $true | |
log("$UserLogin change Name (CN): $($ExistUser.Name) -> $Detailedname" ) | |
$ExistUser | Rename-ADObject -NewName "$Detailedname" | |
} | |
#check DisplayName | |
if ($ExistUser.DisplayName -ne $Detailedname){ | |
$upd = $true | |
log("$UserLogin change DisplayName: $($ExistUser.DisplayName) -> $Detailedname" ) | |
Set-ADUser -Identity $ExistUser.SamAccountName -DisplayName $Detailedname | |
} | |
#check GivenName | |
if ($ExistUser.GivenName -ne $UserFirstName){ | |
$upd = $true | |
log("$UserLogin change GivenName: $($ExistUser.GivenName) -> $UserFirstName") | |
Set-ADUser -Identity $ExistUser.SamAccountName -GivenName "$UserFirstName" | |
} | |
#check Surname | |
if ($ExistUser.Surname -ne $UserLastName){ | |
$upd = $true | |
log("$UserLogin change Surname: $($ExistUser.Surname) -> $UserLastName") | |
Set-ADUser -Identity $ExistUser.SamAccountName -Surname $UserLastName | |
} | |
#check Title | |
if ($ExistUser.Title -ne $Title){ | |
$upd = $true | |
log("$UserLogin change Title: $($ExistUser.Title) -> $Title") | |
Set-ADUser -Identity $ExistUser.SamAccountName -Title $Title | |
} | |
#check Department | |
if ($ExistUser.Department -ne $Department){ | |
$upd = $true | |
log("$UserLogin change Department: $($ExistUser.Department) -> $Department") | |
Set-ADUser -Identity $ExistUser.SamAccountName -Department $Department | |
} | |
#check manager | |
if ($Manager){ | |
$DNManager = (Get-ADUser $Manager).DistinguishedName | |
if ($ExistUser.Manager -ne $DNManager){ | |
$upd = $true | |
log("$UserLogin change Manager: $($ExistUser.Manager) -> $Manager") | |
Set-ADUser -Identity $ExistUser.SamAccountName -Manager $Manager | |
} | |
} | |
#check organisation | |
if ($ExistUser.Company -ne $Company){ | |
$upd = $true | |
log("$UserLogin change Company: $($ExistUser.Company) -> $Company") | |
Set-ADUser -Identity $ExistUser.SamAccountName -Company $Company | |
} | |
#check enable | |
if($ExistUser.Enabled -ne $Enabled) { | |
log("$UserLogin change Enable (status): $($ExistUser.Enabled) -> $Enabled") | |
if ($Enabled) { | |
Enable-ADAccount -Identity "$UserLogin" | |
} else { | |
$UserDisableCount++ | |
Disable-ADAccount -Identity "$UserLogin" | |
} | |
} | |
if ($upd){ | |
$UserUpdCount++ | |
} | |
} else { | |
# add new user | |
if ($Enabled){ | |
$ou = $allou | Where {$_.Description -cmatch $User.OUGUID} | |
if ($ou) { | |
$OU = $ou.DistinguishedName | |
} else { | |
$OU = $withOutGUID | |
} | |
} else { | |
continue # didnt add inactive users | |
#$OU = $dismissed | |
} | |
# personal rules (for long name) | |
if($UserLogin.Length -gt 20){ | |
$UserLogin = "$UserLogin" -replace "^(\w+)_(\w+)", '$2' | |
} | |
if($UserLogin.Length -gt 20){ | |
$UserLogin = $UserLogin.Replace("-","") | |
} | |
if($UserLogin.Length -gt 20){ | |
$UserLogin = $UserLogin.Substring(0, 20) | |
} | |
$uniqueLogin = $false | |
try {get-aduser "$UserLogin"} | |
catch { | |
$uniqueLogin = $true | |
echo "Unique" | |
} | |
if(!$uniqueLogin){ | |
$isDuplicateLogin = $true; | |
$LastUserLogin = $UserLogin | |
$UserLogin = "$UserLogin" -replace "^(\w+)_(\w+)", '$2_$1' | |
echo "$UserLogin`t$LastUserLogin`t$AccountId" >> "DuplicateLogin.csv" | |
$uniqueLogin = $false | |
try {get-aduser "$UserLogin"} | |
catch { | |
$uniqueLogin = $true | |
echo "Unique after replace" | |
} | |
if(!$uniqueLogin){ | |
echo "Duble Duplicate login" | |
$LastUserLogin = $UserLogin | |
echo "$UserLogin`t$AccountId" >> "DuplicateLogin.csv" | |
$UserLogin = "$UserLogin" -replace "^(\w+)_(\w+)", '$2_$1' | |
$UserLogin = $UserLogin.Replace("_",".") | |
echo "$UserLogin`t$LastUserLogin`t$AccountId" >> "DuplicateLogin.csv" | |
} | |
} | |
log("Create user: $UserLogin ($Detailedname, $Title, $Department)") | |
$SAM= $UserLogin + "@guu.ru" | |
genPassword | |
echo "$Detailedname`t$UserLogin`t$Password`t$Department`t$OU" >> "Login.csv" | |
try{ | |
if ($manager){ | |
New-ADUser -Manager $Manager -Name "$Detailedname" -SamAccountName "$UserLogin" -UserPrincipalName "$SAM" -EmailAddres "$SAM" -DisplayName "$Detailedname" -GivenName "$UserFirstName" -Surname "$UserLastName" -Title "$Title" -EmployeeNumber $AccountId -Path "$OU" -ChangePasswordAtLogon $false -Department "$Department" -Company $Company -PasswordNeverExpires $true | |
} else { | |
New-ADUser -Name "$Detailedname" -SamAccountName "$UserLogin" -UserPrincipalName "$SAM" -EmailAddres "$SAM" -DisplayName "$Detailedname" -GivenName "$UserFirstName" -Surname "$UserLastName" -Title "$Title" -EmployeeNumber $AccountId -Path "$OU" -ChangePasswordAtLogon $false -Department "$Department" -Company $Company -PasswordNeverExpires $true | |
} | |
$UserAddCount++ | |
} catch { | |
echo "$OU`t$UserLogin`t$Password" >> "Error.csv" | |
$isErrors = $true | |
log("ERROR: Can't add user: $UserLogin") | |
$message.subject = "AD Sync script ($date) ERROR" | |
#read-host "Press Enter for continue" | |
} | |
Set-ADAccountPassword -Identity "$UserLogin" -NewPassword (ConvertTo-SecureString -AsPlainText "$Password" -Force) | |
if($Enabled) { | |
Enable-ADAccount -Identity "$UserLogin" | |
} else { | |
Disable-ADAccount -Identity "$UserLogin" | |
} | |
} | |
echo $UserGroup | |
if ($UserGroup -ne ""){ | |
try {get-adgroup $UserGroup | |
} catch { | |
New-ADGroup -Name $UserGroup -SamAccountName $UserGroup -GroupScope Global -GroupCategory Security -Path "$group" | |
} | |
Add-ADGroupMember -Identity $UserGroup -Member "$UserLogin" | |
} | |
} | |
log("End working with users") | |
#add files and send mail | |
$message.attachments.add((Resolve-Path Log.txt).Path) | |
if ($UserAddCount -ne 0){ | |
$message.attachments.add((Resolve-Path Login.csv).Path) | |
} | |
if ($isDuplicateLogin){ | |
$message.attachments.add((Resolve-Path DuplicateLogin.csv).Path) | |
} | |
if ($isErrors){ | |
$message.attachments.add((Resolve-Path Error.csv).Path) | |
} | |
$message.body = "Added users:`t$UserAddCount`nDisabled users:`t$UserDisableCount`nUpdated users:`t$UserUpdCount`nAdded OU:`t$OUAddCount`n`n" | |
$smtp.send($message) | |
$message.Dispose() | |
#remove temp dir | |
Remove-Item *.* -Force | |
Set-Location .. | |
Remove-Item $TempDir |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment