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,120 +1,170 @@
<#
.SYNOPSIS
Entfernt das H-Laufwerk (Home-Drive) bei Benutzern in bestimmten OUs
und aktualisiert das Beschreibungsfeld inklusive Logging.
Entfernt das H-Laufwerk (Home-Drive) bei Benutzern in bestimmten OUs
und dokumentiert die Aktion im Beschreibungsfeld inkl. Logging.
.DESCRIPTION
Das Skript durchläuft ein Array von OUs, sucht alle aktiven Benutzer,
entfernt die Attribute 'HomeDirectory' und 'HomeDrive' (H:) und
ergänzt das 'Description'-Feld um einen Zeitstempel.
Das Skript durchläuft ein Array von OUs, sucht alle Benutzer, die ein
HomeDirectory (H:) haben, entfernt die Attribute 'HomeDirectory' und
'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 ---
# Hier die OUs eintragen. Am sichersten sind vollständige Distinguished Names (DN).
# Beispiel für Kurznamen/Suchbegriffe siehe Filter unten im Skript.
$OUList = @(
"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"
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
param (
[string[]]$OUList = @(
"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"
),
[string]$LogPath = "C:\Temp\H_Laufwerk\Logs",
[switch]$Force
)
# Pfad für das Logfile
$LogPath = "C:\Temp\H_Laufwerk\Logs"
$LogFile = Join-Path $LogPath "H-Laufwerk_Entfernung_$(Get-Date -Format 'yyyy-MM-dd').log"
# 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
# --- SICHERHEIT: Simulation, solange weder -Force noch explizites -WhatIf ---
$Simulate = -not $Force
if ($WhatIfPreference) { $Simulate = $true }
# --- FUNKTIONEN ---
Function Write-Log {
Param (
function Write-Log {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$Message,
[ValidateSet("INFO", "SUCCESS", "WARNING", "ERROR")]
[string]$Type = "INFO"
)
$TimeStamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$LogLine = "[$TimeStamp] [$Type] $Message"
# Konsole-Ausgabe (farblich angepasst)
$LogLine = "[$TimeStamp] [$Type] $Message"
switch ($Type) {
"SUCCESS" { Write-Host $LogLine -ForegroundColor Green }
"WARNING" { Write-Host $LogLine -ForegroundColor Yellow }
"ERROR" { Write-Host $LogLine -ForegroundColor Red }
default { Write-Host $LogLine -ForegroundColor Cyan }
}
# In Datei schreiben
$LogLine | Out-File -FilePath $LogFile -Append -Encoding utf8
try {
$LogLine | Out-File -FilePath $script:LogFile -Append -Encoding utf8
}
catch {
Write-Warning "Logdatei konnte nicht geschrieben werden: $_"
}
}
# --- INITIALISIERUNG ---
if (-not (Test-Path $LogPath)) {
New-Item -ItemType Directory -Path $LogPath -Force | Out-Null
try {
if (-not (Test-Path $LogPath)) {
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
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
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"
$AppendText = "H Laufwerk wurde entfernt Datum $CurrentDate"
$AppendText = "H Laufwerk wurde entfernt Datum $CurrentDate"
$Processed = 0
$Skipped = 0
$Failed = 0
# --- HAUPTTEIL ---
foreach ($OU in $OUList) {
Write-Log "Verarbeite OU: $OU" "INFO"
try {
# Alle Benutzer aus der aktuellen OU abrufen, die ein HomeDirectory gesetzt haben
$Users = Get-ADUser -SearchBase $OU -SearchScope Subtree -Filter * -Properties Description, HomeDirectory, HomeDrive
# Nur Benutzer mit gesetztem HomeDirectory laden (effizienter Filter)
$Users = Get-ADUser -SearchBase $OU -SearchScope Subtree `
-Filter { HomeDirectory -like "*" } `
-Properties Description, HomeDirectory, HomeDrive -ErrorAction Stop
}
catch {
Write-Log "Fehler beim Lesen der OU '$OU': $_" "ERROR"
$Failed++
continue
}
if ($null -eq $Users -or $Users.Count -eq 0) {
Write-Log "Keine Benutzer in der OU '$OU' gefunden." "WARNING"
if ($null -eq $Users) {
Write-Log "Keine Benutzer mit H-Laufwerk in der OU '$OU' gefunden." "WARNING"
continue
}
# Bei genau einem Treffer liefert Get-ADUser ein Skalar -> in Array wandeln
if ($Users -isnot [System.Array]) { $Users = @($Users) }
foreach ($User in $Users) {
# Prüfen, ob überhaupt ein H-Laufwerk oder HomeDirectory vorhanden ist
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)
# Neue Beschreibung: bestehende Beschreibung beibehalten + Anhang
$NewDescription = if ([string]::IsNullOrEmpty($User.Description)) {
$AppendText
} else {
}
else {
"$($User.Description) | $AppendText"
}
# Log-Eintrag für die Aktion vorbereiten
$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 {
if ($WhatIfMode) {
Write-Log "[WHAT-IF] $ActionMsg" "INFO"
} else {
# Änderungen scharf durchführen
Set-ADUser -Identity $User.SamAccountName `
-Clear "HomeDirectory", "HomeDrive" `
-Description $NewDescription
Write-Log "Erfolgreich angepasst: $($User.SamAccountName)" "SUCCESS"
}
Set-ADUser -Identity $User.SamAccountName `
-Clear "HomeDirectory", "HomeDrive" `
-Description $NewDescription
Write-Log "Erfolgreich angepasst: $($User.SamAccountName)" "SUCCESS"
$Processed++
}
catch {
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"