Files
claudetools/clients/cascades-tucson/docs/migration/scripts/phase0-export-configs.ps1
Howard Enos 8d975c1b44 import: ingested 160 files from C:\Users\howar\Clients
Howard's personal MSP client documentation folder imported into shared
ClaudeTools repo via /import command. Scope:

Clients (structured MSP docs under clients/<name>/docs/):
- anaise       (NEW)  - 13 files
- cascades-tucson     - 47 files merged (existing had only reports/)
- dataforth           - 18 files merged (alongside incident reports)
- instrumental-music-center - 14 files merged
- khalsa       (NEW)  - 22 files, multi-site (camden, river)
- kittle       (NEW)  - 16 files incl. fix-pdf-preview, gpo-intranet-zone
- lens-auto-brokerage (NEW) - 3 files (name matches SOPS vault)
- _client_template    - 13-file scaffold for new clients

MSP tooling (projects/msp-tools/):
- msp-audit-scripts/ - server_audit.ps1, workstation_audit.ps1, README
- utilities/         - clean_printer_ports, win11_upgrade,
                       screenconnect-toolbox-commands

Credential handling:
- Extracted 1 inline password (Anaise DESKTOP-O8GF4SD / david)
  to SOPS vault: clients/anaise/desktop-o8gf4sd.sops.yaml
- Redacted overview.md with vault reference pattern
- Scanned all 160 files for keys/tokens/connection strings -
  no other credentials found

Skipped:
- Cascades/.claude/settings.local.json (per-machine config)
- Source-root CLAUDE.md (personal, claudetools has its own)
- scripts/server_audit.ps1 and workstation_audit.ps1 at source root
  (identical duplicates of msp-audit-scripts versions)

Memory updates:
- reference_client_docs_structure.md (layout, conventions, active list)
- reference_msp_audit_scripts.md (locations, ScreenConnect 80-char rule)

Session log: session-logs/2026-04-16-howard-client-docs-import.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 19:43:58 -07:00

162 lines
6.3 KiB
PowerShell

#Requires -RunAsAdministrator
<#
.SYNOPSIS
Phase 0: Export all configuration snapshots from CS-SERVER before migration.
.DESCRIPTION
Exports AD users/computers/groups, DNS records, NPS config, and file share
permissions to D:\Shares\IT\Backups\. Run on CS-SERVER via ScreenConnect.
.NOTES
Run BEFORE making any changes. This is the safety net.
#>
$BackupRoot = "D:\Shares\IT\Backups"
$Timestamp = Get-Date -Format "yyyy-MM-dd_HHmm"
Write-Host "=== Phase 0: Configuration Export ===" -ForegroundColor Cyan
Write-Host "Timestamp: $Timestamp"
Write-Host ""
# --- Create backup directories ---
$dirs = @("AD", "DNS", "NPS", "Permissions", "pfSense", "SynologyDrive-Audit")
foreach ($d in $dirs) {
New-Item -Path "$BackupRoot\$d" -ItemType Directory -Force | Out-Null
}
Write-Host "[OK] Backup directories created at $BackupRoot" -ForegroundColor Green
# --- AD Export ---
Write-Host "`n--- Exporting Active Directory ---" -ForegroundColor Yellow
try {
Import-Module ActiveDirectory -ErrorAction Stop
Get-ADUser -Filter * -Properties * |
Export-Csv "$BackupRoot\AD\AD-Users_$Timestamp.csv" -NoTypeInformation
Write-Host "[OK] AD Users exported" -ForegroundColor Green
Get-ADComputer -Filter * -Properties * |
Export-Csv "$BackupRoot\AD\AD-Computers_$Timestamp.csv" -NoTypeInformation
Write-Host "[OK] AD Computers exported" -ForegroundColor Green
Get-ADGroup -Filter * | ForEach-Object {
$g = $_
Get-ADGroupMember $g -ErrorAction SilentlyContinue |
Select-Object @{N='Group';E={$g.Name}}, Name, SamAccountName
} | Export-Csv "$BackupRoot\AD\AD-Groups_$Timestamp.csv" -NoTypeInformation
Write-Host "[OK] AD Groups exported" -ForegroundColor Green
Get-ADOrganizationalUnit -Filter * -Properties * |
Export-Csv "$BackupRoot\AD\AD-OUs_$Timestamp.csv" -NoTypeInformation
Write-Host "[OK] AD OUs exported" -ForegroundColor Green
}
catch {
Write-Host "[ERROR] AD export failed: $_" -ForegroundColor Red
}
# --- DNS Export ---
Write-Host "`n--- Exporting DNS ---" -ForegroundColor Yellow
try {
Import-Module DnsServer -ErrorAction Stop
Get-DnsServerResourceRecord -ZoneName "cascades.local" |
Export-Csv "$BackupRoot\DNS\DNS-Records_$Timestamp.csv" -NoTypeInformation
Write-Host "[OK] DNS records exported" -ForegroundColor Green
Get-DnsServerZone |
Export-Csv "$BackupRoot\DNS\DNS-Zones_$Timestamp.csv" -NoTypeInformation
Write-Host "[OK] DNS zones exported" -ForegroundColor Green
Get-DnsServerForwarder |
Export-Csv "$BackupRoot\DNS\DNS-Forwarders_$Timestamp.csv" -NoTypeInformation
Write-Host "[OK] DNS forwarders exported" -ForegroundColor Green
}
catch {
Write-Host "[ERROR] DNS export failed: $_" -ForegroundColor Red
}
# --- NPS/RADIUS Export ---
Write-Host "`n--- Exporting NPS/RADIUS ---" -ForegroundColor Yellow
try {
$npsFile = "$BackupRoot\NPS\nps-config_$Timestamp.xml"
$result = netsh nps export filename="$npsFile" exportPSK=YES 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Host "[OK] NPS config exported" -ForegroundColor Green
} else {
Write-Host "[WARN] NPS export returned: $result" -ForegroundColor Yellow
}
}
catch {
Write-Host "[WARN] NPS export failed (may not be installed): $_" -ForegroundColor Yellow
}
# --- File Share Permissions Export ---
Write-Host "`n--- Exporting File Share Permissions ---" -ForegroundColor Yellow
try {
$shares = Get-SmbShare | Where-Object { $_.Path -like "D:\*" }
foreach ($s in $shares) {
$shareName = $s.Name -replace '[\\/:*?"<>|]', '_'
# NTFS permissions via icacls
icacls $s.Path /save "$BackupRoot\Permissions\${shareName}-icacls_$Timestamp.txt" /T /C 2>$null
Write-Host " [OK] NTFS permissions for $($s.Name)" -ForegroundColor Green
# SMB share-level permissions
Get-SmbShareAccess -Name $s.Name |
Export-Csv "$BackupRoot\Permissions\${shareName}-SMB_$Timestamp.csv" -NoTypeInformation
Write-Host " [OK] SMB permissions for $($s.Name)" -ForegroundColor Green
}
# Also export the share list itself
Get-SmbShare | Select-Object Name, Path, Description, CurrentUsers |
Export-Csv "$BackupRoot\Permissions\AllShares_$Timestamp.csv" -NoTypeInformation
Write-Host "[OK] Share list exported" -ForegroundColor Green
}
catch {
Write-Host "[ERROR] Share permissions export failed: $_" -ForegroundColor Red
}
# --- SynologyDrive Audit ---
Write-Host "`n--- Auditing SynologyDrive ---" -ForegroundColor Yellow
if (Test-Path "D:\Shares\SynologyDrive") {
Get-ChildItem "D:\Shares\SynologyDrive" -Depth 2 |
Select-Object FullName, Length, LastWriteTime, PSIsContainer |
Export-Csv "$BackupRoot\SynologyDrive-Audit\SynologyDrive-Contents_$Timestamp.csv" -NoTypeInformation
Write-Host "[OK] SynologyDrive structure exported" -ForegroundColor Green
# Summary
$stats = Get-ChildItem "D:\Shares\SynologyDrive" -Recurse -File -ErrorAction SilentlyContinue
Write-Host " Total files: $($stats.Count)" -ForegroundColor Cyan
Write-Host " Total size: $([math]::Round(($stats | Measure-Object Length -Sum).Sum / 1GB, 2)) GB" -ForegroundColor Cyan
} else {
Write-Host "[WARN] D:\Shares\SynologyDrive not found" -ForegroundColor Yellow
}
# --- GPO Export ---
Write-Host "`n--- Exporting GPO state ---" -ForegroundColor Yellow
try {
New-Item -Path "$BackupRoot\GPO" -ItemType Directory -Force | Out-Null
Get-GPO -All | ForEach-Object {
$_ | Get-GPOReport -ReportType XML -Path "$BackupRoot\GPO\$($_.DisplayName)_$Timestamp.xml"
}
Get-GPO -All | Select-Object DisplayName, Id, GpoStatus, CreationTime, ModificationTime |
Export-Csv "$BackupRoot\GPO\GPO-List_$Timestamp.csv" -NoTypeInformation
Write-Host "[OK] GPO reports exported" -ForegroundColor Green
}
catch {
Write-Host "[WARN] GPO export failed: $_" -ForegroundColor Yellow
}
# --- Summary ---
Write-Host "`n=== Export Complete ===" -ForegroundColor Cyan
Write-Host "All backups saved to: $BackupRoot" -ForegroundColor Green
Write-Host ""
Write-Host "Next steps:" -ForegroundColor Yellow
Write-Host " 1. Download pfSense config XML manually (Diagnostics > Backup & Restore)"
Write-Host " 2. Save it to $BackupRoot\pfSense\"
Write-Host " 3. Review SynologyDrive audit output"
Write-Host " 4. Proceed to Phase 1 (Network Foundation)"