We have recently introduced a new ERP in our company, which also includes the complete personnel administration. The software uses MS-SQL Server as a database. As our IT process is very complex for a new user and little things are often forgotten, I have tried to automate the creation as much as possible. This works quite well thanks to Powershell. I built a view in SQL Studio that contains all the information from the personnel administration:
Since I do not want to automatically create all users from the personnel master in the AD (but this is also conceivable), I have restricted the SQL select to a single personnel number in the script for creating a new user. The script looks like this:
#################### # Neuer AD Benutzer von SQL Tabellen #################### # globale Variablen $newuser = "TEST" $SQLServer = "DBSRV\INSTANZ" $SQLDBName = "YOURDB" $SQLsecurity = "Integrated Security = True" $SQLText = "SELECT * FROM dbo.PERSSTAMM WHERE PERS_NR = '" + $newuser + "'" $EXServer = "server.domain.tld" $EXSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$EXServer/PowerShell/ -Authentication Kerberos $SMTPServer = "server.domain.tld" $logMailrecipient = "empfänger@mail.info" $logMailsender = "absender@mail.info" $logMailSubject = "Neuer Benutzer aus ERP ersellen" $logFile = "C:\scripts\log.txt" $ADTargetOU="OU=user,DC=DOMAIN,DC=TLD" $ADPwd = "YourDefaultPassword" $ADphoto = [byte[]](Get-Content "\\domain\NETLOGON\media\ADuserphoto\default.jpg" -Encoding byte) $Blank = "" $OfficePhone = "+xx xxxx xxxx" # Löschen des Logfiles del $logFile -ErrorAction Ignore # Verbinde zu SQL und starte QUERY $SqlCon = New-Object System.Data.SqlClient.SqlConnection $SqlCon.ConnectionString = "Server = $SQLServer; Database = $SQLDBName; $SQLsecurity" $SqlCon.Open() $SqlCmd = New-Object System.Data.SqlClient.SqlCommand $SqlCmd.Connection = $SqlCon $SqlCmd = $SqlCon.CreateCommand() $SqlCmd.CommandText = $SQLText $Result = $SQLCmd.ExecuteReader() $Table = New-Object System.Data.DataTable $Table.Load($Result) $SqlCon.Close() foreach($Item in $Table) { $newUserID=@{ Name=$Item.PERS_NAME+" "+$Item.PERS_VORNAME Description="Dieser User ist NEU - Sync ausständig" GivenName=$Item.PERS_VORNAME Surname=$Item.PERS_NAME DisplayName=$Item.PERS_NAME+" "+$Item.PERS_VORNAME UserPrincipalName=$Item.PERS_EMAIL sAMAccountName=$Item.PERS_NR homeDrive = "Z:" homeDirectory = "\\netshare\userdata\home\" + $Item.PERS_NR } Try{ $newUserID New-ADUser @newUserID -Path $ADTargetOU -ErrorAction Stop -AccountPassword (ConvertTo-SecureString $ADPwd -AsPlainText -Force) -Passthru Enable-ADAccount -Identity $newUserID.sAMAccountName Set-ADUser -Identity $newUserID.sAMAccountName -ChangePasswordAtLogon $true -Replace @{thumbnailPhoto=$ADphoto} Import-PSSession $EXSession Enable-Mailbox -Identity $Item.PERS_NR -Alias $Item.PERS_EMAIL_ALIAS -Database 'MDB01' -AddressBookPolicy 'Default' -RetentionPolicy 'Archivierung' Enable-Mailbox -Identity $Item.PERS_NR -Archive -ArchiveDatabase 'ADB01' Start-Sleep -s 20 Enable-UMMailbox -Identity $Item.PERS_NR -UMMailboxPolicy 'Standardrichtlinie für UM' -Extensions $Item.PERS_TEL_DW -SIPResourceIdentifier $Item.PERS_EMAIL Write-Host "UserID $($newUserID.sAMAccountName) erstellt!" -ForegroundColor green "der User mit der UserID: $($newUserID.sAMAccountName) wurde erstellt!" >> $logFile $_ >> $logFile } Catch{ Write-Host "Es gab ein Problem mit dem erstellen des Users: UserID $($newUserID.sAMAccountName). Der Accoutn wurde nicht erstellt!" -ForegroundColor Red "Es gab ein Problem mit dem erstellen des Users: $newUserID.$samAccountName" >> $logFile $_ >> $logFile } } <# Versenden des Logfiles an eine Mailbox #> If (Test-Path $logFile) { Send-MailMessage -From $logMailsender -Subject $logMailSubject -To $logMailrecipient -Attachments $logFile -SmtpServer $SMTPServer } Else { }
The user is created with the basic information and an e-mail inbox is created. A log is created and sent.
Da nun aber noch einige Informationen beim Benutzer fehlen, (Falsche OU, Adresse, Telefon, Vorgesetzter, Organisation,Bild,…) muss noch ein Syncscript gebaut werden. Den Variablenteil kopiere ich aus dem vorigen Script, da dieser alle Informationen enthält. die Einschränkung auf einen einzelnen User habe ich entfernt:
#################### # Update AD von SQL Tabellen #################### # globale Variablen $newuser = "TEST" $SQLServer = "DBSRV\INSTANZ" $SQLDBName = "YOURDB" $SQLsecurity = "Integrated Security = True" $SQLText = "SELECT * FROM dbo.PERSSTAMM" $SMTPServer = "server.domain.tld" $logMailrecipient = "empfänger@mail.info" $logMailsender = "absender@mail.info" $logMailSubject = "Fehler bei AD-Sync aus ERP" $logFile = "C:\scripts\log.txt" $ADPwd = "YourDefaultPassword" $ADphotobasepath = "\\domain\NETLOGON\media\ADuserphoto\" $Blank = "" $OfficePhone = "+xx xxxx xxxx" # Löschen des Logfiles del $logFile -ErrorAction Ignore # Verbinde zu SQL und starte QUERY $SqlCon = New-Object System.Data.SqlClient.SqlConnection $SqlCon.ConnectionString = "Server = $SQLServer; Database = $SQLDBName; $SQLsecurity" $SqlCon.Open() $SqlCmd = New-Object System.Data.SqlClient.SqlCommand $SqlCmd.Connection = $SqlCon $SqlCmd = $SqlCon.CreateCommand() $SQLCmd.CommandText = $SQLText $Result = $SQLCmd.ExecuteReader() $Table = New-Object System.Data.DataTable $table.Load($Result) $SqlCon.Close() # importiere Daten von SQL foreach($Item in $Table) { # AD Allgemein $givenName = $Item.PERS_VORNAME $initials = $Item.PERS_KBEZ $sn = $Item.PERS_NAME $displayName = $Item.PERS_NAME + " " + $Item.PERS_VORNAME $Description = $null $wWWHomePage ="http://www.domain.tld" # AD Adresse $streetAddress = IF([string]::IsNullOrWhiteSpace($Item.PERS_ADRESSE1)) { $null } Else { $Item.PERS_ADRESSE1 } $l = IF([string]::IsNullOrWhiteSpace($Item.PERS_ORT)) { $null } Else { $Item.PERS_ORT } $st = "Tirol" $postalCode = IF([string]::IsNullOrWhiteSpace($Item.PLZ_CD)) { $null } Else { $Item.PLZ_CD } $co = "Österreich" $c = "AT" # AD Konto $samAccountName = $Item.PERS_NR $accountExpires ="[PERS_DTAENDG]" # AD Profil # AD Rufnummer $telephoneNumber = IF([string]::IsNullOrWhiteSpace($Item.PERS_TEL)) { $Office } Else { $Item.PERS_TEL } $mobile = IF([string]::IsNullOrWhiteSpace($Item.PERS_MOBIL)) { $null } Else { $Item.PERS_MOBIL } $facsimileTelephoneNumber = IF([string]::IsNullOrWhiteSpace($Item.PERS_FAX)) { $null } Else { $Item.PERS_FAX } # AD Organistation $title = IF([string]::IsNullOrWhiteSpace($Item.PERS_FELD5_BEZ)) { $null } Else { $Item.PERS_FELD5_BEZ } $department = IF([string]::IsNullOrWhiteSpace($Item.PERS_KSTNR_BEZ)) { $null } Else { $Item.PERS_KSTNR_BEZ } $company = IF([string]::IsNullOrWhiteSpace($Item.PERS_CD2_BEZ)) { $null } Else { $Item.PERS_CD2_BEZ } $manager = IF([string]::IsNullOrWhiteSpace($Item.USER_CD_VORG2)) { $null } Else { $Item.USER_CD_VORG2 } # AD Attribute erweitert $EmployeeID = $Item.PERS_NR $extensionAttribute9 = IF([string]::IsNullOrWhiteSpace($Item.PERS_FELD5_BEZ2)) { '' } Else { $Item.PERS_FELD5_BEZ2 } $extensionAttribute10 = IF([string]::IsNullOrWhiteSpace($Item.PERS_AUSWEISNR)) { '' } Else { $Item.PERS_AUSWEISNR } $extensionAttribute12 = IF([string]::IsNullOrWhiteSpace($Item.PERS_FELD4_BEZ2)) { '' } Else { ', ' + $Item.PERS_FELD4_BEZ2 } $extensionAttribute14 = IF([string]::IsNullOrWhiteSpace($Item.PERS_FAX_OL)) { '' } Else { $Item.PERS_FAX_OL } $extensionAttribute15 = IF([string]::IsNullOrWhiteSpace($Item.PERS_FELD4_BEZ)) { '' } Else { $Item.PERS_FELD4_BEZ + ' ' } $ADphotopath = $ADphotobasepath + $Item.PERS_NAME + " " + $Item.PERS_VORNAME + '.jpg' IF (Test-Path $ADphotopath ) { $thumbnailPhoto = [byte[]](Get-Content $ADphotopath -Encoding byte) } Else { $thumbnailPhoto = [byte[]](Get-Content "\\domain\NETLOGON\media\ADuserphoto\default.jpg" -Encoding byte) } $active = IF ($Item.PERS_STATUS -eq '0') { $true } Else { $false } $ADTargetOU = "OU=users,OU=" + $Item.PERS_KSTNR_BEZ + ",OU=" + $Item.PERS_CD2 + "," + "OU=user,DC=DOMAIN,DC=TLD" if([string]::isNullOrEmpty($sAMAccountName.description)) { "modifying $($sAMAccountName)" # Update AD mit den definierten Informationen Set-ADUser -Identity $sAMAccountName -GivenName $givenName -Initials $initials -Surname $sn -DisplayName $displayName -Description $Description -HomePage $wWWHomePage -StreetAddress $streetAddress -City $l -State $st -PostalCode $postalCode -Country $c -OfficePhone $telephoneNumber -MobilePhone $mobile -Fax $facsimileTelephoneNumber -Title $title -Department $department -Company $company -Manager $manager -EmployeeID $EmployeeID -Replace @{extensionAttribute9 = $extensionAttribute9; extensionAttribute10 = $extensionAttribute10; extensionAttribute12 = $extensionAttribute12; extensionAttribute14 = $extensionAttribute14; extensionAttribute15 = $extensionAttribute15; thumbnailPhoto = $thumbnailPhoto} -Enabled $active # Verschiebe User in richtige OU Get-ADUser $sAMAccountName | Move-ADObject -TargetPath $ADTargetOU #Fehler Ermittlung If (!$?) #Fehler beim Sync { "User:[" + $sAMAccountName + "] sync mit Fehlern" >> $logFile } Else #kein Fehler beim Sync { } } } <# Versenden des Logfiles an eine Mailbox #> If (Test-Path $logFile) { Send-MailMessage -From $logMailsender -Subject $logMailSubject -To $logMailrecipient -Attachments $logFile -SmtpServer $SMTPServer } Else { }
I am now updating all users found in the HR master data. The information in the AD is added, the user is moved to the correct OU and, if available, the default photo is replaced with the correct photo from NETShare. If the user is still deactivated in the HR master data, it is also deactivated in the AD. A log is then sent. The script can now be integrated as a task every x hours/days.
Call via Web GUI
Since I wanted to hand over the creation and sync of a user to the helpdesk, but did not want them to change the script, I looked for a way to process the whole thing via a web call. The tool Powershell Server 2016 (available in a free version) makes this possible and parameters can also be transferred via an HTML website.
A contribution by Alexander Christanell.