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>
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
#Requires -RunAsAdministrator
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Phase 2.5a: Create new AD security groups for staged share rollout.
|
||||
.DESCRIPTION
|
||||
Creates three new global security groups for the new share structure.
|
||||
Groups are created EMPTY — members are added per-department when each
|
||||
department is ready to cut over to the new shares.
|
||||
|
||||
Also removes Tamra.Matthews from SG-Sales-RW (she moves to SG-Sales-RO).
|
||||
No other changes are made to existing groups or members.
|
||||
.NOTES
|
||||
IDEMPOTENT — safe to re-run. Existing groups are skipped, not overwritten.
|
||||
Run on CS-SERVER via GuruRMM remote execution.
|
||||
|
||||
Verify $GroupOU before running:
|
||||
Get-ADGroup SG-Management-RW | Select DistinguishedName
|
||||
The OU in $GroupOU must match the OU where existing SG- groups live.
|
||||
#>
|
||||
|
||||
Import-Module ActiveDirectory -ErrorAction Stop
|
||||
|
||||
# --- VERIFY THIS MATCHES WHERE EXISTING SG- GROUPS LIVE ---
|
||||
# Check with: Get-ADGroup SG-Management-RW | Select DistinguishedName
|
||||
$GroupOU = "OU=Groups,DC=cascades,DC=local"
|
||||
|
||||
Write-Host "=== Phase 2.5a: New AD Security Groups ===" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# ============================================================
|
||||
# STEP 1: Create new groups (empty — members added later)
|
||||
# ============================================================
|
||||
Write-Host "--- Creating New Security Groups ---" -ForegroundColor Yellow
|
||||
|
||||
$newGroups = @(
|
||||
@{ Name = "SG-Mgmt-RW"; Description = "Management share - Read/Write" }
|
||||
@{ Name = "SG-Sales-RO"; Description = "Sales share - Read Only" }
|
||||
@{ Name = "SG-Activities-RW"; Description = "Activities share - Read/Write" }
|
||||
)
|
||||
|
||||
foreach ($g in $newGroups) {
|
||||
try {
|
||||
$existing = Get-ADGroup -Filter "Name -eq '$($g.Name)'" -ErrorAction SilentlyContinue
|
||||
if (-not $existing) {
|
||||
New-ADGroup `
|
||||
-Name $g.Name `
|
||||
-GroupScope Global `
|
||||
-GroupCategory Security `
|
||||
-Path $GroupOU `
|
||||
-Description $g.Description `
|
||||
-ErrorAction Stop
|
||||
Write-Host " [OK] Created: $($g.Name)" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " [SKIP] $($g.Name) already exists" -ForegroundColor DarkGray
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host " [ERROR] Failed to create $($g.Name): $_" -ForegroundColor Red
|
||||
}
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# STEP 2: Remove Tamra.Matthews from SG-Sales-RW
|
||||
# ============================================================
|
||||
Write-Host "`n--- Adjusting SG-Sales-RW Membership ---" -ForegroundColor Yellow
|
||||
|
||||
try {
|
||||
$isMember = Get-ADGroupMember -Identity "SG-Sales-RW" -ErrorAction Stop |
|
||||
Where-Object { $_.SamAccountName -eq "Tamra.Matthews" }
|
||||
|
||||
if ($isMember) {
|
||||
Remove-ADGroupMember -Identity "SG-Sales-RW" -Members "Tamra.Matthews" -Confirm:$false -ErrorAction Stop
|
||||
Write-Host " [OK] Removed Tamra.Matthews from SG-Sales-RW" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " [SKIP] Tamra.Matthews is not a member of SG-Sales-RW" -ForegroundColor DarkGray
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host " [ERROR] Failed to adjust SG-Sales-RW: $_" -ForegroundColor Red
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# SUMMARY: All SG- groups with member counts
|
||||
# ============================================================
|
||||
Write-Host "`n=== SG- Group Summary ===" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
Get-ADGroup -Filter 'Name -like "SG-*"' -ErrorAction SilentlyContinue |
|
||||
Sort-Object Name |
|
||||
ForEach-Object {
|
||||
$count = (Get-ADGroupMember $_ -ErrorAction SilentlyContinue | Measure-Object).Count
|
||||
Write-Host (" {0,-25} {1,2} member(s)" -f $_.Name, $count) -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "=== AD Groups Complete ===" -ForegroundColor Cyan
|
||||
Write-Host "Next: Run phase2-new-shares.ps1 to create the folder structure and SMB shares" -ForegroundColor Green
|
||||
@@ -0,0 +1,173 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user