diff --git a/Setup-ByteTrail-AD.ps1 b/Setup-ByteTrail-AD.ps1 index efa537e..74594e2 100644 --- a/Setup-ByteTrail-AD.ps1 +++ b/Setup-ByteTrail-AD.ps1 @@ -6,19 +6,88 @@ # ============================================================ #region KONFIGURATION -$Domain = "bytetrail.local" -$DomainDN = "DC=bytetrail,DC=local" +$Domain = "byte.trail" +$DomainDN = "DC=byte,DC=trail" $MailDomain = "byte.trail" $DefaultPW = ConvertTo-SecureString "ByteTrail2026!" -AsPlainText -Force -$DC = $env:COMPUTERNAME # Script laeuft direkt auf dem DC #endregion Write-Host "`n=== ByteTrail AD Setup gestartet ===" -ForegroundColor Cyan +# ============================================================ +# DIAGNOSE - Pruefen ob AD bereit ist +# ============================================================ +Write-Host "`n[0/4] AD-Diagnose..." -ForegroundColor Yellow + +# ADWS-Dienst pruefen +$adws = Get-Service ADWS -ErrorAction SilentlyContinue +if ($adws) { + if ($adws.Status -ne 'Running') { + Write-Host " [!] ADWS-Dienst ist NICHT gestartet (Status: $($adws.Status)). Starte..." -ForegroundColor Red + try { Start-Service ADWS -ErrorAction Stop; Start-Sleep -Seconds 5 } + catch { Write-Host " [!] ADWS konnte nicht gestartet werden: $_" -ForegroundColor Red; exit 1 } + } + Write-Host " [OK] ADWS-Dienst laeuft" -ForegroundColor Green +} else { + Write-Host " [!] ADWS-Dienst nicht gefunden - ist AD DS installiert?" -ForegroundColor Red + exit 1 +} + +# AD erreichbar? +try { + $ADDomain = Get-ADDomain -ErrorAction Stop + Write-Host " [OK] AD-Domaene: $($ADDomain.DNSRoot)" -ForegroundColor Green + Write-Host " [OK] Naming Context: $($ADDomain.DistinguishedName)" -ForegroundColor Green + Write-Host " [OK] PDC Emulator: $($ADDomain.PDCEmulator)" -ForegroundColor Green + Write-Host " [OK] Infrastruktur Master: $($ADDomain.InfrastructureMaster)" -ForegroundColor Green + + # RODC-Check + $dc = Get-ADDomainController -ErrorAction Stop + if ($dc.IsReadOnly) { + Write-Host " [!] ACHTUNG: Dieser DC ist ein READ-ONLY DC (RODC) - Schreiboperationen werden fehlschlagen!" -ForegroundColor Red + exit 1 + } + Write-Host " [OK] DC: $($dc.HostName) (Beschreibbar)" -ForegroundColor Green +} catch { + Write-Host " [!] AD nicht erreichbar: $($_.Exception.Message)" -ForegroundColor Red + Write-Host " [!] InnerException: $($_.Exception.InnerException)" -ForegroundColor Red + Write-Host "`nMoegliche Loesungen:" -ForegroundColor Yellow + Write-Host " 1. Server neustarten (nach DC-Promotion noetig)" -ForegroundColor Yellow + Write-Host " 2. Restart-Service ADWS" -ForegroundColor Yellow + Write-Host " 3. dcdiag /v ausfuehren fuer Details" -ForegroundColor Yellow + exit 1 +} + +# Quick-Write-Test: Versuche ein Dummy-Attribut zu lesen/schreiben +Write-Host " [..] Schreibtest..." -ForegroundColor Gray +try { + $testOUName = "_ByteTrailSetupTest" + $testOU = "OU=$testOUName,$DomainDN" + New-ADOrganizationalUnit -Name $testOUName -Path $DomainDN -ErrorAction Stop + Remove-ADOrganizationalUnit -Identity $testOU -Confirm:$false -Recursive -ErrorAction Stop + Write-Host " [OK] Schreibzugriff funktioniert" -ForegroundColor Green +} catch { + Write-Host " [!] SCHREIBTEST FEHLGESCHLAGEN!" -ForegroundColor Red + Write-Host " [!] Fehler: $($_.Exception.Message)" -ForegroundColor Red + if ($_.Exception.InnerException) { + Write-Host " [!] Detail: $($_.Exception.InnerException.Message)" -ForegroundColor Red + } + Write-Host "`nMoegliche Ursachen:" -ForegroundColor Yellow + Write-Host " 1. Server wurde nach DC-Promotion noch nicht neugestartet" -ForegroundColor Yellow + Write-Host " 2. AD DS Datenbank nicht bereit - 'Restart-Service NTDS' oder Server neustarten" -ForegroundColor Yellow + Write-Host " 3. Dieses Konto hat keine Schreibrechte (als Domain Admin ausfuehren)" -ForegroundColor Yellow + Write-Host " 4. dcdiag /v ausfuehren fuer Details" -ForegroundColor Yellow + + $antwort = Read-Host "`nTrotzdem fortfahren? (j/n)" + if ($antwort -ne 'j') { exit 1 } +} + +Write-Host "" + # ============================================================ # 1. OU-STRUKTUR # ============================================================ -Write-Host "`n[1/4] Erstelle OU-Struktur..." -ForegroundColor Yellow +Write-Host "[1/4] Erstelle OU-Struktur..." -ForegroundColor Yellow $OUs = @( "OU=Geschaeftsfuehrung,$DomainDN", @@ -29,25 +98,37 @@ $OUs = @( "OU=Gruppen,$DomainDN" ) +$OUCreated = 0; $OUExists = 0; $OUError = 0 + foreach ($OU in $OUs) { $OUName = ($OU -split ",")[0] -replace "OU=", "" try { - $existing = Get-ADOrganizationalUnit -Identity $OU -Server $DC -ErrorAction Stop + Get-ADOrganizationalUnit -Identity $OU -ErrorAction Stop | Out-Null Write-Host " [~] OU existiert bereits: $OUName" -ForegroundColor Gray + $OUExists++ } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { try { - New-ADOrganizationalUnit -Name $OUName -Path $DomainDN -ProtectedFromAccidentalDeletion $true -Server $DC -ErrorAction Stop + New-ADOrganizationalUnit -Name $OUName -Path $DomainDN -ProtectedFromAccidentalDeletion $true -ErrorAction Stop Write-Host " [+] OU erstellt: $OUName" -ForegroundColor Green + $OUCreated++ } catch { - Write-Host " [!] FEHLER beim Erstellen von OU '$OUName': $_" -ForegroundColor Red + Write-Host " [!] FEHLER OU '$OUName': $($_.Exception.Message)" -ForegroundColor Red + $OUError++ } } catch { - # Anderer Fehler beim Pruefen - versuche trotzdem zu erstellen + # Anderer Fehler beim Pruefen (z.B. Berechtigung) - versuche trotzdem try { - New-ADOrganizationalUnit -Name $OUName -Path $DomainDN -ProtectedFromAccidentalDeletion $true -Server $DC -ErrorAction Stop + New-ADOrganizationalUnit -Name $OUName -Path $DomainDN -ProtectedFromAccidentalDeletion $true -ErrorAction Stop Write-Host " [+] OU erstellt: $OUName" -ForegroundColor Green + $OUCreated++ } catch { - Write-Host " [!] FEHLER beim Erstellen von OU '$OUName': $_" -ForegroundColor Red + if ($_.Exception.Message -like "*already exists*" -or $_.Exception.Message -like "*existiert bereits*") { + Write-Host " [~] OU existiert bereits: $OUName" -ForegroundColor Gray + $OUExists++ + } else { + Write-Host " [!] FEHLER OU '$OUName': $($_.Exception.Message)" -ForegroundColor Red + $OUError++ + } } } } @@ -71,10 +152,13 @@ $Groups = @( @{ Name = 'GRP-ADMINS'; Description = 'IT-Administratoren' } ) +$GrpCreated = 0; $GrpExists = 0; $GrpError = 0 + foreach ($Group in $Groups) { try { - $existing = Get-ADGroup -Identity $Group.Name -Server $DC -ErrorAction Stop + Get-ADGroup -Identity $Group.Name -ErrorAction Stop | Out-Null Write-Host " [~] Gruppe existiert bereits: $($Group.Name)" -ForegroundColor Gray + $GrpExists++ } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { try { New-ADGroup ` @@ -84,11 +168,12 @@ foreach ($Group in $Groups) { -GroupCategory Security ` -Description $Group.Description ` -Path "OU=Gruppen,$DomainDN" ` - -Server $Domain ` -ErrorAction Stop Write-Host " [+] Gruppe erstellt: $($Group.Name)" -ForegroundColor Green + $GrpCreated++ } catch { - Write-Host " [!] FEHLER beim Erstellen von Gruppe '$($Group.Name)': $_" -ForegroundColor Red + Write-Host " [!] FEHLER Gruppe '$($Group.Name)': $($_.Exception.Message)" -ForegroundColor Red + $GrpError++ } } catch { try { @@ -99,11 +184,17 @@ foreach ($Group in $Groups) { -GroupCategory Security ` -Description $Group.Description ` -Path "OU=Gruppen,$DomainDN" ` - -Server $Domain ` -ErrorAction Stop Write-Host " [+] Gruppe erstellt: $($Group.Name)" -ForegroundColor Green + $GrpCreated++ } catch { - Write-Host " [!] FEHLER beim Erstellen von Gruppe '$($Group.Name)': $_" -ForegroundColor Red + if ($_.Exception.Message -like "*already exists*" -or $_.Exception.Message -like "*existiert bereits*") { + Write-Host " [~] Gruppe existiert bereits: $($Group.Name)" -ForegroundColor Gray + $GrpExists++ + } else { + Write-Host " [!] FEHLER Gruppe '$($Group.Name)': $($_.Exception.Message)" -ForegroundColor Red + $GrpError++ + } } } } @@ -207,7 +298,7 @@ foreach ($User in $Users) { $UserCreated = $false try { - $existing = Get-ADUser -Identity $Sam -Server $DC -ErrorAction Stop + Get-ADUser -Identity $Sam -ErrorAction Stop | Out-Null Write-Host " [~] User existiert bereits: $Sam" -ForegroundColor Gray $UserExistsCount++ $UserCreated = $true # User existiert, Gruppen trotzdem zuweisen @@ -228,18 +319,17 @@ foreach ($User in $Users) { -PasswordNeverExpires $false ` -ChangePasswordAtLogon $true ` -Enabled $true ` - -Server $Domain ` -ErrorAction Stop Write-Host " [+] User erstellt: $Sam ($($User.Abt))" -ForegroundColor Green $UserCreatedCount++ $UserCreated = $true } catch { - Write-Host " [!] FEHLER beim Erstellen von User '$Sam': $_" -ForegroundColor Red + Write-Host " [!] FEHLER User '$Sam': $($_.Exception.Message)" -ForegroundColor Red $UserErrorCount++ } } catch { - Write-Host " [!] FEHLER beim Pruefen von User '$Sam': $_" -ForegroundColor Red + Write-Host " [!] FEHLER beim Pruefen von User '$Sam': $($_.Exception.Message)" -ForegroundColor Red $UserErrorCount++ } @@ -247,12 +337,14 @@ foreach ($User in $Users) { if ($UserCreated) { foreach ($Gruppe in $User.Gruppen) { try { - Add-ADGroupMember -Identity $Gruppe -Members $Sam -Server $DC -ErrorAction Stop + # User explizit im richtigen Domain-Kontext holen + $UserObj = Get-ADUser -Identity $Sam -ErrorAction Stop + Add-ADGroupMember -Identity $Gruppe -Members $UserObj -ErrorAction Stop } catch { - if ($_.Exception.Message -like "*already a member*" -or $_.Exception.Message -like "*ist bereits Mitglied*") { + if ($_.Exception.Message -like "*already a member*" -or $_.Exception.Message -like "*ist bereits Mitglied*" -or $_.Exception.Message -like "*member already exists*") { # Stille Warnung - User ist schon in der Gruppe } else { - Write-Warning " Gruppe '$Gruppe' konnte nicht zugewiesen werden: $_" + Write-Warning " Gruppe '$Gruppe' -> '$Sam': $($_.Exception.Message)" } } } @@ -269,7 +361,7 @@ $SvcUPN = "$SvcSam@$Domain" $SvcPW = ConvertTo-SecureString 'Mail$3rv!ceAcc2026' -AsPlainText -Force try { - $existing = Get-ADUser -Identity $SvcSam -Server $DC -ErrorAction Stop + Get-ADUser -Identity $SvcSam -ErrorAction Stop | Out-Null Write-Host " [~] Service-Account existiert bereits: $SvcSam" -ForegroundColor Gray } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { try { @@ -285,22 +377,21 @@ try { -ChangePasswordAtLogon $false ` -CannotChangePassword $true ` -Enabled $true ` - -Server $Domain ` -ErrorAction Stop Write-Host " [+] Service-Account erstellt: $SvcSam" -ForegroundColor Green } catch { - Write-Host " [!] FEHLER beim Erstellen von Service-Account '$SvcSam': $_" -ForegroundColor Red + Write-Host " [!] FEHLER Service-Account '$SvcSam': $($_.Exception.Message)" -ForegroundColor Red } } catch { - Write-Host " [!] FEHLER beim Pruefen von Service-Account '$SvcSam': $_" -ForegroundColor Red + Write-Host " [!] FEHLER beim Pruefen von Service-Account '$SvcSam': $($_.Exception.Message)" -ForegroundColor Red } # ============================================================ # ZUSAMMENFASSUNG # ============================================================ Write-Host "`n=== Setup abgeschlossen ===" -ForegroundColor Cyan -Write-Host "OUs: $($OUs.Count) konfiguriert" -ForegroundColor White -Write-Host "Gruppen: $($Groups.Count) konfiguriert" -ForegroundColor White +Write-Host "OUs: $OUCreated neu, $OUExists vorhanden, $OUError Fehler" -ForegroundColor White +Write-Host "Gruppen: $GrpCreated neu, $GrpExists vorhanden, $GrpError Fehler" -ForegroundColor White Write-Host "User: $UserCreatedCount neu erstellt, $UserExistsCount bereits vorhanden, $UserErrorCount Fehler (+ 1 Service-Account)" -ForegroundColor White Write-Host "`nStandard-Passwort User: ByteTrail2026! (Benutzer muessen es beim ersten Login aendern)" -ForegroundColor Yellow Write-Host "Service-Account Mailserver: $SvcSam / Mail`$3rv!ceAcc2026" -ForegroundColor Yellow