295 lines
15 KiB
PowerShell
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
|
|
}
|
|
|