# ============================================================ # ByteTrail GmbH – GPO, File Server & DFS Namespace Setup Script # Domäne: bytetrail.local # Ausführen auf: Domain Controller / Fileserver als Domain Admin # ============================================================ Import-Module GroupPolicy -ErrorAction Stop #region KONFIGURATION $Domain = "bytetrail.local" $DomainDN = "DC=bytetrail,DC=local" $NetBIOSDom = "BYTETRAIL" $MailDomain = "bytetrail.at" $FreigabePfad = "D:\Freigabe" $DfsRootPfad = "D:\DfsRoot" # NEU für Variante 1: Separater, leerer Pfad für den DFS-Root #endregion Write-Host "`n=== ByteTrail GPO, Fileserver & DFS Setup gestartet ===" -ForegroundColor Cyan # Dynamische Namensauflösung via SID try { Import-Module ActiveDirectory -ErrorAction Stop $DomainSID = (Get-ADDomain).DomainSID.Value $DomainAdminsSID = "$DomainSID-512" $DomainUsersSID = "$DomainSID-513" $DomainAdminsName = (Get-ADGroup -Identity $DomainAdminsSID).Name $DomainUsersName = (Get-ADGroup -Identity $DomainUsersSID).Name } catch { Write-Host " [!] Fehler beim Auflösen der Standardgruppen: $($_.Exception.Message)" -ForegroundColor Red return } # ============================================================ # TEIL 1: GRUPPENRICHTLINIEN (GPOs) SKELETT # ============================================================ Write-Host "`n[1/4] Konfiguriere Gruppenrichtlinien (GPOs)..." -ForegroundColor Yellow $GpoSecurityName = "ByteTrail_Base_Security" $GpoDrivesName = "ByteTrail_Mapped_Drives" # 1.1 Basis-Sicherheit (Domänenweit) if (!(Get-GPO -Name $GpoSecurityName -ErrorAction SilentlyContinue)) { try { $gpoSec = New-GPO -Name $GpoSecurityName -Comment "Basis-Sicherheitsrichtlinien (Bildschirmsperre etc.)" New-GPLink -Name $GpoSecurityName -Target $DomainDN -LinkEnabled Yes | Out-Null Set-GPRegistryValue -Name $GpoSecurityName -Key "HKCU\Software\Policies\Microsoft\Windows\Control Panel\Desktop" -ValueName "ScreenSaveActive" -Type String -Value "1" | Out-Null Set-GPRegistryValue -Name $GpoSecurityName -Key "HKCU\Software\Policies\Microsoft\Windows\Control Panel\Desktop" -ValueName "ScreenSaverIsSecure" -Type String -Value "1" | Out-Null Set-GPRegistryValue -Name $GpoSecurityName -Key "HKCU\Software\Policies\Microsoft\Windows\Control Panel\Desktop" -ValueName "ScreenSaveTimeOut" -Type String -Value "900" | Out-Null Write-Host " [+] GPO '$GpoSecurityName' erstellt, konfiguriert und mit Domäne verknüpft." -ForegroundColor Green } catch { Write-Host " [!] Fehler bei GPO '$GpoSecurityName': $($_.Exception.Message)" -ForegroundColor Red } } else { Write-Host " [~] GPO '$GpoSecurityName' existiert bereits." -ForegroundColor Gray } # 1.2 Netzlaufwerke GPO-Hülle if (!(Get-GPO -Name $GpoDrivesName -ErrorAction SilentlyContinue)) { try { New-GPO -Name $GpoDrivesName -Comment "Automatische Netzlaufwerk-Zuweisungen fuer Fachabteilungen" | Out-Null New-GPLink -Name $GpoDrivesName -Target "OU=Geschaeftsfuehrung,$DomainDN" -LinkEnabled Yes | Out-Null New-GPLink -Name $GpoDrivesName -Target "OU=Sales,$DomainDN" -LinkEnabled Yes | Out-Null New-GPLink -Name $GpoDrivesName -Target "OU=Marketing,$DomainDN" -LinkEnabled Yes | Out-Null New-GPLink -Name $GpoDrivesName -Target "OU=Service,$DomainDN" -LinkEnabled Yes | Out-Null Write-Host " [+] GPO '$GpoDrivesName' erstellt und mit OUs verknüpft." -ForegroundColor Green } catch { Write-Host " [!] Fehler bei GPO '$GpoDrivesName': $($_.Exception.Message)" -ForegroundColor Red } } else { Write-Host " [~] GPO '$GpoDrivesName' existiert bereits." -ForegroundColor Gray } # ============================================================ # TEIL 2: FILESERVER ORDNER & BERECHTIGUNGEN (NTFS) # ============================================================ Write-Host "`n[2/4] Konfiguriere Ordnerstruktur & NTFS-Berechtigungen auf $FreigabePfad..." -ForegroundColor Yellow # Haupt-Datenverzeichnis if (!(Test-Path $FreigabePfad)) { New-Item -Path $FreigabePfad -ItemType Directory -Force | Out-Null } try { Get-SmbShare -Name "Freigabe" -ErrorAction Stop | Out-Null Write-Host " [~] SMB-Freigabe 'Freigabe' existiert bereits." -ForegroundColor Gray } catch { New-SmbShare -Name "Freigabe" -Path $FreigabePfad -FullAccess "$NetBIOSDom\$DomainAdminsName" -ChangeAccess "$NetBIOSDom\$DomainUsersName" | Out-Null Write-Host " [+] SMB-Freigabe 'Freigabe' erstellt." -ForegroundColor Green } # NEU für Variante 1: Separates Verzeichnis für den DFS-Root (Muss physisch komplett leer bleiben!) if (!(Test-Path $DfsRootPfad)) { New-Item -Path $DfsRootPfad -ItemType Directory -Force | Out-Null } try { Get-SmbShare -Name "DfsRoot$" -ErrorAction Stop | Out-Null Write-Host " [~] SMB-Freigabe 'DfsRoot$' existiert bereits." -ForegroundColor Gray } catch { # Versteckte Freigabe für das DFS-Root-Skelett New-SmbShare -Name "DfsRoot$" -Path $DfsRootPfad -FullAccess "$NetBIOSDom\$DomainAdminsName" -ReadAccess "$NetBIOSDom\$DomainUsersName" | Out-Null Write-Host " [+] SMB-Freigabe 'DfsRoot$' für DFS erstellt." -ForegroundColor Green } $AclBase = Get-Acl $FreigabePfad $AclBase.SetAccessRuleProtection($true, $true) Set-Acl -Path $FreigabePfad -AclObject $AclBase $Folders = @( @{ Name = "Geschaeftsfuehrung"; Group = "GRP-GF-VOLLZUGRIFF" } @{ Name = "Sales"; Group = "GRP-SALES-FILES" } @{ Name = "Marketing"; Group = "GRP-MKT-FILES" } @{ Name = "Service"; Group = "GRP-SVC-FILES" } ) $RightsModify = [System.Security.AccessControl.FileSystemRights]::Modify $RightsRead = [System.Security.AccessControl.FileSystemRights]::ReadAndExecute $RightsFull = [System.Security.AccessControl.FileSystemRights]::FullControl $Inheritance = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit, [System.Security.AccessControl.InheritanceFlags]::ObjectInherit $Propagation = [System.Security.AccessControl.PropagationFlags]::None $Allow = [System.Security.AccessControl.AccessControlType]::Allow $RuleAdmin = New-Object System.Security.AccessControl.FileSystemAccessRule("$NetBIOSDom\GRP-ADMINS", $RightsFull, $Inheritance, $Propagation, $Allow) $RuleSystem = New-Object System.Security.AccessControl.FileSystemAccessRule("NT AUTHORITY\SYSTEM", $RightsFull, $Inheritance, $Propagation, $Allow) # Wichtig für Backup/Windows-Dienste $RuleGFRead = New-Object System.Security.AccessControl.FileSystemAccessRule("$NetBIOSDom\GRP-GF-VOLLZUGRIFF", $RightsRead, $Inheritance, $Propagation, $Allow) foreach ($Folder in $Folders) { $FolderPath = "$FreigabePfad\$($Folder.Name)" if (!(Test-Path $FolderPath)) { New-Item -Path $FolderPath -ItemType Directory -Force | Out-Null } $Acl = Get-Acl -Path $FolderPath $Acl.SetAccessRuleProtection($true, $false) $Acl.AddAccessRule($RuleAdmin) $Acl.AddAccessRule($RuleSystem) $RuleDept = New-Object System.Security.AccessControl.FileSystemAccessRule("$NetBIOSDom\$($Folder.Group)", $RightsModify, $Inheritance, $Propagation, $Allow) $Acl.AddAccessRule($RuleDept) if ($Folder.Name -ne "Geschaeftsfuehrung") { $Acl.AddAccessRule($RuleGFRead) } Set-Acl -Path $FolderPath -AclObject $Acl Write-Host " [+] Rechte für Ordner '$($Folder.Name)' erfolgreich gesetzt." -ForegroundColor Green } $AustauschPath = "$FreigabePfad\Austausch" if (!(Test-Path $AustauschPath)) { New-Item -Path $AustauschPath -ItemType Directory -Force | Out-Null } $AclAustausch = Get-Acl -Path $AustauschPath $AclAustausch.SetAccessRuleProtection($true, $false) $RuleAll = New-Object System.Security.AccessControl.FileSystemAccessRule("$NetBIOSDom\$DomainUsersName", $RightsModify, $Inheritance, $Propagation, $Allow) $AclAustausch.AddAccessRule($RuleAll) $AclAustausch.AddAccessRule($RuleAdmin) $AclAustausch.AddAccessRule($RuleSystem) Set-Acl -Path $AustauschPath -AclObject $AclAustausch Write-Host " [+] Rechte für Ordner 'Austausch' erfolgreich gesetzt." -ForegroundColor Green # ============================================================ # TEIL 3: DFS-NAMESPACES (Kollisionsfrei nach Variante 1) # ============================================================ Write-Host "`n[3/4] Konfiguriere DFS-Namespace..." -ForegroundColor Yellow if (!(Get-WindowsFeature -Name FS-DFS-Namespace).Installed) { Write-Host " [..] Installiere DFS-Namespace Server-Rolle..." -ForegroundColor Gray Install-WindowsFeature FS-DFS-Namespace -IncludeManagementTools | Out-Null } Import-Module DFSN $NamespaceRoot = "\\$Domain\Daten" $LocalServerFQDN = "$env:COMPUTERNAME.$Domain" # DFS-Root erstellen (Verweist nun exklusiv auf die leere Freigabe) try { Get-DfsnRoot -Path $NamespaceRoot -ErrorAction Stop | Out-Null Write-Host " [~] DFS-Root '$NamespaceRoot' existiert bereits." -ForegroundColor Gray } catch { New-DfsnRoot -Path $NamespaceRoot -Type DomainV2 -TargetPath "\\$LocalServerFQDN\DfsRoot$" -ErrorAction Stop | Out-Null Write-Host " [+] DFS-Root '$NamespaceRoot' erfolgreich erstellt." -ForegroundColor Green } # DFS-Ordner (Links) im leeren Namespace-Verzeichnis einrichten foreach ($Folder in $Folders) { $DfsFolderPath = "$NamespaceRoot\$($Folder.Name)" try { Get-DfsnFolder -Path $DfsFolderPath -ErrorAction Stop | Out-Null } catch { New-DfsnFolder -Path $DfsFolderPath -TargetPath "\\$LocalServerFQDN\Freigabe\$($Folder.Name)" -ErrorAction Stop | Out-Null Write-Host " [+] DFS Link erstellt: $($Folder.Name) -> $NamespaceRoot\$($Folder.Name)" -ForegroundColor Green } } # DFS Link für den öffentlichen Austausch-Ordner $DfsAustauschPath = "$NamespaceRoot\Austausch" try { Get-DfsnFolder -Path $DfsAustauschPath -ErrorAction Stop | Out-Null } catch { New-DfsnFolder -Path $DfsAustauschPath -TargetPath "\\$LocalServerFQDN\Freigabe\Austausch" -ErrorAction Stop | Out-Null Write-Host " [+] DFS Link erstellt: Austausch -> $DfsAustauschPath" -ForegroundColor Green } # ============================================================ # TEIL 4: GPP DRIVE MAPS (EMPFOHLENE VARIANTE) # ============================================================ Write-Host "`n[4/4] Konfiguriere GPP Drive Maps..." -ForegroundColor Yellow $Gpo = Get-GPO -Name $GpoDrivesName $GpoGuid = $Gpo.Id.Guid # SYSVOL Pfade $GpoRoot = "\\$Domain\SYSVOL\$Domain\Policies\{$GpoGuid}" $PreferencesPath = "$GpoRoot\User\Preferences" $DriveMapPath = "$PreferencesPath\Drives" # Ordner erzeugen New-Item -Path $DriveMapPath -ItemType Directory -Force | Out-Null # ============================================================ # DRIVE MAP XML # ============================================================ $XmlContent = @" "@ # XML speichern $XmlContent | Out-File "$DriveMapPath\Drives.xml" -Encoding UTF8 -Force # ============================================================ # GPT.INI Version erhöhen # ============================================================ $GptIni = "$GpoRoot\GPT.INI" if (Test-Path $GptIni) { $Content = Get-Content $GptIni $VersionLine = $Content | Where-Object { $_ -match "^Version=" } if ($VersionLine) { $CurrentVersion = [int]($VersionLine -replace "Version=", "") $NewVersion = $CurrentVersion + 1 $Content = $Content -replace "Version=$CurrentVersion", "Version=$NewVersion" $Content | Set-Content $GptIni -Encoding ASCII } } # ============================================================ # Netzwerk-Wartezeit aktivieren # ============================================================ Set-GPRegistryValue ` -Name $GpoSecurityName ` -Key "HKLM\Software\Policies\Microsoft\Windows NT\CurrentVersion\Winlogon" ` -ValueName "SyncForegroundPolicy" ` -Type DWord ` -Value 1 | Out-Null Write-Host " [+] GPP Drive Maps erfolgreich konfiguriert." -ForegroundColor Green Write-Host "`n=== Setup erfolgreich abgeschlossen ===" -ForegroundColor Cyan