<#
.SYNOPSIS
Creates write-only audit drop share with service account and scheduled archive.

.DESCRIPTION
Provisions on CS-SERVER:
  - AD service account svc-audit-upload (no interactive logon)
  - AD group AuditUploaders (members get write-only access)
  - D:\Shares\AuditDrop folder with NTFS write-only ACL
  - Hidden SMB share \\CS-SERVER\AuditDrop$ (Change for AuditUploaders, Full for Domain Admins)
  - Daily 3am scheduled task that moves yesterday's drops into D:\Shares\AuditDrop_Archive\YYYY-MM-DD\

Idempotent — safe to re-run.

.NOTES
Run as Domain Admin on CS-SERVER (or any system with AD tools + SMB management installed).
Verify the OUs in $svcOuPath and $groupOuPath exist before running, or change them.
#>

# === VARIABLES ===
$domainDN     = "DC=cascades,DC=local"
$svcOuPath    = "OU=ServiceAccounts,$domainDN"
$groupOuPath  = "OU=Groups,$domainDN"
$svcUser      = "svc-audit-upload"
$group        = "AuditUploaders"
$drop         = "D:\Shares\AuditDrop"
$archiveRoot  = "D:\Shares\AuditDrop_Archive"
$scriptPath   = "D:\Shares\Scripts\Archive-AuditDrop.ps1"

# === 0. Pre-flight: confirm target OUs exist ===
foreach ($ou in @($svcOuPath, $groupOuPath)) {
    try {
        Get-ADOrganizationalUnit -Identity $ou -ErrorAction Stop | Out-Null
        Write-Host "[OK] OU exists: $ou"
    } catch {
        Write-Host "[ERROR] OU not found: $ou" -ForegroundColor Red
        Write-Host "        Create it first, or edit `$svcOuPath / `$groupOuPath in this script." -ForegroundColor Yellow
        Write-Host "        Example: New-ADOrganizationalUnit -Name 'ServiceAccounts' -Path '$domainDN' -ProtectedFromAccidentalDeletion `$true" -ForegroundColor Yellow
        exit 1
    }
}

# === 1. Create the dedicated upload service account ===
$svcPwd = Read-Host -AsSecureString -Prompt "Enter password for $svcUser (store in 1Password / SOPS vault)"

if (-not (Get-ADUser -Filter "SamAccountName -eq '$svcUser'" -ErrorAction SilentlyContinue)) {
    New-ADUser `
        -Name $svcUser `
        -SamAccountName $svcUser `
        -DisplayName "Service: Audit JSON Upload" `
        -Description "Write-only access to \\CS-SERVER\AuditDrop$. Used by Syncro audit upload script. Do not use interactively." `
        -Path $svcOuPath `
        -AccountPassword $svcPwd `
        -PasswordNeverExpires $true `
        -CannotChangePassword $true `
        -Enabled $true
    Write-Host "[OK] Created service account: $svcUser"
} else {
    Write-Host "[OK] Service account already exists: $svcUser"
}

# === 2. Create the AD group ===
if (-not (Get-ADGroup -Filter "SamAccountName -eq '$group'" -ErrorAction SilentlyContinue)) {
    New-ADGroup `
        -Name $group `
        -SamAccountName $group `
        -GroupScope Global `
        -GroupCategory Security `
        -Path $groupOuPath `
        -Description "Members can WRITE-ONLY to \\CS-SERVER\AuditDrop$. No read/list."
    Write-Host "[OK] Created group: $group"
} else {
    Write-Host "[OK] Group already exists: $group"
}

# Add service account to group (idempotent)
Add-ADGroupMember -Identity $group -Members $svcUser -ErrorAction SilentlyContinue
Write-Host "[OK] Membership confirmed: $svcUser in $group"

# === 3. Create the drop folder ===
New-Item -Path $drop -ItemType Directory -Force | Out-Null
Write-Host "[OK] Drop folder ready: $drop"

# === 4. NTFS write-only permissions ===
icacls $drop /inheritance:r | Out-Null
icacls $drop /grant:r "CASCADES\Domain Admins:(OI)(CI)F" | Out-Null
icacls $drop /grant:r "SYSTEM:(OI)(CI)F" | Out-Null
icacls $drop /grant:r "CASCADES\${group}:(WD,AD,WA,WEA,RA,REA,RC,S,X)" | Out-Null

Write-Host "[OK] NTFS permissions applied. Listing:"
icacls $drop

# === 5. Create the hidden SMB share ===
if (-not (Get-SmbShare -Name "AuditDrop$" -ErrorAction SilentlyContinue)) {
    New-SmbShare `
        -Name "AuditDrop$" `
        -Path $drop `
        -FullAccess "CASCADES\Domain Admins" `
        -ChangeAccess "CASCADES\${group}" `
        -Description "Audit JSON drop-box. Hidden. Write-only for AuditUploaders group."
    Write-Host "[OK] Created SMB share: AuditDrop$"
} else {
    Write-Host "[OK] SMB share already exists: AuditDrop$"
}

Write-Host "[OK] Share access:"
Get-SmbShareAccess -Name "AuditDrop$"

# === 6. Generate the archive script ===
# IMPORTANT: backtick-escape any $ that must remain literal in the GENERATED file.
#   - $drop and $archiveRoot expand NOW (they're fixed paths set above)
#   - $src, $archive, $_, $(Get-Date ...) must be backtick-escaped so they expand at TASK RUN TIME
$archiveScript = @"
`$src = "$drop"
`$archive = "$archiveRoot\`$(Get-Date -Format yyyy-MM-dd)"
New-Item -Path `$archive -ItemType Directory -Force | Out-Null
Get-ChildItem -Path `$src -File | Where-Object { `$_.LastWriteTime -lt (Get-Date).AddHours(-2) } |
    Move-Item -Destination `$archive -Force
"@

New-Item -ItemType Directory -Path (Split-Path $scriptPath) -Force | Out-Null
$archiveScript | Out-File $scriptPath -Encoding UTF8 -Force
Write-Host "[OK] Archive script written: $scriptPath"
Write-Host "     Contents:"
Get-Content $scriptPath | ForEach-Object { Write-Host "       $_" }

# === 7. Create scheduled task (daily 3am) ===
$action  = New-ScheduledTaskAction -Execute "powershell.exe" `
    -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`""
$trigger = New-ScheduledTaskTrigger -Daily -At 3am

if (-not (Get-ScheduledTask -TaskName "Archive-AuditDrop" -ErrorAction SilentlyContinue)) {
    Register-ScheduledTask `
        -TaskName "Archive-AuditDrop" `
        -Action $action `
        -Trigger $trigger `
        -RunLevel Highest `
        -User "SYSTEM"
    Write-Host "[OK] Scheduled task created: Archive-AuditDrop (daily 3am)"
} else {
    Write-Host "[OK] Scheduled task already exists: Archive-AuditDrop"
}

# === 8. Test instructions ===
Write-Host ""
Write-Host "=== TEST FROM A WORKSTATION ===" -ForegroundColor Cyan
Write-Host "Run these manually to verify write-only behavior:"
Write-Host ""
Write-Host "  `$cred = Get-Credential cascades\$svcUser"
Write-Host "  New-PSDrive -Name T -PSProvider FileSystem -Root '\\CS-SERVER\AuditDrop$' -Credential `$cred"
Write-Host "  'hello' | Out-File T:\test_`$(hostname).txt    # SHOULD SUCCEED"
Write-Host "  Get-ChildItem T:\                              # SHOULD FAIL (Access Denied)"
Write-Host "  Get-Content T:\test_`$(hostname).txt           # SHOULD FAIL (Access Denied)"
Write-Host "  Remove-PSDrive T"
Write-Host ""
Write-Host "If all three SHOULD-FAIL lines actually return Access Denied, the drop-box is correctly write-only." -ForegroundColor Green
