Files
bytetrail/Configure-ByteTrail-FileServer.ps1
T
2026-05-25 14:43:12 +02:00

374 lines
16 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ============================================================
# 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 version="1.0" encoding="utf-8"?>
<Drives clsid="{8FDDCC1A-0C3C-43cd-A6B4-71A6DF20DA8C}">
<!-- Geschäftsführung -->
<Drive clsid="{935D1B74-9CB8-4e3c-9914-7DD559B7A417}" name="G:" status="G">
<Properties action="U"
thisDrive="SHOW"
allDrives="NOCHANGE"
userName=""
path="\\$Domain\Daten\Geschaeftsfuehrung"
label="Geschaeftsfuehrung"
persistent="1"
useLetter="1"
letter="G" />
<Filters>
<FilterGroup bool="AND"
not="0"
name="$NetBIOSDom\GRP-GF-VOLLZUGRIFF"
sid=""
userContext="1"
primaryGroup="0"
localGroup="0" />
</Filters>
</Drive>
<!-- Sales -->
<Drive clsid="{935D1B74-9CB8-4e3c-9914-7DD559B7A417}" name="S:" status="S">
<Properties action="U"
thisDrive="SHOW"
allDrives="NOCHANGE"
userName=""
path="\\$Domain\Daten\Sales"
label="Sales"
persistent="1"
useLetter="1"
letter="S" />
<Filters>
<FilterGroup bool="AND"
not="0"
name="$NetBIOSDom\GRP-SALES-FILES"
sid=""
userContext="1"
primaryGroup="0"
localGroup="0" />
</Filters>
</Drive>
<!-- Marketing -->
<Drive clsid="{935D1B74-9CB8-4e3c-9914-7DD559B7A417}" name="M:" status="M">
<Properties action="U"
thisDrive="SHOW"
allDrives="NOCHANGE"
userName=""
path="\\$Domain\Daten\Marketing"
label="Marketing"
persistent="1"
useLetter="1"
letter="M" />
<Filters>
<FilterGroup bool="AND"
not="0"
name="$NetBIOSDom\GRP-MKT-FILES"
sid=""
userContext="1"
primaryGroup="0"
localGroup="0" />
</Filters>
</Drive>
<!-- Service -->
<Drive clsid="{935D1B74-9CB8-4e3c-9914-7DD559B7A417}" name="T:" status="T">
<Properties action="U"
thisDrive="SHOW"
allDrives="NOCHANGE"
userName=""
path="\\$Domain\Daten\Service"
label="Service"
persistent="1"
useLetter="1"
letter="T" />
<Filters>
<FilterGroup bool="AND"
not="0"
name="$NetBIOSDom\GRP-SVC-FILES"
sid=""
userContext="1"
primaryGroup="0"
localGroup="0" />
</Filters>
</Drive>
<!-- Austausch -->
<Drive clsid="{935D1B74-9CB8-4e3c-9914-7DD559B7A417}" name="X:" status="X">
<Properties action="U"
thisDrive="SHOW"
allDrives="NOCHANGE"
userName=""
path="\\$Domain\Daten\Austausch"
label="Austausch"
persistent="1"
useLetter="1"
letter="X" />
</Drive>
</Drives>
"@
# 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