sync: Auto-sync from ACG-M-L5090 at 2026-03-10 19:11:00
Synced files: - Quote wizard frontend (all components, hooks, types, config) - API updates (config, models, routers, schemas, services) - Client work (bg-builders, gurushow) - Scripts (BGB Lesley termination, CIPP, Datto, migration) - Temp files (Bardach contacts, VWP investigation, misc) - Credentials and session logs - Email service, PHP API, session logs Machine: ACG-M-L5090 Timestamp: 2026-03-10 19:11:00 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
193
scripts/bgb-lesley-recover-review.ps1
Normal file
193
scripts/bgb-lesley-recover-review.ps1
Normal file
@@ -0,0 +1,193 @@
|
||||
#Requires -Modules ExchangeOnlineManagement
|
||||
<#
|
||||
.SYNOPSIS
|
||||
BG Builders - Lesley Roth: Recover deleted items (last 10 days) and review inbox rules
|
||||
.DESCRIPTION
|
||||
1. Connects to Exchange Online as sysadmin@bgbuildersllc.com
|
||||
2. Recovers all soft-deleted items from Lesley's mailbox (last 10 days)
|
||||
3. Lists all inbox rules on the account
|
||||
.NOTES
|
||||
Run in PowerShell 7 (pwsh) for best compatibility
|
||||
Tenant: bgbuildersllc.com / sonorangreenllc.onmicrosoft.com
|
||||
Target: lesley@bgbuildersllc.com
|
||||
#>
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$targetUser = 'lesley@bgbuildersllc.com'
|
||||
|
||||
# ── Connect to Exchange Online ──────────────────────────────────────
|
||||
Write-Host "`n=== Connecting to Exchange Online ===" -ForegroundColor Cyan
|
||||
try {
|
||||
$session = Get-ConnectionInformation -ErrorAction SilentlyContinue
|
||||
if (-not $session -or $session.State -ne 'Connected') {
|
||||
Connect-ExchangeOnline -UserPrincipalName sysadmin@bgbuildersllc.com -ShowBanner:$false
|
||||
} else {
|
||||
Write-Host "Already connected to Exchange Online" -ForegroundColor Green
|
||||
}
|
||||
} catch {
|
||||
Write-Host "Connecting fresh..." -ForegroundColor Yellow
|
||||
Connect-ExchangeOnline -UserPrincipalName sysadmin@bgbuildersllc.com -ShowBanner:$false
|
||||
}
|
||||
|
||||
# ── Part 1: Review Inbox Rules ──────────────────────────────────────
|
||||
Write-Host "`n=== INBOX RULES for $targetUser ===" -ForegroundColor Cyan
|
||||
|
||||
try {
|
||||
$rules = Get-InboxRule -Mailbox $targetUser -IncludeHidden
|
||||
if ($rules) {
|
||||
Write-Host "`nFound $($rules.Count) rule(s):" -ForegroundColor Yellow
|
||||
foreach ($rule in $rules) {
|
||||
Write-Host "`n--- Rule: $($rule.Name) ---" -ForegroundColor White
|
||||
Write-Host " Enabled: $($rule.Enabled)"
|
||||
Write-Host " Priority: $($rule.Priority)"
|
||||
Write-Host " Description: $($rule.Description)"
|
||||
|
||||
if ($rule.ForwardTo) {
|
||||
Write-Host " ** FORWARD TO: $($rule.ForwardTo)" -ForegroundColor Red
|
||||
}
|
||||
if ($rule.ForwardAsAttachmentTo) {
|
||||
Write-Host " ** FWD ATTACH: $($rule.ForwardAsAttachmentTo)" -ForegroundColor Red
|
||||
}
|
||||
if ($rule.RedirectTo) {
|
||||
Write-Host " ** REDIRECT TO: $($rule.RedirectTo)" -ForegroundColor Red
|
||||
}
|
||||
if ($rule.DeleteMessage) {
|
||||
Write-Host " ** DELETE MSG: True" -ForegroundColor Red
|
||||
}
|
||||
if ($rule.MoveToFolder) {
|
||||
Write-Host " Move To: $($rule.MoveToFolder)"
|
||||
}
|
||||
if ($rule.From) {
|
||||
Write-Host " From: $($rule.From)"
|
||||
}
|
||||
if ($rule.SubjectContainsWords) {
|
||||
Write-Host " Subject Words: $($rule.SubjectContainsWords -join ', ')"
|
||||
}
|
||||
if ($rule.BodyContainsWords) {
|
||||
Write-Host " Body Words: $($rule.BodyContainsWords -join ', ')"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Host "No inbox rules found." -ForegroundColor Green
|
||||
}
|
||||
} catch {
|
||||
Write-Host "Error getting inbox rules: $_" -ForegroundColor Red
|
||||
}
|
||||
|
||||
# ── Check forwarding configuration ──────────────────────────────────
|
||||
Write-Host "`n=== FORWARDING CONFIG for $targetUser ===" -ForegroundColor Cyan
|
||||
|
||||
try {
|
||||
$mbx = Get-Mailbox -Identity $targetUser
|
||||
if ($mbx.ForwardingAddress) {
|
||||
Write-Host " ForwardingAddress: $($mbx.ForwardingAddress)" -ForegroundColor Red
|
||||
} else {
|
||||
Write-Host " ForwardingAddress: (none)" -ForegroundColor Green
|
||||
}
|
||||
if ($mbx.ForwardingSmtpAddress) {
|
||||
Write-Host " ForwardingSmtpAddress: $($mbx.ForwardingSmtpAddress)" -ForegroundColor Red
|
||||
} else {
|
||||
Write-Host " ForwardingSmtpAddress: (none)" -ForegroundColor Green
|
||||
}
|
||||
Write-Host " DeliverToMailboxAndForward: $($mbx.DeliverToMailboxAndForward)"
|
||||
} catch {
|
||||
Write-Host "Error getting forwarding config: $_" -ForegroundColor Red
|
||||
}
|
||||
|
||||
# ── Part 2: Recover Deleted Items (last 10 days) ───────────────────
|
||||
Write-Host "`n=== RECOVERING DELETED ITEMS (last 10 days) ===" -ForegroundColor Cyan
|
||||
Write-Host "Target: $targetUser" -ForegroundColor White
|
||||
|
||||
$startDate = (Get-Date).AddDays(-10)
|
||||
$endDate = Get-Date
|
||||
$dateRange = "$($startDate.ToString('yyyy-MM-dd'))..$($endDate.ToString('yyyy-MM-dd'))"
|
||||
|
||||
# Step 1: Try Get-RecoverableItems (requires Mailbox Import Export role)
|
||||
Write-Host "`n--- Method 1: Get-RecoverableItems ---" -ForegroundColor White
|
||||
try {
|
||||
Write-Host "Scanning recoverable items from $dateRange..."
|
||||
$preview = Get-RecoverableItems -Identity $targetUser -FilterStartTime $startDate -FilterEndTime $endDate -FilterItemType All
|
||||
|
||||
if ($preview) {
|
||||
Write-Host "Found $($preview.Count) recoverable item(s):" -ForegroundColor Yellow
|
||||
$preview | Group-Object ItemClass | ForEach-Object { Write-Host " $($_.Name): $($_.Count) items" }
|
||||
$preview | Select-Object -First 20 | ForEach-Object {
|
||||
$subj = if ($_.Subject) { $_.Subject } else { "(no subject)" }
|
||||
Write-Host " [$($_.LastModifiedTime.ToString('MM/dd HH:mm'))] $subj"
|
||||
}
|
||||
Write-Host "`nRestoring all $($preview.Count) items..." -ForegroundColor Yellow
|
||||
Restore-RecoverableItems -Identity $targetUser -FilterStartTime $startDate -FilterEndTime $endDate -FilterItemType All -Confirm:$false
|
||||
Write-Host "Recovery complete!" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "No recoverable items found." -ForegroundColor Green
|
||||
}
|
||||
} catch {
|
||||
Write-Host "Get-RecoverableItems not available (needs Mailbox Import Export role)." -ForegroundColor Yellow
|
||||
Write-Host "Falling back to Compliance Search..." -ForegroundColor Yellow
|
||||
|
||||
# Step 2: Connect to Security & Compliance and run a content search
|
||||
Write-Host "`n--- Method 2: Compliance Search (eDiscovery) ---" -ForegroundColor White
|
||||
try {
|
||||
Connect-IPPSSession -UserPrincipalName sysadmin@bgbuildersllc.com -ShowBanner:$false
|
||||
Write-Host "Connected to Security & Compliance Center." -ForegroundColor Green
|
||||
|
||||
$searchName = "LesleyRecovery_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
|
||||
$kql = "received>=$($startDate.ToString('yyyy-MM-dd')) AND received<=$($endDate.ToString('yyyy-MM-dd'))"
|
||||
|
||||
Write-Host "Creating compliance search: $searchName"
|
||||
Write-Host " KQL: $kql"
|
||||
Write-Host " Mailbox: $targetUser"
|
||||
|
||||
New-ComplianceSearch -Name $searchName `
|
||||
-ExchangeLocation $targetUser `
|
||||
-ContentMatchQuery $kql `
|
||||
-Description "Recover deleted items for Lesley Roth - last 10 days" |
|
||||
Out-Null
|
||||
|
||||
Write-Host "Starting search..." -ForegroundColor Yellow
|
||||
Start-ComplianceSearch -Identity $searchName
|
||||
|
||||
# Poll for completion (max 5 minutes)
|
||||
$maxWait = 300
|
||||
$elapsed = 0
|
||||
do {
|
||||
Start-Sleep -Seconds 10
|
||||
$elapsed += 10
|
||||
$status = (Get-ComplianceSearch -Identity $searchName).Status
|
||||
Write-Host " Status: $status ($elapsed sec)"
|
||||
} while ($status -ne 'Completed' -and $elapsed -lt $maxWait)
|
||||
|
||||
$result = Get-ComplianceSearch -Identity $searchName
|
||||
Write-Host "`nSearch Results:" -ForegroundColor Cyan
|
||||
Write-Host " Status: $($result.Status)"
|
||||
Write-Host " Items Found: $($result.Items)"
|
||||
Write-Host " Size: $($result.Size)"
|
||||
Write-Host " Success Results: $($result.SuccessResults)"
|
||||
|
||||
if ($result.Items -gt 0) {
|
||||
Write-Host "`nItems found! To restore them:" -ForegroundColor Yellow
|
||||
Write-Host " Option A: Use the Microsoft Purview portal > Content Search > '$searchName' > Export/Restore"
|
||||
Write-Host " Option B: Run New-ComplianceSearchAction -SearchName '$searchName' -Purge -PurgeType SoftDelete"
|
||||
Write-Host " (This moves items - for restore, use the Purview portal export instead)"
|
||||
Write-Host "`n Purview URL: https://compliance.microsoft.com/contentsearchv2" -ForegroundColor Cyan
|
||||
} else {
|
||||
Write-Host "`nNo deleted items found in date range." -ForegroundColor Green
|
||||
Write-Host "(Litigation hold preserves items in-place - they may still be in the mailbox)"
|
||||
}
|
||||
} catch {
|
||||
Write-Host "Compliance search also failed: $_" -ForegroundColor Red
|
||||
Write-Host "`nManual recovery options:" -ForegroundColor Yellow
|
||||
Write-Host " 1. Outlook > Deleted Items > 'Recover items recently removed from this folder'"
|
||||
Write-Host " (Log in as Barry/Shelly who have FullAccess)"
|
||||
Write-Host " 2. CIPP > Mailbox Restore"
|
||||
Write-Host " 3. Microsoft Purview portal > eDiscovery > Content Search"
|
||||
Write-Host " URL: https://compliance.microsoft.com/contentsearchv2"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "`n=== DONE ===" -ForegroundColor Cyan
|
||||
Write-Host "Summary:"
|
||||
Write-Host " - Inbox rules reviewed"
|
||||
Write-Host " - Forwarding config checked"
|
||||
Write-Host " - Deleted item recovery attempted"
|
||||
Write-Host ""
|
||||
Reference in New Issue
Block a user