# Als Administrator ausführen # Testaufbau für Standalone DFS Namespace auf Windows Server 2016 $ErrorActionPreference = "Stop" # ========================= # Konfiguration # ========================= $ServerFqdn = "srvwsm001.imagoverum.com" $NamespaceName = "DFS" $NamespacePath = "\\$ServerFqdn\$NamespaceName" $RootPath = "C:\$NamespaceName" $Shares = @( @{ Name = "share1"; Path = "C:\share1" }, @{ Name = "share2"; Path = "C:\share2" } ) # ========================= # Hilfsfunktionen # ========================= function Write-Step { param([string]$Text) Write-Host "`n=== $Text ===" -ForegroundColor Cyan } function Ensure-WindowsFeatureInstalled { param([string]$FeatureName) $feature = Get-WindowsFeature -Name $FeatureName if (-not $feature) { throw "Windows-Feature '$FeatureName' wurde nicht gefunden." } if ($feature.Installed) { Write-Host "Feature '$FeatureName' ist bereits installiert." -ForegroundColor Yellow } else { Write-Host "Installiere Feature '$FeatureName'..." -ForegroundColor Green Install-WindowsFeature -Name $FeatureName -IncludeManagementTools | Out-Null Write-Host "Feature '$FeatureName' wurde installiert." -ForegroundColor Green } } function Ensure-DirectoryExists { param([string]$Path) if (Test-Path -LiteralPath $Path) { Write-Host "Ordner existiert bereits: $Path" -ForegroundColor Yellow } else { New-Item -Path $Path -ItemType Directory -Force | Out-Null Write-Host "Ordner angelegt: $Path" -ForegroundColor Green } } function Ensure-ModifyAclEveryone { param([string]$Path) if (-not (Test-Path -LiteralPath $Path)) { throw "Pfad nicht gefunden: $Path" } $acl = Get-Acl -Path $Path $inheritanceFlags = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit" $propagationFlags = [System.Security.AccessControl.PropagationFlags]::None $rights = [System.Security.AccessControl.FileSystemRights]::Modify $accessType = [System.Security.AccessControl.AccessControlType]::Allow $rule = New-Object System.Security.AccessControl.FileSystemAccessRule( "Everyone", $rights, $inheritanceFlags, $propagationFlags, $accessType ) $existing = $false foreach ($entry in $acl.Access) { if ( $entry.IdentityReference.Value -eq "Everyone" -and $entry.AccessControlType -eq "Allow" -and (($entry.FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::Modify) -ne 0) ) { $existing = $true break } } if ($existing) { Write-Host "NTFS-Recht bereits vorhanden: Everyone Modify auf $Path" -ForegroundColor Yellow } else { $acl.AddAccessRule($rule) | Out-Null Set-Acl -Path $Path -AclObject $acl Write-Host "NTFS-Recht gesetzt: Everyone Modify auf $Path" -ForegroundColor Green } } function Ensure-SmbShareExists { param( [string]$Name, [string]$Path ) $share = Get-SmbShare -Name $Name -ErrorAction SilentlyContinue if (-not $share) { New-SmbShare -Name $Name -Path $Path -FullAccess "Everyone" | Out-Null Write-Host "SMB-Share angelegt: \\$ServerFqdn\$Name -> $Path" -ForegroundColor Green return } Write-Host "SMB-Share existiert bereits: \\$ServerFqdn\$Name" -ForegroundColor Yellow if ($share.Path -ne $Path) { throw "Share '$Name' existiert bereits, zeigt aber auf '$($share.Path)' statt '$Path'. Bitte manuell korrigieren." } $shareAccess = Get-SmbShareAccess -Name $Name -ErrorAction SilentlyContinue $everyoneFull = $shareAccess | Where-Object { $_.Name -eq "Everyone" -and $_.AccessControlType -eq "Allow" -and $_.AccessRight -eq "Full" } if (-not $everyoneFull) { Grant-SmbShareAccess -Name $Name -AccountName "Everyone" -AccessRight Full -Force | Out-Null Write-Host "Share-Recht ergänzt: Everyone Full auf \\$ServerFqdn\$Name" -ForegroundColor Green } else { Write-Host "Share-Recht bereits vorhanden: Everyone Full auf \\$ServerFqdn\$Name" -ForegroundColor Yellow } } function Ensure-DfsRootExists { param( [string]$NamespacePath, [string]$TargetPath ) $root = Get-DfsnRoot -Path $NamespacePath -ErrorAction SilentlyContinue if ($root) { Write-Host "DFS Namespace existiert bereits: $NamespacePath" -ForegroundColor Yellow return } if (-not (Get-SmbShare -Name $NamespaceName -ErrorAction SilentlyContinue)) { throw "Root-Share '$NamespaceName' existiert nicht. DFS Root kann nicht erstellt werden." } New-DfsnRoot -Path $NamespacePath -TargetPath $TargetPath -Type Standalone | Out-Null Write-Host "DFS Namespace angelegt: $NamespacePath" -ForegroundColor Green } function Ensure-DfsFolderExists { param( [string]$FolderPath, [string]$TargetPath ) $folder = Get-DfsnFolder -Path $FolderPath -ErrorAction SilentlyContinue if (-not $folder) { New-DfsnFolder -Path $FolderPath -TargetPath $TargetPath | Out-Null Write-Host "DFS-Ordner angelegt: $FolderPath -> $TargetPath" -ForegroundColor Green return } Write-Host "DFS-Ordner existiert bereits: $FolderPath" -ForegroundColor Yellow $targets = Get-DfsnFolderTarget -Path $FolderPath -ErrorAction SilentlyContinue $targetExists = $targets | Where-Object { $_.TargetPath -eq $TargetPath } if (-not $targetExists) { New-DfsnFolderTarget -Path $FolderPath -TargetPath $TargetPath | Out-Null Write-Host "DFS-Target ergänzt: $FolderPath -> $TargetPath" -ForegroundColor Green } else { Write-Host "DFS-Target bereits vorhanden: $FolderPath -> $TargetPath" -ForegroundColor Yellow } } # ========================= # Start # ========================= Write-Step "DFS Rolle sicherstellen" Ensure-WindowsFeatureInstalled -FeatureName "FS-DFS-Namespace" Write-Step "Root-Ordner und Shares sicherstellen" Ensure-DirectoryExists -Path $RootPath Ensure-ModifyAclEveryone -Path $RootPath Ensure-SmbShareExists -Name $NamespaceName -Path $RootPath Write-Step "Zielordner und Shares sicherstellen" foreach ($s in $Shares) { Ensure-DirectoryExists -Path $s.Path Ensure-ModifyAclEveryone -Path $s.Path Ensure-SmbShareExists -Name $s.Name -Path $s.Path } Write-Step "DFS Namespace sicherstellen" Ensure-DfsRootExists -NamespacePath $NamespacePath -TargetPath "\\$ServerFqdn\$NamespaceName" Write-Step "DFS Ordner sicherstellen" foreach ($s in $Shares) { $dfsFolderPath = "$NamespacePath\$($s.Name)" $targetPath = "\\$ServerFqdn\$($s.Name)" Ensure-DfsFolderExists -FolderPath $dfsFolderPath -TargetPath $targetPath } Write-Step "Ergebnis" Write-Host "Namespace: $NamespacePath" -ForegroundColor Green foreach ($s in $Shares) { Write-Host " - $NamespacePath\$($s.Name) -> \\$ServerFqdn\$($s.Name)" -ForegroundColor Green } Write-Host "`nFertig." -ForegroundColor Green