diff --git a/Windows/AcitveDirectory/usersignatures.md b/Windows/AcitveDirectory/usersignatures.md new file mode 100644 index 0000000..abaf4fd --- /dev/null +++ b/Windows/AcitveDirectory/usersignatures.md @@ -0,0 +1,631 @@ +# Requirements +1. ".env" Datei im gleichen Verzeichnis, wie das, in dem das Powershell Script gesichert wird. +2. "template.txt", "template.html", "template.rtf" ebenfalls in dem jeweiligen Verzeichnis ablegen. + +## Aufbau: .env Datei + +``` +AD_OUPath=OU=...,OU=...,OU=...,DC=contoso,DC=org +SIGNATURE_PATH=C:\Scripts\Sinatures +DEBUG=0 +``` + +Die Werte sind Beispielwerte und entsprechend anzupassen. Debug gibt Rückmeldungen in der Powershell. + +## Aufbau: template Dateien + +In den Templates werden Platzhalter genutzt um die Variablen zu ersetzen mit den Werten aus dem AD. + +[VORNAME] +[NACHNAME] +[JOB] +[DEPARTMENT] +[PHONE] +[PLAIN_PHONE] +[EMAIL] + +Ich selbst habe den Teil innerhalb der Templates so gestaltet, dass es "[JOB] | [DEPARTMENT]" gibt. Wenn ein User keine JOB Bezeichnung im AD hat, würde das automatisch ersetzt werden durch "[DEPARTMENT]". + +Da ich auch Links beim Klicken auf Icons nutze, muss die Telefonnummer etwas angepasst werden in der html Template Datei. Dafür habe ich im "tel:" Bereich ein "[PLAIN_PHONE]" gesetzt. + +## Powershell Script: + +```powershell +Canvas [Console]::OutputEncoding = [Text.Encoding]::UTF8 + +############################################################################### +# 0) FUNKTION ZUR DEBUG-AUSGABE +############################################################################### +function Write-HostIfDebug { + param( + [Parameter(Mandatory=$true)] + [string]$Message, + + # Der Typ hier ist entfernt, damit null oder eine valide Farbe möglich ist. + $ForegroundColor + ) + + if ($Env:DEBUG -eq "1") { + if ($ForegroundColor) { + Write-Host $Message -ForegroundColor $ForegroundColor + } else { + Write-Host $Message + } + } +} + +############################################################################### +# 1) SIGNATUREN-LOGIK +############################################################################### +function ConvertPhoneForHtml($phone) { + if (![string]::IsNullOrEmpty($phone)) { + $phone = $phone -replace " ", " ​" + $phone = $phone -replace "-", " ​- ​" + } + return $phone +} + +function ConvertEmailForHtml($mail) { + if (![string]::IsNullOrEmpty($mail)) { + $mail = $mail -replace "\\.", ".​" + $mail = $mail -replace "@", "@​" + $mail = $mail -replace "-", "-​" + } + return $mail +} + +# .env einlesen +$envFile = Join-Path $PSScriptRoot '.env' +if (Test-Path $envFile) { + Get-Content -Path $envFile | ForEach-Object { + if ($_ -match '^(?[^=]+)=(?.*)$') { + $key = $Matches['key'] + $value = $Matches['value'] + Set-Item -Path "Env:$key" -Value $value + } + } +} else { + Write-HostIfDebug ".env-Datei wurde nicht gefunden. Bitte stelle sicher, dass sie im gleichen Verzeichnis liegt." + return +} + +# Pfade aus .env +$ouPath = $Env:AD_OUPath +$signaturePath = $Env:SIGNATURE_PATH + +if (!$ouPath) { + Write-HostIfDebug "Bitte überprüfe, ob in der .env-Datei die Variable 'AD_OUPath' eingetragen ist." + return +} + +if (![string]::IsNullOrEmpty($signaturePath)) { + if (!(Test-Path $signaturePath)) { + Write-HostIfDebug "Der Pfad '$signaturePath' existiert nicht. Bitte überprüfen." + return + } +} else { + Write-HostIfDebug "Bitte überprüfe, ob in der .env-Datei die Variable 'SIGNATURE_PATH' eingetragen ist." + return +} + +Write-HostIfDebug "Suche nach Benutzern in der OU: $ouPath..." + +# Benutzer holen (und sortieren) +$users = Get-ADUser -Filter * -SearchBase $ouPath -Properties cn, givenName, sn, telephoneNumber, mail, title, department +Write-HostIfDebug "Gefundene Benutzer:`n" + +$global:AllUsers = $users | + Sort-Object -Property sn, givenName | + ForEach-Object { + [PSCustomObject]@{ + Selected = $false + CN = $_.cn + ADUser = $_ + DisplayText = if ($_.sn -and $_.givenName) { + "$($_.sn), $($_.givenName) ($($_.cn))" + } else { + $_.cn + } + } + } + +function Generate-SignaturesForUsers($selectedUsers) { + foreach ($item in $selectedUsers) { + $user = $item.ADUser + $cn = $user.cn + $givenName = $user.givenName + $sn = $user.sn + $originalPhone = $user.telephoneNumber + $originalEmail = $user.mail + $plainPhone = if (![string]::IsNullOrEmpty($originalPhone)) { + $originalPhone -replace '^0+', '' + } else { "" } + $convertedPhone = ConvertPhoneForHtml($originalPhone) + $convertedEmail = ConvertEmailForHtml($originalEmail) + $jobTitle = $user.title + $department = $user.department + + Write-HostIfDebug "-----------------------------------" + Write-HostIfDebug "CN : $cn" + Write-HostIfDebug "Vorname : $($givenName)" + Write-HostIfDebug "Nachname : $($sn)" + Write-HostIfDebug "Telefon (orig): $($originalPhone)" + Write-HostIfDebug "Telefon (HTML): $($convertedPhone)" + Write-HostIfDebug "plain_phone : $($plainPhone)" + Write-HostIfDebug "E-Mail (orig) : $($originalEmail)" + Write-HostIfDebug "E-Mail (HTML) : $($convertedEmail)" + Write-HostIfDebug "Job (Title) : $($jobTitle)" + Write-HostIfDebug "Abteilung : $($department)" + + # 1) HTML + $templateFilePath = Join-Path $PSScriptRoot 'template.html' + if (!(Test-Path $templateFilePath)) { + Write-HostIfDebug "Vorlage 'template.html' wurde nicht gefunden, bitte prüfe den Pfad." -ForegroundColor Red + return + } + + $signatureHtml = Get-Content -Path $templateFilePath -Raw + + if ([string]::IsNullOrEmpty($jobTitle)) { + $searchString = '
[JOB] | [DEPARTMENT]
' + $pattern = [Regex]::Escape($searchString) + $replacement = '
[DEPARTMENT]
' + $signatureHtml = $signatureHtml -replace $pattern, $replacement + } + + # E-Mail + if ($originalEmail) { + $pattern = 'href="mailto:\[EMAIL\]"' + $replacement = 'href="mailto:' + $originalEmail + '"' + $signatureHtml = $signatureHtml -replace $pattern, $replacement + + $pattern = '\[EMAIL\]' + $replacement = $convertedEmail + $signatureHtml = $signatureHtml -replace $pattern, $replacement + } else { + $pattern = 'href="mailto:\[EMAIL\]"' + $replacement = 'href="mailto:"' + $signatureHtml = $signatureHtml -replace $pattern, $replacement + + $pattern = '\[EMAIL\]' + $replacement = '' + $signatureHtml = $signatureHtml -replace $pattern, $replacement + } + + # Phone + if ($plainPhone) { + $pattern = 'href="tel:\+49\[PLAIN_PHONE\]"' + $replacement = 'href="tel:+49' + $plainPhone + '"' + $signatureHtml = $signatureHtml -replace $pattern, $replacement + + $pattern = '\[PHONE\]' + $replacement = $convertedPhone + $signatureHtml = $signatureHtml -replace $pattern, $replacement + } else { + $pattern = 'href="tel:\+49\[PHONE\]"' + $replacement = 'href="tel:"' + $signatureHtml = $signatureHtml -replace $pattern, $replacement + + $pattern = '\[PHONE\]' + $replacement = '' + $signatureHtml = $signatureHtml -replace $pattern, $replacement + } + + # Weitere Platzhalter + $signatureHtml = $signatureHtml -replace '\[VORNAME\]', $givenName + $signatureHtml = $signatureHtml -replace '\[NACHNAME\]', $sn + $signatureHtml = $signatureHtml -replace '\[JOB\]', $jobTitle + $signatureHtml = $signatureHtml -replace '\[DEPARTMENT\]', $department + $signatureHtml = $signatureHtml -replace '\[PLAIN_PHONE\]', $plainPhone + + $filename = "${cn}.htm" + $outputPath = Join-Path $signaturePath $filename + Set-Content -Path $outputPath -Value $signatureHtml -Encoding UTF8 + Write-HostIfDebug "Signatur (HTML) für '$($cn)' unter: $outputPath erstellt." -ForegroundColor Green + + # 2) TXT (wenn vorhanden) + $templateTxtFilePath = Join-Path $PSScriptRoot 'template.txt' + if (Test-Path $templateTxtFilePath) { + $signatureTxt = Get-Content -Path $templateTxtFilePath -Raw + + if ([string]::IsNullOrEmpty($jobTitle)) { + $searchString = '[JOB] | [DEPARTMENT]' + $pattern = [Regex]::Escape($searchString) + $replacement = '[DEPARTMENT]' + $signatureTxt = $signatureTxt -replace $pattern, $replacement + } + + if ($originalEmail) { + $signatureTxt = $signatureTxt -replace '\[EMAIL\]', $originalEmail + } else { + $signatureTxt = $signatureTxt -replace '\[EMAIL\]', '' + } + + if ($originalPhone) { + $signatureTxt = $signatureTxt -replace '\[PHONE\]', $originalPhone + } else { + $signatureTxt = $signatureTxt -replace '\[PHONE\]', '' + } + + if ($plainPhone) { + $signatureTxt = $signatureTxt -replace '\[PLAIN_PHONE\]', $plainPhone + } else { + $signatureTxt = $signatureTxt -replace '\[PLAIN_PHONE\]', '' + } + + $signatureTxt = $signatureTxt -replace '\[VORNAME\]', $givenName + $signatureTxt = $signatureTxt -replace '\[NACHNAME\]', $sn + $signatureTxt = $signatureTxt -replace '\[JOB\]', $jobTitle + $signatureTxt = $signatureTxt -replace '\[DEPARTMENT\]', $department + + $txtFilename = "${cn}.txt" + $txtOutputPath = Join-Path $signaturePath $txtFilename + Set-Content -Path $txtOutputPath -Value $signatureTxt -Encoding UTF8 + Write-HostIfDebug "Signatur (TXT) für '$($cn)' unter: $txtOutputPath erstellt." -ForegroundColor Green + } + + # 3) RTF (wenn vorhanden) + $templateRtfFilePath = Join-Path $PSScriptRoot 'template.rtf' + if (Test-Path $templateRtfFilePath) { + $signatureRtf = Get-Content -Path $templateRtfFilePath -Raw + + if ([string]::IsNullOrEmpty($jobTitle)) { + $searchString = '[JOB] | [DEPARTMENT]' + $pattern = [Regex]::Escape($searchString) + $replacement = '[DEPARTMENT]' + $signatureRtf = $signatureRtf -replace $pattern, $replacement + } + + if ($originalEmail) { + $signatureRtf = $signatureRtf -replace '\[EMAIL\]', $originalEmail + } else { + $signatureRtf = $signatureRtf -replace '\[EMAIL\]', '' + } + + if ($originalPhone) { + $signatureRtf = $signatureRtf -replace '\[PHONE\]', $originalPhone + } else { + $signatureRtf = $signatureRtf -replace '\[PHONE\]', '' + } + + if ($plainPhone) { + $signatureRtf = $signatureRtf -replace '\[PLAIN_PHONE\]', $plainPhone + } else { + $signatureRtf = $signatureRtf -replace '\[PLAIN_PHONE\]', '' + } + + $signatureRtf = $signatureRtf -replace '\[VORNAME\]', $givenName + $signatureRtf = $signatureRtf -replace '\[NACHNAME\]', $sn + $signatureRtf = $signatureRtf -replace '\[JOB\]', $jobTitle + $signatureRtf = $signatureRtf -replace '\[DEPARTMENT\]', $department + + $rtfFilename = "${cn}.rtf" + $rtfOutputPath = Join-Path $signaturePath $rtfFilename + Set-Content -Path $rtfOutputPath -Value $signatureRtf -Encoding Default + + Write-HostIfDebug "Signatur (RTF) für '$($cn)' unter: $rtfOutputPath erstellt." -ForegroundColor Green + } + Write-HostIfDebug "-----------------------------------" + } + Write-HostIfDebug "Fertig! Signaturen wurden erstellt." +} + +############################################################################### +# 2) WPF-UI + DRAG MOVE +############################################################################### +Add-Type -AssemblyName PresentationCore,PresentationFramework + +$XAML = @" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +