Files
claudetools/clients/cascades-tucson/docs/migration/scripts/phase2-new-shares.ps1
Howard Enos 3328a24742 client/cascades: Phase 2.5 AD groups and shares — COMPLETE
Created SG-Mgmt-RW, SG-Sales-RO, SG-Activities-RW in OU=Groups.
Created SMB shares Management, Sales, Activities, Server on D:\Shares
with ABE enabled and correct NTFS ACLs per group.
Scripts run on CS-SERVER via GuruRMM 2026-05-20. AD doc updated to live state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 22:32:20 -07:00

174 lines
6.0 KiB
PowerShell

#Requires -RunAsAdministrator
<#
.SYNOPSIS
Phase 2.5b: Create new share folders, NTFS permissions, and SMB shares on CS-SERVER.
.DESCRIPTION
Builds the folder structure for the staged share rollout. Folders are created
empty — data sync runs separately after this script. Sets NTFS permissions with
broken inheritance and creates SMB shares with Access-Based Enumeration enabled.
Shares created: Management, Sales, Activities, Server.
Does NOT touch: D:\Shares\homes, D:\Shares\Culinary, D:\Shares\Receptionist,
D:\Shares\directoryshare, D:\Shares\IT, D:\Shares\chat, D:\Shares\Public,
or any other existing shares.
.NOTES
IDEMPOTENT — safe to re-run. NTFS permissions are always reapplied (not skipped).
Existing SMB shares have their description updated; share-level permissions are
left alone on re-run.
Requires the ActiveDirectory module and must be run as Administrator on CS-SERVER.
Run AFTER phase2-ad-groups-new.ps1.
#>
Import-Module ActiveDirectory -ErrorAction Stop
$DestRoot = "D:\Shares"
Write-Host "=== Phase 2.5b: New Share Folders & Permissions ===" -ForegroundColor Cyan
Write-Host ""
# --- Share definitions ---
# RWGroup and ROGroup may be $null. $null means that ACE is omitted.
$shares = @(
@{
Name = "Management"
Path = "$DestRoot\Management"
RWGroup = "CASCADES\SG-Mgmt-RW"
ROGroup = $null
Desc = "Management share (Directors only)"
},
@{
Name = "Sales"
Path = "$DestRoot\Sales"
RWGroup = "CASCADES\SG-Sales-RW"
ROGroup = "CASCADES\SG-Sales-RO"
Desc = "Sales share"
},
@{
Name = "Activities"
Path = "$DestRoot\Activities"
RWGroup = "CASCADES\SG-Activities-RW"
ROGroup = $null
Desc = "Activities share (Life Enrichment)"
},
@{
Name = "Server"
Path = "$DestRoot\Server"
RWGroup = "CASCADES\SG-IT-RW"
ROGroup = "CASCADES\Domain Users"
Desc = "Server share (IT tools and scripts)"
}
)
foreach ($s in $shares) {
Write-Host "`n--- $($s.Name) ---" -ForegroundColor Yellow
# Create folder if it doesn't exist
try {
if (-not (Test-Path $s.Path)) {
New-Item -Path $s.Path -ItemType Directory -Force | Out-Null
Write-Host " [OK] Created folder: $($s.Path)" -ForegroundColor Green
} else {
Write-Host " [SKIP] Folder already exists: $($s.Path)" -ForegroundColor DarkGray
}
}
catch {
Write-Host " [ERROR] Failed to create folder $($s.Path): $_" -ForegroundColor Red
continue
}
# Set NTFS permissions (always reapplied — not skipped on re-run)
try {
$acl = New-Object System.Security.AccessControl.DirectorySecurity
# Break inheritance and discard all inherited entries
$acl.SetAccessRuleProtection($true, $false)
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule(
"SYSTEM",
"FullControl",
"ContainerInherit,ObjectInherit",
"None",
"Allow"
)))
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule(
"CASCADES\Domain Admins",
"FullControl",
"ContainerInherit,ObjectInherit",
"None",
"Allow"
)))
if ($s.RWGroup) {
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule(
$s.RWGroup,
"Modify",
"ContainerInherit,ObjectInherit",
"None",
"Allow"
)))
}
if ($s.ROGroup) {
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule(
$s.ROGroup,
"ReadAndExecute",
"ContainerInherit,ObjectInherit",
"None",
"Allow"
)))
}
Set-Acl -Path $s.Path -AclObject $acl -ErrorAction Stop
Write-Host " [OK] NTFS permissions set" -ForegroundColor Green
}
catch {
Write-Host " [ERROR] NTFS permissions failed on $($s.Path): $_" -ForegroundColor Red
continue
}
# Create or update SMB share
try {
$existingShare = Get-SmbShare -Name $s.Name -ErrorAction SilentlyContinue
if (-not $existingShare) {
New-SmbShare `
-Name $s.Name `
-Path $s.Path `
-Description $s.Desc `
-FullAccess "Authenticated Users" `
-FolderEnumerationMode AccessBased `
-ErrorAction Stop
Write-Host " [OK] Created SMB share: \\CS-SERVER\$($s.Name) (ABE enabled)" -ForegroundColor Green
} else {
# Update description only; share-level permissions are left alone
Set-SmbShare -Name $s.Name -Description $s.Desc -Force -ErrorAction Stop
Write-Host " [SKIP] SMB share already exists — description updated" -ForegroundColor DarkGray
}
}
catch {
Write-Host " [ERROR] SMB share failed for $($s.Name): $_" -ForegroundColor Red
}
}
# ============================================================
# SUMMARY
# ============================================================
Write-Host "`n=== New Shares Summary ===" -ForegroundColor Cyan
Write-Host "`nAll SMB shares on D:\:" -ForegroundColor Yellow
Get-SmbShare | Where-Object { $_.Path -like "D:\*" } |
Select-Object Name, Path, Description, FolderEnumerationMode |
Format-Table -AutoSize -Wrap
Write-Host "NTFS permissions on new folders:" -ForegroundColor Yellow
foreach ($s in $shares) {
if (Test-Path $s.Path) {
Write-Host "`n $($s.Path):" -ForegroundColor Cyan
& icacls $s.Path
}
}
Write-Host "`n=== New Share Setup Complete ===" -ForegroundColor Cyan
Write-Host "Folders are empty — sync data separately before activating each department." -ForegroundColor Green