diff --git a/README.md b/README.md index 716eece..621eaa2 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,30 @@ Dieser Bereich muss von allen Entwicklern gelesen werden, bevor am Projekt gearb --- +## PowerShell Integration (Benutzererstellung) + +Die Weboberfläche nutzt PowerShell-Skripte, um Active Directory Benutzer anzulegen. Damit dies funktioniert, sind folgende Voraussetzungen erforderlich: + +- Der Webserver läuft auf Windows und PHP kann PowerShell ausführen (`powershell` oder `pwsh`). +- Die PowerShell-Module `ActiveDirectory` müssen installiert (RSAT) und verfügbar sein. +- Der Benutzer, unter dem der Webserver läuft, muss ausreichende Rechte besitzen, um `New-ADUser` und `Add-ADGroupMember` auszuführen. +- Im `config/config.php` kann `powershell.dry_run` auf `true` gesetzt werden, um Tests ohne Änderungen durchzuführen. + +Konfigurationsoptionen (in `config/config.php`): +- `powershell.exe`: Name oder Pfad zur PowerShell-Executable (standard `powershell`). +- `powershell.script_dir`: Pfad zu den PowerShell-Skripten (standard `scripts/powershell`). +- `powershell.execution_policy`: Auszuführende ExecutionPolicy (z. B. `Bypass`). +- `powershell.dry_run`: Wenn `true`, werden keine echten AD-Änderungen durchgeführt; das Skript meldet nur, was es tun würde. + +Die grundlegende Funktionalität wurde mit folgenden Komponenten implementiert: +- `public/api/create_user.php`: API-Endpoint zur Erstellung eines einzelnen Benutzers. +- `public/api/create_users_csv.php`: API-Endpoint zur Erstellung mehrerer Benutzer aus CSV. +- `scripts/powershell/create_user.ps1`: PowerShell-Skript zum Erstellen eines einzelnen Benutzers. +- `scripts/powershell/create_users_csv.ps1`: PowerShell-Skript zum Erstellen mehrerer Benutzer aus CSV. + +Bitte testen zuerst mit `powershell.dry_run = true` und prüfen sie die resultierenden Meldungen in UI. + + ## Mitwirken Wer etwas ändern oder erweitern möchte: diff --git a/app/Controllers/UserManagementController.php b/app/Controllers/UserManagementController.php index 41499c0..c84695e 100644 --- a/app/Controllers/UserManagementController.php +++ b/app/Controllers/UserManagementController.php @@ -110,12 +110,36 @@ class UserManagementController { $viewPath = __DIR__ . '/../../public/views/createuser.php'; + // Use session flash messages if available + $error = null; + $success = null; + if (session_status() !== PHP_SESSION_ACTIVE) { + @session_start(); + } + if (isset($_SESSION['flash_error'])) { + $error = $_SESSION['flash_error']; + unset($_SESSION['flash_error']); + } + if (isset($_SESSION['flash_success'])) { + $success = $_SESSION['flash_success']; + unset($_SESSION['flash_success']); + } + $csvDetails = null; + if (isset($_SESSION['csv_details'])) { + $csvDetails = $_SESSION['csv_details']; + unset($_SESSION['csv_details']); + } + + $powershellDryRun = $this->config['powershell']['dry_run'] ?? false; + return [ 'view' => $viewPath, 'data' => [ - 'error' => null, - 'success' => null, + 'error' => $error, + 'success' => $success, 'loginPage' => false, + 'csvDetails' => $csvDetails, + 'powershellDryRun' => $powershellDryRun, ], 'pageTitle' => 'Benutzer erstellen', 'activeMenu' => 'createuser', diff --git a/config/config.php b/config/config.php index a65cdb3..ac439bd 100644 --- a/config/config.php +++ b/config/config.php @@ -60,4 +60,14 @@ return [ // Minimale Stufe: debug, info, warning, error 'min_level' => 'info', ], + 'powershell' => [ + // Executable name: 'powershell' on Windows, 'pwsh' for PowerShell core. + 'exe' => 'powershell', + // Script directory where the PS1 scripts live (relative to config dir) + 'script_dir' => __DIR__ . '/../scripts/powershell', + // Execution policy to pass to the PowerShell invocation + 'execution_policy' => 'Bypass', + // For testing; if true, the scripts will run in dry-run mode (no real AD changes) + 'dry_run' => false, + ], ]; diff --git a/public/api/create_user.php b/public/api/create_user.php new file mode 100644 index 0000000..ce59401 --- /dev/null +++ b/public/api/create_user.php @@ -0,0 +1,109 @@ + $sam, + 'displayname' => $display, + 'mail' => $mail, + 'password' => $pass, + 'ou' => $ou, + 'groups' => $groups, + 'dry_run' => (bool)($config['powershell']['dry_run'] ?? false), +]; + +// Write payload to temp file +$tmpFile = tempnam(sys_get_temp_dir(), 'create_user_') . '.json'; +file_put_contents($tmpFile, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + +// Build PS script path +$scriptDir = $config['powershell']['script_dir'] ?? __DIR__ . '/../../scripts/powershell'; +$script = $scriptDir . DIRECTORY_SEPARATOR . 'create_user.ps1'; + +$exe = $config['powershell']['exe'] ?? 'powershell'; +$executionPolicy = $config['powershell']['execution_policy'] ?? 'Bypass'; + +$cmd = sprintf( + '%s -NoProfile -NonInteractive -ExecutionPolicy %s -File "%s" -InputFile "%s"', + $exe, + $executionPolicy, + $script, + $tmpFile +); + +// Execute and capture output and exit code +$output = []; +$returnVar = null; +if (!file_exists($script)) { + $_SESSION['flash_error'] = 'PowerShell-Skript nicht gefunden: ' . $script; + @unlink($tmpFile); + header('Location: ../index.php?route=createuser'); + exit; +} + +// Try to locate the PowerShell executable +$exePathCheck = shell_exec(sprintf('where %s 2>NUL', escapeshellarg($exe))); +if ($exePathCheck === null) { + // 'where' returns null when command fails; continue anyways, exec will fail if not found +} + +exec($cmd . ' 2>&1', $output, $returnVar); +$json = implode("\n", $output); + +@unlink($tmpFile); + +// Try to parse JSON output +$result = null; +if ($json !== '') { + $decoded = json_decode($json, true); + if (is_array($decoded)) { + $result = $decoded; + } +} + +if ($result === null) { + $_SESSION['flash_error'] = 'Unbekannter Fehler beim Ausführen des PowerShell-Skripts: ' . ($json ?: 'Keine Ausgabe'); + header('Location: ../index.php?route=createuser'); + exit; +} + +if (!empty($result['success'])) { + $_SESSION['flash_success'] = $result['message'] ?? 'Benutzer erfolgreich erstellt.'; +} else { + $_SESSION['flash_error'] = $result['message'] ?? 'Fehler beim Erstellen des Benutzers.'; +} + +header('Location: ../index.php?route=createuser'); +exit; diff --git a/public/api/create_users_csv.php b/public/api/create_users_csv.php new file mode 100644 index 0000000..3b01536 --- /dev/null +++ b/public/api/create_users_csv.php @@ -0,0 +1,107 @@ + $tmpFile, + 'delimiter' => $delimiter, + 'has_header' => (bool)((int)$hasHeader), + 'dry_run' => (bool)($config['powershell']['dry_run'] ?? false), +]; + +// Save options as JSON as the input to the PS script +$metaFile = tempnam(sys_get_temp_dir(), 'create_users_meta_') . '.json'; +file_put_contents($metaFile, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + +$scriptDir = $config['powershell']['script_dir'] ?? __DIR__ . '/../../scripts/powershell'; +$script = $scriptDir . DIRECTORY_SEPARATOR . 'create_users_csv.ps1'; +$exe = $config['powershell']['exe'] ?? 'powershell'; +$executionPolicy = $config['powershell']['execution_policy'] ?? 'Bypass'; + +$cmd = sprintf( + '%s -NoProfile -NonInteractive -ExecutionPolicy %s -File "%s" -InputFile "%s"', + $exe, + $executionPolicy, + $script, + $metaFile +); + +$output = []; +$returnVar = null; +if (!file_exists($script)) { + $_SESSION['flash_error'] = 'PowerShell-Skript nicht gefunden: ' . $script; + @unlink($tmpFile); + @unlink($metaFile); + header('Location: ../index.php?route=createuser'); + exit; +} + +exec($cmd . ' 2>&1', $output, $returnVar); +$json = implode("\n", $output); + +@unlink($tmpFile); +@unlink($metaFile); + +$result = null; +if ($json !== '') { + $decoded = json_decode($json, true); + if (is_array($decoded)) { + $result = $decoded; + } +} + +if ($result === null) { + $_SESSION['flash_error'] = 'Unbekannter Fehler beim Ausführen des PowerShell-Skripts: ' . ($json ?: 'Keine Ausgabe'); + header('Location: ../index.php?route=createuser'); + exit; +} + +if (!empty($result['success'])) { + $_SESSION['flash_success'] = $result['message'] ?? 'CSV verarbeitet.'; + if (!empty($result['details'])) { + $_SESSION['csv_details'] = $result['details']; + } +} else { + $_SESSION['flash_error'] = $result['message'] ?? 'Fehler beim Verarbeiten der CSV.'; +} + +header('Location: ../index.php?route=createuser'); +exit; diff --git a/public/views/createuser.php b/public/views/createuser.php index 53ab95d..9e0ca82 100644 --- a/public/views/createuser.php +++ b/public/views/createuser.php @@ -38,6 +38,12 @@ declare(strict_types=1); + +
Hier können Sie einzelne Active-Directory-Benutzer anlegen oder eine CSV-Datei hochladen, um mehrere Benutzer gleichzeitig zu erstellen. Sie können die CSV in der Vorschau bearbeiten bevor Sie die Erstellung auslösen.
| Anmeldename | +Status | +Hinweis | +
|---|---|---|
| + | + | + |