<# .SYNOPSIS Lists all SMB shares of a Windows file server incl. local path, size and permissions โ€” the basis for the include/exclude decision (projektplan ยง2.6). .DESCRIPTION Run ON the file server (or against a remote one via -ComputerName). Reports per share: name, local path, description, share-level permissions, NTFS groups, plus optional size/file count. Admin shares (C$, ADMIN$, IPC$) are skipped unless -IncludeAdminShares is given. Purely read-only. Requires local admin for Get-SmbShare (part of Windows Server, no extra module needed). .EXAMPLE .\list-shares.ps1 .EXAMPLE # remote, and with size per share (slow on large shares) .\list-shares.ps1 -ComputerName Z-FILESERVER -WithSize #> param( [string]$ComputerName = $env:COMPUTERNAME, [switch]$IncludeAdminShares, [switch]$WithSize, [string]$OutDir = (Join-Path (Get-Location) "share-list") ) $ErrorActionPreference = 'Continue' New-Item -ItemType Directory -Path $OutDir -Force | Out-Null Write-Host "=== SMB shares on $ComputerName ===" -ForegroundColor Cyan $shares = Get-SmbShare -CimSession $ComputerName -ErrorAction Stop if (-not $IncludeAdminShares) { $shares = $shares | Where-Object { -not $_.Name.EndsWith('$') } } $result = foreach ($sh in $shares) { Write-Host (" {0,-25} {1}" -f $sh.Name, $sh.Path) # share-level permissions $sharePerms = try { (Get-SmbShareAccess -Name $sh.Name -CimSession $ComputerName -ErrorAction Stop | ForEach-Object { "$($_.AccountName)=$($_.AccessRight)" }) -join '; ' } catch { 'n/a' } # NTFS permissions (top level only) โ€” who actually has access $ntfsPerms = try { $uncPath = "\\$ComputerName\$($sh.Name)" ((Get-Acl -LiteralPath $uncPath -ErrorAction Stop).Access | ForEach-Object { "$($_.IdentityReference)=$($_.FileSystemRights)" } | Select-Object -Unique | Select-Object -First 10) -join '; ' } catch { 'n/a' } $sizeGB = $null; $fileCount = $null if ($WithSize) { Write-Host " measuring size ..." -ForegroundColor DarkGray try { $m = Get-ChildItem -LiteralPath "\\$ComputerName\$($sh.Name)" -Recurse -File -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum $sizeGB = [Math]::Round($m.Sum / 1GB, 2) $fileCount = $m.Count } catch { } } [PSCustomObject]@{ Name = $sh.Name Path = $sh.Path Description = $sh.Description SharePermissions = $sharePerms NtfsPermissions = $ntfsPerms SizeGB = $sizeGB FileCount = $fileCount } } $csv = Join-Path $OutDir "smb-shares.csv" $result | Export-Csv $csv -NoTypeInformation -Encoding UTF8 $result | Format-Table Name, Path, SizeGB, FileCount -AutoSize # DFS namespaces (if used) โ€” often the path users actually see Write-Host "`n=== DFS namespaces ===" -ForegroundColor Cyan try { $roots = Get-DfsnRoot -ErrorAction Stop if ($roots) { $dfs = foreach ($r in $roots) { Get-DfsnFolder -Path "$($r.Path)\*" -ErrorAction SilentlyContinue | ForEach-Object { $t = Get-DfsnFolderTarget -Path $_.Path -ErrorAction SilentlyContinue [PSCustomObject]@{ DfsPath = $_.Path; Targets = ($t.TargetPath -join '; ') } } } $dfs | Export-Csv (Join-Path $OutDir "dfs-namespaces.csv") -NoTypeInformation -Encoding UTF8 $dfs | Format-Table -AutoSize } else { Write-Host " none" } } catch { Write-Host " no DFS role / not available on this host" } Write-Host "`nResults in: $OutDir" -ForegroundColor Green