refactor(Active_Directory): H_Laufwerk_entfernen.ps1 ueberarbeitet

- BUGFIX: ungueltigen kombinierten OU-DN in zwei saubere DNs gespalten
- Echter -WhatIf/-Confirm-Support via [CmdletBinding(SupportsShouldProcess)]
- Sicherheits-Default: Simulation, scharf nur mit -Force
- Effizienter AD-Filter (nur User mit HomeDirectory)
- Robustere Fehlerbehandlung (Logpfad, Modul-Import, Zusammenfassung)
This commit is contained in:
buiaca 2026-07-28 18:05:30 +02:00
parent 47c489f5e3
commit 788edaace4

View File

@ -1,32 +1,53 @@
<# <#
.SYNOPSIS .SYNOPSIS
Entfernt das H-Laufwerk (Home-Drive) bei Benutzern in bestimmten OUs Entfernt das H-Laufwerk (Home-Drive) bei Benutzern in bestimmten OUs
und aktualisiert das Beschreibungsfeld inklusive Logging. und dokumentiert die Aktion im Beschreibungsfeld inkl. Logging.
.DESCRIPTION .DESCRIPTION
Das Skript durchläuft ein Array von OUs, sucht alle aktiven Benutzer, Das Skript durchläuft ein Array von OUs, sucht alle Benutzer, die ein
entfernt die Attribute 'HomeDirectory' und 'HomeDrive' (H:) und HomeDirectory (H:) haben, entfernt die Attribute 'HomeDirectory' und
ergänzt das 'Description'-Feld um einen Zeitstempel. 'HomeDrive' und ergänzt das 'Description'-Feld um einen Zeitstempel.
SICHERHEIT:
- Standardmäßig läuft das Skript im SIMULATIONSMODUS (es werden nur
Logs geschrieben, nichts im AD verändert).
- Mit -WhatIf wird simuliert (PowerShell-Standardverhalten).
- Mit -Force werden die Änderungen SCHarf in AD geschrieben.
- -Confirm fragt vor jeder einzelnen Änderung nach.
Empfehlung: Immer zuerst mit -WhatIf testen, erst dann mit -Force fahren.
.PARAMETER OUList
Array von Distinguished Names (DN) der OUs, die durchsucht werden.
Jede OU MUSS ein eigenständiger, gültiger DN sein.
.PARAMETER LogPath
Verzeichnis für die Logdateien (Default: C:\Temp\H_Laufwerk\Logs).
.PARAMETER Force
Erzwingt die reale Ausführung (ohne Simulation). Vorsicht!
.EXAMPLE
.\H_Laufwerk_entfernen.ps1 -WhatIf
Simuliert die Entfernung und schreibt nur ins Log.
.EXAMPLE
.\H_Laufwerk_entfernen.ps1 -Force
Führt die Entfernung real im AD aus (Vorsicht!).
#> #>
# --- KONFIGURATION --- [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
# Hier die OUs eintragen. Am sichersten sind vollständige Distinguished Names (DN). param (
# Beispiel für Kurznamen/Suchbegriffe siehe Filter unten im Skript. [string[]]$OUList = @(
$OUList = @( "OU=NNG,OU=Users,OU=N-Tree,DC=n-ad,DC=n-ergie",
"OU=NNG,OU=Users,OU=N-Tree,DC=n-ad,DC=n-ergie, OU=NSG,OU=Users,OU=N-Tree,DC=n-ad,DC=n-ergie" "OU=NSG,OU=Users,OU=N-Tree,DC=n-ad,DC=n-ergie"
),
[string]$LogPath = "C:\Temp\H_Laufwerk\Logs",
[switch]$Force
) )
# Pfad für das Logfile # --- SICHERHEIT: Simulation, solange weder -Force noch explizites -WhatIf ---
$LogPath = "C:\Temp\H_Laufwerk\Logs" $Simulate = -not $Force
$LogFile = Join-Path $LogPath "H-Laufwerk_Entfernung_$(Get-Date -Format 'yyyy-MM-dd').log" if ($WhatIfPreference) { $Simulate = $true }
# SICHERHEITS-SCHALTER (Safety First)
# $true = Es wird nur simuliert und geloggt, was passieren WÜRDE.
# $false = Die Änderungen werden direkt ins Active Directory geschrieben!
$WhatIfMode = $true
# --- FUNKTIONEN --- # --- FUNKTIONEN ---
Function Write-Log { function Write-Log {
Param ( [CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$Message, [string]$Message,
[ValidateSet("INFO", "SUCCESS", "WARNING", "ERROR")] [ValidateSet("INFO", "SUCCESS", "WARNING", "ERROR")]
[string]$Type = "INFO" [string]$Type = "INFO"
@ -34,7 +55,6 @@ Function Write-Log {
$TimeStamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $TimeStamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$LogLine = "[$TimeStamp] [$Type] $Message" $LogLine = "[$TimeStamp] [$Type] $Message"
# Konsole-Ausgabe (farblich angepasst)
switch ($Type) { switch ($Type) {
"SUCCESS" { Write-Host $LogLine -ForegroundColor Green } "SUCCESS" { Write-Host $LogLine -ForegroundColor Green }
"WARNING" { Write-Host $LogLine -ForegroundColor Yellow } "WARNING" { Write-Host $LogLine -ForegroundColor Yellow }
@ -42,79 +62,109 @@ Function Write-Log {
default { Write-Host $LogLine -ForegroundColor Cyan } default { Write-Host $LogLine -ForegroundColor Cyan }
} }
# In Datei schreiben try {
$LogLine | Out-File -FilePath $LogFile -Append -Encoding utf8 $LogLine | Out-File -FilePath $script:LogFile -Append -Encoding utf8
}
catch {
Write-Warning "Logdatei konnte nicht geschrieben werden: $_"
}
} }
# --- INITIALISIERUNG --- # --- INITIALISIERUNG ---
try {
if (-not (Test-Path $LogPath)) { if (-not (Test-Path $LogPath)) {
New-Item -ItemType Directory -Path $LogPath -Force | Out-Null New-Item -ItemType Directory -Path $LogPath -Force | Out-Null
} }
}
catch {
Write-Error "Logverzeichnis konnte nicht erstellt werden: $_"
exit 1
}
Write-Log "=== Skriptstart (WhatIf-Modus = $WhatIfMode) ===" "INFO" $LogFile = Join-Path $LogPath "H-Laufwerk_Entfernung_$(Get-Date -Format 'yyyy-MM-dd').log"
Write-Log "=== Skriptstart (Modus: $(if ($Simulate) { 'SIMULATION/WhatIf' } else { 'SCHARF' })) ===" "INFO"
# AD-Modul prüfen # AD-Modul prüfen
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) { if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
Write-Log "Das ActiveDirectory-Modul ist nicht installiert!" "ERROR" Write-Log "Das ActiveDirectory-Modul ist nicht installiert!" "ERROR"
Exit exit 1
}
try {
Import-Module ActiveDirectory -ErrorAction Stop
}
catch {
Write-Log "ActiveDirectory-Modul konnte nicht geladen werden: $_" "ERROR"
exit 1
} }
Import-Module ActiveDirectory
# Das aktuelle Datum für die Beschreibung generieren
$CurrentDate = Get-Date -Format "dd.MM.yyyy" $CurrentDate = Get-Date -Format "dd.MM.yyyy"
$AppendText = "H Laufwerk wurde entfernt Datum $CurrentDate" $AppendText = "H Laufwerk wurde entfernt Datum $CurrentDate"
$Processed = 0
$Skipped = 0
$Failed = 0
# --- HAUPTTEIL --- # --- HAUPTTEIL ---
foreach ($OU in $OUList) { foreach ($OU in $OUList) {
Write-Log "Verarbeite OU: $OU" "INFO" Write-Log "Verarbeite OU: $OU" "INFO"
try { try {
# Alle Benutzer aus der aktuellen OU abrufen, die ein HomeDirectory gesetzt haben # Nur Benutzer mit gesetztem HomeDirectory laden (effizienter Filter)
$Users = Get-ADUser -SearchBase $OU -SearchScope Subtree -Filter * -Properties Description, HomeDirectory, HomeDrive $Users = Get-ADUser -SearchBase $OU -SearchScope Subtree `
-Filter { HomeDirectory -like "*" } `
-Properties Description, HomeDirectory, HomeDrive -ErrorAction Stop
} }
catch { catch {
Write-Log "Fehler beim Lesen der OU '$OU': $_" "ERROR" Write-Log "Fehler beim Lesen der OU '$OU': $_" "ERROR"
$Failed++
continue continue
} }
if ($null -eq $Users -or $Users.Count -eq 0) { if ($null -eq $Users) {
Write-Log "Keine Benutzer in der OU '$OU' gefunden." "WARNING" Write-Log "Keine Benutzer mit H-Laufwerk in der OU '$OU' gefunden." "WARNING"
continue continue
} }
# Bei genau einem Treffer liefert Get-ADUser ein Skalar -> in Array wandeln
if ($Users -isnot [System.Array]) { $Users = @($Users) }
foreach ($User in $Users) { foreach ($User in $Users) {
# Prüfen, ob überhaupt ein H-Laufwerk oder HomeDirectory vorhanden ist # Neue Beschreibung: bestehende Beschreibung beibehalten + Anhang
if ([string]::IsNullOrEmpty($User.HomeDirectory) -and [string]::IsNullOrEmpty($User.HomeDrive)) {
Write-Log "Benutzer $($User.SamAccountName): Kein H-Laufwerk konfiguriert. Überspringe." "INFO"
continue
}
# Neue Beschreibung zusammensetzen (bestehende Beschreibung beibehalten)
$NewDescription = if ([string]::IsNullOrEmpty($User.Description)) { $NewDescription = if ([string]::IsNullOrEmpty($User.Description)) {
$AppendText $AppendText
} else { }
else {
"$($User.Description) | $AppendText" "$($User.Description) | $AppendText"
} }
# Log-Eintrag für die Aktion vorbereiten
$ActionMsg = "Benutzer $($User.SamAccountName) - Entferne Pfad: '$($User.HomeDirectory)' ($($User.HomeDrive)) | Neue Beschreibung: '$NewDescription'" $ActionMsg = "Benutzer $($User.SamAccountName) - Entferne Pfad: '$($User.HomeDirectory)' ($($User.HomeDrive)) | Neue Beschreibung: '$NewDescription'"
if ($Simulate) {
Write-Log "[SIMULATION] $ActionMsg" "INFO"
$Processed++
continue
}
if (-not $PSCmdlet.ShouldProcess(
$User.SamAccountName,
"HomeDirectory/HomeDrive entfernen + Beschreibung aktualisieren")) {
$Skipped++
continue
}
try { try {
if ($WhatIfMode) {
Write-Log "[WHAT-IF] $ActionMsg" "INFO"
} else {
# Änderungen scharf durchführen
Set-ADUser -Identity $User.SamAccountName ` Set-ADUser -Identity $User.SamAccountName `
-Clear "HomeDirectory", "HomeDrive" ` -Clear "HomeDirectory", "HomeDrive" `
-Description $NewDescription -Description $NewDescription
Write-Log "Erfolgreich angepasst: $($User.SamAccountName)" "SUCCESS" Write-Log "Erfolgreich angepasst: $($User.SamAccountName)" "SUCCESS"
} $Processed++
} }
catch { catch {
Write-Log "Fehler beim Verarbeiten von $($User.SamAccountName): $_" "ERROR" Write-Log "Fehler beim Verarbeiten von $($User.SamAccountName): $_" "ERROR"
$Failed++
} }
} }
} }
Write-Log "=== Skript beendet ===" "INFO" Write-Log "=== Skript beendet | Verarbeitet: $Processed | Übersprungen: $Skipped | Fehler: $Failed ===" "INFO"