revert Test um User im AD anzulegen mit PS Skripts
This commit is contained in:
taarly 2025-12-12 09:33:14 +00:00
parent d6baaad963
commit 6060a5134b
4 changed files with 0 additions and 267 deletions

View File

@ -1,96 +0,0 @@
<?php
declare(strict_types=1);
final class PowerShellService
{
private string $psExe;
public function __construct(?string $psExe = null)
{
// Windows PowerShell 5.1
$this->psExe = $psExe ?? 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe';
// Alternative PowerShell 7:
// $this->psExe = $psExe ?? 'C:\\Program Files\\PowerShell\\7\\pwsh.exe';
}
/**
* @return array{exitCode:int, stdout:string, stderr:string}
*/
public function runScript(string $scriptPath, array $namedArgs, int $timeoutSeconds = 30): array
{
$scriptPath = realpath($scriptPath) ?: $scriptPath;
if (!is_file($scriptPath)) {
throw new RuntimeException("PowerShell script not found: {$scriptPath}");
}
$args = [];
foreach ($namedArgs as $name => $value) {
if (!preg_match('/^[A-Za-z][A-Za-z0-9]*$/', (string)$name)) {
throw new InvalidArgumentException("Invalid argument name: {$name}");
}
$args[] = '-' . $name;
$args[] = (string)$value; // wird als eigenes Argument übergeben (kein Command-String-Basteln)
}
$cmd = array_merge([
$this->psExe,
'-NoLogo',
'-NoProfile',
'-NonInteractive',
'-ExecutionPolicy', 'Bypass',
'-File', $scriptPath,
], $args);
$descriptors = [
0 => ["pipe", "r"],
1 => ["pipe", "w"],
2 => ["pipe", "w"],
];
$proc = proc_open($cmd, $descriptors, $pipes, null, null, [
'bypass_shell' => true,
'suppress_errors' => true,
]);
if (!is_resource($proc)) {
throw new RuntimeException("Failed to start PowerShell process.");
}
fclose($pipes[0]);
stream_set_blocking($pipes[1], false);
stream_set_blocking($pipes[2], false);
$stdout = '';
$stderr = '';
$start = time();
while (true) {
$stdout .= stream_get_contents($pipes[1]);
$stderr .= stream_get_contents($pipes[2]);
$status = proc_get_status($proc);
if (!$status['running']) {
break;
}
if ((time() - $start) > $timeoutSeconds) {
proc_terminate($proc, 9);
$stderr .= "\n[PHP] Timeout after {$timeoutSeconds}s";
break;
}
usleep(50_000);
}
fclose($pipes[1]);
fclose($pipes[2]);
$exitCode = proc_close($proc);
return [
'exitCode' => (int)$exitCode,
'stdout' => trim($stdout),
'stderr' => trim($stderr),
];
}
}

View File

@ -1,58 +0,0 @@
<?php
declare(strict_types=1);
header('Content-Type: application/json; charset=utf-8');
require_once __DIR__ . '/../app/Services/PowerShellService.php';
// Minimal-Validation (zusätzlich zur PS-Validation)
$username = (string)($_POST['username'] ?? '');
$vorname = (string)($_POST['vorname'] ?? '');
$nachname = (string)($_POST['nachname'] ?? '');
$passwort = (string)($_POST['passwort'] ?? '');
$gruppe = (string)($_POST['gruppe'] ?? '');
if ($username === '' || $vorname === '' || $nachname === '' || $passwort === '' || $gruppe === '') {
http_response_code(400);
echo json_encode(['ok' => false, 'error' => 'Bitte alle Felder ausfüllen.']);
exit;
}
try {
$ps = new PowerShellService();
$script = __DIR__ . '/../scripts/powershell/New-AdUserFromPhp.ps1';
$res = $ps->runScript($script, [
'Username' => $username,
'Vorname' => $vorname,
'Nachname' => $nachname,
'Passwort' => $passwort,
'Benutzergruppe' => $gruppe,
], 60);
// PowerShell gibt JSON zurück
$json = $res['stdout'];
$data = json_decode($json, true);
if (!is_array($data)) {
http_response_code(500);
echo json_encode([
'ok' => false,
'error' => 'Ungültige Antwort von PowerShell.',
'stderr' => $res['stderr'],
'raw' => $json,
]);
exit;
}
// Wenn PS exitCode != 0, trotzdem JSON ausgeben (enthält error)
if ($res['exitCode'] !== 0) {
http_response_code(400);
}
echo json_encode($data);
} catch (Throwable $e) {
http_response_code(500);
echo json_encode(['ok' => false, 'error' => $e->getMessage()]);
}

View File

@ -1,41 +0,0 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AD User anlegen</title>
</head>
<body>
<h1>AD User anlegen</h1>
<form method="post" action="ad_create_user.php">
<p>
<label>Username (sAMAccountName)<br>
<input name="username" required maxlength="32">
</label>
</p>
<p>
<label>Vorname<br>
<input name="vorname" required maxlength="64">
</label>
</p>
<p>
<label>Nachname<br>
<input name="nachname" required maxlength="64">
</label>
</p>
<p>
<label>Passwort<br>
<input name="passwort" type="password" required minlength="8" maxlength="128">
</label>
</p>
<p>
<label>Benutzergruppe (Gruppenname / DN)<br>
<input name="gruppe" required maxlength="128" placeholder="z.B. 'IT-Users'">
</label>
</p>
<button type="submit">Anlegen</button>
</form>
</body>
</html>

View File

@ -1,72 +0,0 @@
param(
[Parameter(Mandatory=$true)]
[ValidatePattern('^[a-zA-Z0-9._-]{1,32}$')]
[string]$Username,
[Parameter(Mandatory=$true)]
[ValidateLength(1, 64)]
[string]$Vorname,
[Parameter(Mandatory=$true)]
[ValidateLength(1, 64)]
[string]$Nachname,
[Parameter(Mandatory=$true)]
[ValidateLength(8, 128)]
[string]$Passwort,
# Gruppe als Name / DN / SamAccountName der Gruppe
[Parameter(Mandatory=$true)]
[ValidateLength(1, 128)]
[string]$Benutzergruppe
)
$ErrorActionPreference = "Stop"
try {
Import-Module ActiveDirectory
# Existiert User schon?
$existing = Get-ADUser -Filter "SamAccountName -eq '$Username'" -ErrorAction SilentlyContinue
if ($null -ne $existing) {
throw "Benutzer existiert bereits: $Username"
}
# Existiert Gruppe?
$grp = Get-ADGroup -Identity $Benutzergruppe -ErrorAction SilentlyContinue
if ($null -eq $grp) {
throw "Gruppe nicht gefunden: $Benutzergruppe"
}
$displayName = "$Vorname $Nachname"
$securePw = ConvertTo-SecureString -AsPlainText $Passwort -Force
New-ADUser `
-SamAccountName $Username `
-Name $displayName `
-GivenName $Vorname `
-Surname $Nachname `
-DisplayName $displayName `
-AccountPassword $securePw `
-Enabled $true `
-ChangePasswordAtLogon $true
Add-ADGroupMember -Identity $Benutzergruppe -Members $Username
[pscustomobject]@{
ok = $true
username = $Username
displayName = $displayName
group = $Benutzergruppe
} | ConvertTo-Json -Depth 4
exit 0
}
catch {
[pscustomobject]@{
ok = $false
error = $_.Exception.Message
} | ConvertTo-Json -Depth 4
exit 1
}