personio/sync_diff.ps1
2024-07-26 19:37:06 +02:00

295 lines
15 KiB
PowerShell

<#
.SYNOPSIS
Personio Sync Script (Personio -> MEHRKANAL AD)
.DESCRIPTION
Dieses Script übernimmt Personenbezogene Daten aus Personio in die Active Directory
.EXAMPLE
PS C:\POSTV>.\mk.ps1
<Startet den Sync für alle User>
.NOTES
Author: Sebastian Mendyka <mendyka@mehrkanal.com>
Date: Sep 13, 2017
.Link
URL: https://developer.personio.de/v1.0/reference
#>
######################################################################################
######################################################################################
# Variablen setzen
######################################################################################
######################################################################################
$application = "https://api.personio.de";
$company = "5989";
# Define the user credentials
$username = "#TOREPLACE#";
$password = "#TOREPLACE#";
# Force TLS1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$LOGDATE = Get-Date -Format "yyyy-MM-dd_"
$OWNPID = $([System.Diagnostics.Process]::GetCurrentProcess()).ID
$ScriptDir = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)
$ini = .\functions\functions.ps1 "$ScriptDir\config.ini"
$IMPERSONATEADMIN = $ini.exchange.impersonateuser
######################################################################################
######################################################################################
# Functions
######################################################################################
######################################################################################
# Active Directory Modul laden
. .\functions\json_function.ps1
# Active Directory Modul laden
. .\functions\activedirectory_function.ps1
# Füge Log Klasse hinzu, Inspiriert von https://gist.github.com/9to5IT/9620565
. .\functions\log_function.ps1
# Füge Exchange Klassen hinzu
. .\functions\exchange_function.ps1
# Füge Personio Klassen hinzu
. .\functions\personio.ps1
# Füge SQLITE Klassen hinzu
. .\functions\sqlite.ps1
Write-Log -Message "Starte DIFF Import" -Level Info
# http://www.spech.de/2016/06/sqlite-mit-der-powershell-nutzen/
if (! $(Get-Command Invoke-SqliteQuery -ErrorAction SilentlyContinue)) {
Write-Log -Message "Aktiviere SQLITE Modul" -Level Warn
#Import-Module "$($ScriptDir)\modules\sqlite\PSSQLite.psm1"
Import-Module PSSQLite
}
if (! $(Get-Command Invoke-SqliteQuery -ErrorAction SilentlyContinue)) {
Send-ErrorMail -Mail "Error: Sqlite Module not found / working" -VACSTART "-" -VACENDE "-" -VACID "-"
Write-Log -Message "Aktiviere SQLITE Modul" -Level Error
exit
}
$force = 0
$CHANGEDUSERDATA = $false
$CHANGEDAPPOINTMENT = $false
######################################################################################
######################################################################################
# Prüfe auf "neue" Kalender Daten
######################################################################################
######################################################################################
try {
Write-Log -Message "Get tmp Data (convert to json)" -Level Warn
$tmpcontent = $(Get-DiffUserVacation)
$tmpcontent | fl | out-file "$ScriptDir\$($ini.general.tmp_path)\data_diff_tmp_test.csv"
$getallapidata = $($tmpcontent).content | ConvertFrom-Json | select -expand "data"
Write-Log -Message "Create tmp Data (convert to json)" -Level Warn
$tmpgetallapidata = ($getallapidata).attributes | convertto-json -depth 8
Write-Log -Message "Write tmp Data" -Level Warn
$tmpgetallapidata | fl | out-file "$ScriptDir\$($ini.general.tmp_path)\data_diff_tmp.csv"
if (Test-Path "$ScriptDir\$($ini.general.tmp_path)\data_diff.csv") {
Write-Log -Message "Compare tmp Data" -Level Warn
$fileA = Get-Content "$ScriptDir\$($ini.general.tmp_path)\data_diff.csv"
$fileB = Get-Content "$ScriptDir\$($ini.general.tmp_path)\data_diff_tmp.csv"
if ( Compare-Object "$fileA" "$fileB") {
Write-Log -Message "Daten haben sich geändert..." -Level Info
$CHANGEDAPPOINTMENT = $true
}
else {
if ($force -eq "0") {
Write-Log -Message "Daten haben sich NICHT geändert... Breche ab" -Level Warn
$CHANGEDAPPOINTMENT = $false
}
else {
Write-Log -Message "Daten haben sich NICHT geändert... force aktiv" -Level Info
$CHANGEDAPPOINTMENT = $true
}
}
}
}
catch {
Write-Log -Message "Error: $($_.Exception.Message) - check_change - Line Number: $($_.InvocationInfo.ScriptLineNumber)" -Level Error
Send-ErrorMail -Mail "Error: get Cal-Data from API: $($_.Exception.Message)" -VACSTART "-" -VACENDE "-" -VACID "-"
exit
}
############################## DEBUG
#$CHANGEDUSERDATA = $true
#$CHANGEDAPPOINTMENT = $false
############################## DEBUG
if ( $CHANGEDUSERDATA -eq $false -and $CHANGEDAPPOINTMENT -eq $false) {
Write-Log -Message "Keine Datenänderungen vorhanden.. Beende Import" -Level Info
exit
}
######################################################################################
######################################################################################
# Aktualisiere Kalenderdaten des Users -> $_.ID
######################################################################################
if ( $CHANGEDAPPOINTMENT -eq $true) {
Create-ExMsalToken
######################################################################################
######################################################################################
# Add new Appointments
######################################################################################
######################################################################################
#2022-09-21T00:00:00+02:00
# $DatePattern = "yyyy-MM-ddTHH:mm:ssK"
$DatePattern = "MM/dd/yyyy HH:mm:ss"
$getallapidata | where { $_.attributes.status -match "approved" -and [datetime]::ParseExact($_.attributes.start_date, $DatePattern, $null) -gt $STARTDATEOLDEST -and ([DateTime]::ParseExact($_.attributes.start_date, $DatePattern, $null).Year) -ge "2022" } | ForEach-Object {
[PSCustomObject]@{
"VACID" = $_.attributes.id | select -First 1
"VACStatus" = $_.attributes.status | select -First 1
"VACStart" = $_.attributes.start_date | select -First 1
"VACEnde" = $_.attributes.end_date | select -First 1
"VACTage" = $_.attributes.days_count | select -First 1
"VACHalbTagAnfang" = $_.attributes.half_day_start | select -First 1
"VACHalbTagEnde" = $_.attributes.half_day_end | select -First 1
"VACTyp" = $_.attributes.time_off_type.attributes.name | select -First 1
"VACTypID" = $_.attributes.time_off_type.attributes.id | select -First 1
"VACEMail" = $_.attributes.employee.attributes.email.value | select -First 1
"VACFirstName" = $_.attributes.employee.attributes.first_name.value | select -First 1
"VACLastName" = $_.attributes.employee.attributes.last_name.value | select -First 1
}
} | ForEach-Object {
######################################################################################
######################################################################################
# Prüfe auf gelöschte Termine
######################################################################################
######################################################################################
$tmpmail = "$($_.VACEMail)"
Write-log -Message "Prüfe $tmpmail" -Level Info
$USERMAIL = (Get-ADUser -Filter { EmailAddress -eq $tmpmail }).UserPrincipalName
$USERID = (Get-ADUser -Filter { EmailAddress -eq $tmpmail }).SamAccountName
if (! (Test-path -Path "$($ScriptDir)\sqlite\$($USERID).db" )) {
CREATE-SQLITE $USERID
}
else {
If ((Get-Item "$($ScriptDir)\sqlite\$($USERID).db").length -le 0kb) {
Remove-Item "$($ScriptDir)\sqlite\$($USERID).db"
CREATE-SQLITE $USERID
}
}
$STARTDATE = Get-Date -date $_.VACStart
$STARTDATEOLDEST = (get-date).adddays(-60)
$ENDDATE = Get-Date -date $_.VACEnde
$ENDDATEOLDEST = (get-date).adddays(+360)
[datetime]$VACStart = $_.VACStart
[datetime]$VACEnde = $_.VACEnde
$VACHalbTagAnfang = $_.VACHalbTagAnfang
$VACHalbTagEnde = $_.VACHalbTagEnde
$VACTage = $_.VACTage
# Berechnung Urlaubsanfang und Urlaubsende
if ($VACTAGE -lt 1) {
if ($VACHalbTagAnfang -eq "1") {
$VACStart = $VACStart
}
if ($VACHalbTagEnde -eq "1") {
$VACStart = $VACStart.AddHours(13)
$VACEnde = $VACEnde.AddHours(23).AddMinutes(59)
}
else {
$VACEnde = $VACEnde.AddHours(13)
}
}
else {
if ($VACHalbTagAnfang -eq "1") {
$VACStart = $VACStart.AddHours(13)
}
if ($VACHalbTagEnde -eq "1") {
$VACEnde = $VACEnde.AddHours(13)
}
else {
$VACEnde = $VACEnde.AddHours(23).AddMinutes(59)
}
}
######################################################################################
######################################################################################
# Prüfe auf vorhandensein des Kalendereintrags in SQLITE Objekt
######################################################################################
######################################################################################
$GETRESPONSE = Get-SQLITE -USERID $USERID -VACPERSONIOID $_.VACID
if ($GETRESPONSE -eq $null) {
Write-Log -Message "Kalendereintrag: $($_.VACID) für $($USERID) nicht gefunden" -Level Warn
$RESPONSE = GET-ExchangeSubject -VacationType $($_.VACTypID)
######################################################################################
######################################################################################
# Termin ist nicht im SQLITE vorhanden..
######################################################################################
######################################################################################
$CREATEEWSOK = New-CalendarItem -Subject "$($RESPONSE.Name)" -Body "Dieser Eintrag wurde automatisch erzeugt. Bindend sind nur die Angaben in Personio (https://mehrkanal.personio.de/login/index )" -Start $VACStart -End $VACEnde -AdminUser "$IMPERSONATEADMIN" -Impersonate $_.VACEMail -FreeBusyStatus "$($RESPONSE.Status)"
if ( $CREATEEWSOK -ne $null -or $CREATEEWSOK -ne $false) {
echo $CREATEEWSOK
INSERT-SQLITE -USERID $USERID -MAIL $_.VACEMail -FIRSTNAME $_.VACFirstName -LASTNAME $_.VACLastName -VACPERSONIOID $_.VACID -VACTYPE $_.VACTYP -VACSTART $VACStart -VACEND $VACEnde -VAEXCHANGEID $CREATEEWSOK
Write-Log -Message "Kalendereintrag: $($_.VACID) für $($USERID) wurde hinzugefügt Start: $($_.VACStart) STOP: $VACEnde TYP: $($_.VACTYP)" -Level Warn
Write-Log -Message "Kalendereintrag: $($APIRESP)" -Level Warn
}
else {
Write-Log -Message "Urlaubsfreigabe EWS Sync war fehlerhaft..." -Level Error
Send-ErrorMail -Mail $($_.VACEMail) -VACSTART $($VACStart) -VACENDE $($VACEnde) -VACID $($_.VACID)
}
}
else {
Write-Log -Message "Eintrag wurde gefunden... vergleiche" -Level Info
######################################################################################
######################################################################################
# Vergleiche API-Response mit vorhandenen SQLITE Daten...
######################################################################################
######################################################################################
$RESPONSE = GET-ExchangeSubject -VacationType $($_.VACTypID)
$APIRESP = New-Object psobject -Property @{USERID = $USERID; MAIL = $_.VACEMail; VACID = $_.VACID; VACTYP = $_.VACTYP; VACSTART = $VACStart; VACENDE = $VACEnde }
$SQLITERESP = New-Object psobject -Property @{USERID = ($GETRESPONSE).Userid; MAIL = ($GETRESPONSE).Mail; VACID = ($GETRESPONSE).id; VACTYP = ($GETRESPONSE).Vactype; VACSTART = [datetime]($GETRESPONSE).Vacstart; VACENDE = [datetime]($GETRESPONSE).Vacend }
if (Compare-Object $APIRESP $SQLITERESP -Property VACID, MAIL, VACSTART, VACENDE, VACTYPE ) {
Write-Log -Message "Kalendereintrag: $($_.VACID) für $($USERID) haben sich geändert" -Level Warn
Write-Log -Message "Kalendereintrag: $($APIRESP)" -Level Warn
Write-Log -Message "Kalendereintrag: $($SQLITERESP)" -Level Warn
######################################################################################
######################################################################################
# Termin muss in Exchange geändert werden
######################################################################################
######################################################################################
$EXCHANGEMEETINGID = ($GETRESPONSE).Vacexchangeid
Remove-CalendarItem -CALID ($GETRESPONSE).Vacexchangeid -Impersonate ($GETRESPONSE).Mail
DELETE-SQLITE -USERID $USERID -VACPERSONIOID $_.VACID
$CREATEEWSOK = New-CalendarItem -Subject "$($RESPONSE.Name)" -Body "Dieser Eintrag wurde automatisch erzeugt. Bindend sind nur die Angaben in Personio (https://mehrkanal.personio.de/login/index )" -Start $VACStart -End $VACEnde -AdminUser "$IMPERSONATEADMIN" -Impersonate $_.VACEMail -FreeBusyStatus "$($RESPONSE.Status)"
if ( $CREATEEWSOK -ne $null -or $CREATEEWSOK -ne $false) {
echo $CREATEEWSOK
INSERT-SQLITE -USERID $USERID -MAIL $_.VACEMail -FIRSTNAME $_.VACFirstName -LASTNAME $_.VACLastName -VACPERSONIOID $_.VACID -VACTYPE $_.VACTYP -VACSTART $VACStart -VACEND $VACEnde -VAEXCHANGEID $CREATEEWSOK
}
else {
Write-Log -Message "Urlaubsfreigabe EWS Sync war fehlerhaft..." -Level Error
Send-ErrorMail -Mail $($_.VACEMail) -VACSTART $($VACStart) -VACENDE $($VACEnde) -VACID $($_.VACID)
}
}
}
}
# Erhalte Kalender-Daten und bereite diese auf...
$tmpgetallapidata | fl | out-file "$ScriptDir\$($ini.general.tmp_path)\data_diff.csv"
# Starte Logging
Write-Log -Message "Beende Import" -Level Info
}
else {
Write-Log -Message "Eintrag ist gleich..." -Level Info
}