Add AD scripts and stage import instructions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
sysadmin
2026-04-03 09:48:59 -07:00
parent 88dc431cfa
commit aed04e8ca4
7 changed files with 726 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
# Stage TXT Import Task
# Date: 2026-03-28
# Context: CTONWTXT.BAT now uploads C:\STAGE\*.TXT from DOS machines to T:\STAGE\%MACHINE%\
## What happened
1. CTONWTXT.BAT was never being called -- fixed, now called from CTONW.BAT on every boot
2. Destination changed from broken X: (Novell serve.sys check) to T:\STAGE\%MACHINE%\
3. DOS 6.22 can't MD on existing dirs without error, so dirs are pre-created on NAS
4. All TS-* machine folders pre-created under /data/test/STAGE/ on D2TESTNAS
## What needs to run
Save the script below as C:\Shares\testdatadb\import-all-stage.js and run it:
cd C:\Shares\testdatadb
node import-all-stage.js
## What it does
- Scans \\D2TESTNAS\test\STAGE\TS-*\*.TXT (~8,100 files across 10 machines)
- Parses each TXT datasheet (Date, Model, SN)
- Decodes hex-prefix serial numbers for 8.3 filename encoding:
- Letter prefix = hex digit: A=10, B=11, C=12, ..., H=17, etc.
- Example: H8236-12.TXT has SN: 178236-12 inside the file
- Example: A819-1.TXT has SN: A819-1 inside -> decoded to 10819-1
- The SN line inside H-prefix files already has the full numeric serial
- The SN line inside A-prefix files still has the encoded serial
- Cross-references against testdata.db by (serial_number, model_number)
- Inserts MISSING records as log_type='SHT' with test_station from folder name
- Copies ALL files to X:\For_Web\{decoded_serial}.TXT (the web share)
## Machines with data
TS-4L: 3,082 files (largest)
TS-4R: 2,741 files
TS-1R: 509 files
TS-8R: 478 files
TS-3R: 435 files
TS-11R: 325 files
TS-8L: 285 files
TS-11L: 248 files
TS-27: 10 files (already imported this session)
TS-1L: 1 file
## Serial number encoding (8.3 filename scheme)
The QuickBASIC ATE software encodes long serial numbers to fit DOS 8.3 filenames.
The first two digits get replaced with a hex letter if the serial is too long:
178236-12 -> H8236-12.TXT (17 -> H, which is char code 72, 72-55=17)
10819-1 -> A819-1.TXT (10 -> A, which is char code 65, 65-55=10)
Decode: letter.charCodeAt(0) - 55 = numeric prefix
Only applies if filename starts with [A-Z] followed by digits.
## TS-27 already done
10 files from TS-27 were already imported earlier this session into the DB as SHT records.
The import script uses INSERT OR REPLACE so re-running is safe.
## Previous CTONWTXT.BAT issues (resolved)
- v1.0: Never called, checked for Novell serve.sys, used X: drive parameter
- v2.0: Called from CTONW, but used mixed-case "Stage" path -> failed on DOS
- v2.1: All uppercase STAGE, but had MD commands that fail on existing dirs
- v2.2: Same issue
- v2.3: Removed MD entirely, dirs pre-created on NAS. CURRENT VERSION.

View File

@@ -0,0 +1,88 @@
<#
.SYNOPSIS
Configures PowerShell transcript logging for remote sessions.
.DESCRIPTION
Enables comprehensive transcript logging via registry settings,
creates the logging directory with proper permissions, and sets up
automatic log rotation.
.NOTES
Author: ClaudeTools Automation
Version: 1.0
Run as Administrator
#>
$ErrorActionPreference = 'Stop'
$transcriptPath = "C:\ClaudeTools\Logs\Transcripts"
Write-Host "Configuring PowerShell Transcript Logging..." -ForegroundColor Cyan
# Create transcript directory
if (-not (Test-Path $transcriptPath)) {
New-Item -ItemType Directory -Path $transcriptPath -Force | Out-Null
Write-Host "Created transcript directory: $transcriptPath" -ForegroundColor Green
}
# Set permissions on transcript directory
# Administrators: Full Control, SYSTEM: Full Control, Remote Management Users: Read/Write
$acl = Get-Acl $transcriptPath
$acl.SetAccessRuleProtection($true, $false) # Disable inheritance
# Add Administrators - Full Control
$adminRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
"Administrators", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"
)
$acl.AddAccessRule($adminRule)
# Add SYSTEM - Full Control
$systemRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
"SYSTEM", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"
)
$acl.AddAccessRule($systemRule)
# Add Remote Management Users - Modify (so they can write transcripts)
$rmRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
"Remote Management Users", "Modify", "ContainerInherit,ObjectInherit", "None", "Allow"
)
$acl.AddAccessRule($rmRule)
Set-Acl $transcriptPath $acl
Write-Host "Set permissions on transcript directory" -ForegroundColor Green
# Configure PowerShell transcript logging via registry
$psPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription"
if (-not (Test-Path $psPath)) {
New-Item -Path $psPath -Force | Out-Null
}
# Enable transcription
Set-ItemProperty -Path $psPath -Name "EnableTranscripting" -Value 1 -Type DWord
Set-ItemProperty -Path $psPath -Name "EnableInvocationHeader" -Value 1 -Type DWord
Set-ItemProperty -Path $psPath -Name "OutputDirectory" -Value $transcriptPath -Type String
Write-Host "Enabled PowerShell transcription via registry" -ForegroundColor Green
# Also enable module logging for additional audit trail
$modulePath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging"
if (-not (Test-Path $modulePath)) {
New-Item -Path $modulePath -Force | Out-Null
}
Set-ItemProperty -Path $modulePath -Name "EnableModuleLogging" -Value 1 -Type DWord
# Enable script block logging
$scriptPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging"
if (-not (Test-Path $scriptPath)) {
New-Item -Path $scriptPath -Force | Out-Null
}
Set-ItemProperty -Path $scriptPath -Name "EnableScriptBlockLogging" -Value 1 -Type DWord
Write-Host "Enabled module and script block logging" -ForegroundColor Green
Write-Host "`nTranscript logging configuration complete!" -ForegroundColor Green
Write-Host "Transcripts will be saved to: $transcriptPath"
# Display current settings
Write-Host "`n--- Current Settings ---" -ForegroundColor Yellow
Get-ItemProperty -Path $psPath | Select-Object EnableTranscripting, EnableInvocationHeader, OutputDirectory

View File

@@ -0,0 +1,87 @@
<#
.SYNOPSIS
Generates a report of all Active Directory computers.
.DESCRIPTION
This script queries Active Directory for all computer accounts and exports
key properties including name, operating system, last logon, and OU location.
.PARAMETER OutputPath
Optional. Path to export CSV report. If not specified, outputs to console.
.PARAMETER OperatingSystem
Optional. Filter by operating system (e.g., "Windows Server*", "*Windows 10*").
.EXAMPLE
.\Get-ADComputerReport.ps1
Lists all computers to console.
.EXAMPLE
.\Get-ADComputerReport.ps1 -OperatingSystem "Windows Server*" -OutputPath "C:\ClaudeTools\Logs\servers.csv"
Exports all Windows Server computers to CSV.
.NOTES
Author: ClaudeTools Automation
Version: 1.0
Requires: ActiveDirectory PowerShell module
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$false)]
[string]$OutputPath,
[Parameter(Mandatory=$false)]
[string]$OperatingSystem = "*"
)
# Import AD module
Import-Module ActiveDirectory -ErrorAction Stop
Write-Host "Querying Active Directory computers..." -ForegroundColor Cyan
# Get computers with properties
$computers = Get-ADComputer -Filter "OperatingSystem -like '$OperatingSystem'" -Properties `
OperatingSystem,
OperatingSystemVersion,
LastLogonDate,
Created,
Enabled,
IPv4Address,
Description,
DistinguishedName |
Select-Object `
@{N='Name';E={$_.Name}},
@{N='OperatingSystem';E={$_.OperatingSystem}},
@{N='OSVersion';E={$_.OperatingSystemVersion}},
@{N='Enabled';E={$_.Enabled}},
@{N='IPv4Address';E={$_.IPv4Address}},
@{N='LastLogon';E={$_.LastLogonDate}},
@{N='Created';E={$_.Created}},
@{N='OU';E={($_.DistinguishedName -split ',',2)[1]}},
@{N='Description';E={$_.Description}}
$computerCount = ($computers | Measure-Object).Count
Write-Host "Found $computerCount computers." -ForegroundColor Green
if ($OutputPath) {
$computers | Export-Csv -Path $OutputPath -NoTypeInformation
Write-Host "Report exported to: $OutputPath" -ForegroundColor Green
} else {
$computers | Format-Table -AutoSize
}
# Summary by OS
Write-Host "`n--- Operating System Summary ---" -ForegroundColor Yellow
$computers | Group-Object OperatingSystem | Sort-Object Count -Descending |
Format-Table @{N='Operating System';E={$_.Name}}, Count -AutoSize
# Summary by status
$enabledCount = ($computers | Where-Object { $_.Enabled -eq $true } | Measure-Object).Count
$disabledCount = ($computers | Where-Object { $_.Enabled -eq $false } | Measure-Object).Count
Write-Host "Enabled: $enabledCount | Disabled: $disabledCount"
# Stale computers (no logon in 90 days)
$staleDate = (Get-Date).AddDays(-90)
$staleCount = ($computers | Where-Object { $_.LastLogon -lt $staleDate -or $null -eq $_.LastLogon } | Measure-Object).Count
Write-Host "Stale (no logon 90+ days): $staleCount" -ForegroundColor $(if ($staleCount -gt 0) { 'Yellow' } else { 'Green' })

View File

@@ -0,0 +1,92 @@
<#
.SYNOPSIS
Generates a report of all Active Directory users with key properties.
.DESCRIPTION
This script queries Active Directory for all user accounts and exports
key properties including name, email, last logon, account status, and group memberships.
.PARAMETER OutputPath
Optional. Path to export CSV report. If not specified, outputs to console.
.PARAMETER IncludeDisabled
Switch to include disabled accounts in the report.
.EXAMPLE
.\Get-ADUserReport.ps1
Lists all enabled users to console.
.EXAMPLE
.\Get-ADUserReport.ps1 -OutputPath "C:\ClaudeTools\Logs\users.csv" -IncludeDisabled
Exports all users (including disabled) to CSV file.
.NOTES
Author: ClaudeTools Automation
Version: 1.0
Requires: ActiveDirectory PowerShell module
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$false)]
[string]$OutputPath,
[Parameter(Mandatory=$false)]
[switch]$IncludeDisabled
)
# Import AD module
Import-Module ActiveDirectory -ErrorAction Stop
Write-Host "Querying Active Directory users..." -ForegroundColor Cyan
# Build filter
$filter = if ($IncludeDisabled) { "*" } else { "Enabled -eq 'True'" }
# Get users with properties
$users = Get-ADUser -Filter $filter -Properties `
DisplayName,
EmailAddress,
Department,
Title,
Manager,
LastLogonDate,
PasswordLastSet,
PasswordNeverExpires,
Enabled,
Created,
MemberOf,
Description |
Select-Object `
@{N='SamAccountName';E={$_.SamAccountName}},
@{N='DisplayName';E={$_.DisplayName}},
@{N='Email';E={$_.EmailAddress}},
@{N='Department';E={$_.Department}},
@{N='Title';E={$_.Title}},
@{N='Enabled';E={$_.Enabled}},
@{N='LastLogon';E={$_.LastLogonDate}},
@{N='PasswordLastSet';E={$_.PasswordLastSet}},
@{N='PasswordNeverExpires';E={$_.PasswordNeverExpires}},
@{N='Created';E={$_.Created}},
@{N='GroupCount';E={($_.MemberOf | Measure-Object).Count}},
@{N='Description';E={$_.Description}}
$userCount = ($users | Measure-Object).Count
Write-Host "Found $userCount users." -ForegroundColor Green
if ($OutputPath) {
$users | Export-Csv -Path $OutputPath -NoTypeInformation
Write-Host "Report exported to: $OutputPath" -ForegroundColor Green
} else {
$users | Format-Table -AutoSize
}
# Summary statistics
Write-Host "`n--- Summary ---" -ForegroundColor Yellow
Write-Host "Total Users: $userCount"
$enabledCount = ($users | Where-Object { $_.Enabled -eq $true } | Measure-Object).Count
$disabledCount = ($users | Where-Object { $_.Enabled -eq $false } | Measure-Object).Count
Write-Host "Enabled: $enabledCount"
Write-Host "Disabled: $disabledCount"
$neverExpire = ($users | Where-Object { $_.PasswordNeverExpires -eq $true } | Measure-Object).Count
Write-Host "Password Never Expires: $neverExpire"

111
scripts/Get-GPOStatus.ps1 Normal file
View File

@@ -0,0 +1,111 @@
<#
.SYNOPSIS
Reports on Group Policy Object status and replication.
.DESCRIPTION
This script checks all GPOs in the domain and reports their status,
including version information, links, and replication status between
AD and SYSVOL.
.PARAMETER OutputPath
Optional. Path to export CSV report. If not specified, outputs to console.
.PARAMETER CheckReplication
Switch to perform detailed replication check between AD and SYSVOL.
.EXAMPLE
.\Get-GPOStatus.ps1
Lists all GPOs with basic status.
.EXAMPLE
.\Get-GPOStatus.ps1 -CheckReplication -OutputPath "C:\ClaudeTools\Logs\gpo-status.csv"
Full replication check with CSV export.
.NOTES
Author: ClaudeTools Automation
Version: 1.0
Requires: GroupPolicy PowerShell module
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$false)]
[string]$OutputPath,
[Parameter(Mandatory=$false)]
[switch]$CheckReplication
)
# Import required modules
Import-Module GroupPolicy -ErrorAction Stop
Import-Module ActiveDirectory -ErrorAction Stop
Write-Host "Querying Group Policy Objects..." -ForegroundColor Cyan
# Get all GPOs
$gpos = Get-GPO -All | Select-Object `
@{N='Name';E={$_.DisplayName}},
@{N='ID';E={$_.Id}},
@{N='Status';E={$_.GpoStatus}},
@{N='CreationTime';E={$_.CreationTime}},
@{N='ModificationTime';E={$_.ModificationTime}},
@{N='UserVersion';E={$_.User.DSVersion}},
@{N='ComputerVersion';E={$_.Computer.DSVersion}},
@{N='WMIFilter';E={$_.WmiFilter.Name}}
$gpoCount = ($gpos | Measure-Object).Count
Write-Host "Found $gpoCount GPOs." -ForegroundColor Green
# Check GPO links
Write-Host "`nChecking GPO links..." -ForegroundColor Cyan
$gpoLinks = @()
foreach ($gpo in (Get-GPO -All)) {
$report = [xml](Get-GPOReport -Guid $gpo.Id -ReportType Xml)
$links = $report.GPO.LinksTo.SOMPath
$gpoLinks += [PSCustomObject]@{
Name = $gpo.DisplayName
LinkCount = if ($links) { ($links | Measure-Object).Count } else { 0 }
Links = if ($links) { $links -join "; " } else { "Not Linked" }
}
}
if ($CheckReplication) {
Write-Host "`nChecking SYSVOL replication status..." -ForegroundColor Cyan
$domain = (Get-ADDomain).DNSRoot
$dcs = Get-ADDomainController -Filter *
foreach ($dc in $dcs) {
Write-Host " Checking $($dc.HostName)..." -ForegroundColor Gray
$sysvolPath = "\\$($dc.HostName)\SYSVOL\$domain\Policies"
if (Test-Path $sysvolPath) {
$sysvolGPOs = Get-ChildItem $sysvolPath -Directory | Where-Object { $_.Name -match '^{' }
Write-Host " SYSVOL GPO count: $($sysvolGPOs.Count)" -ForegroundColor Green
} else {
Write-Host " Unable to access SYSVOL" -ForegroundColor Red
}
}
}
# Output results
if ($OutputPath) {
$gpos | Export-Csv -Path $OutputPath -NoTypeInformation
Write-Host "`nReport exported to: $OutputPath" -ForegroundColor Green
} else {
Write-Host "`n--- GPO List ---" -ForegroundColor Yellow
$gpos | Format-Table Name, Status, ModificationTime, UserVersion, ComputerVersion -AutoSize
Write-Host "`n--- GPO Links ---" -ForegroundColor Yellow
$gpoLinks | Format-Table Name, LinkCount, Links -AutoSize
}
# Summary
Write-Host "`n--- Summary ---" -ForegroundColor Yellow
Write-Host "Total GPOs: $gpoCount"
$unlinked = ($gpoLinks | Where-Object { $_.LinkCount -eq 0 } | Measure-Object).Count
Write-Host "Unlinked GPOs: $unlinked" -ForegroundColor $(if ($unlinked -gt 0) { 'Yellow' } else { 'Green' })
$disabled = ($gpos | Where-Object { $_.Status -ne 'AllSettingsEnabled' } | Measure-Object).Count
Write-Host "Disabled/Partial GPOs: $disabled" -ForegroundColor $(if ($disabled -gt 0) { 'Yellow' } else { 'Green' })

View File

@@ -0,0 +1,173 @@
<#
.SYNOPSIS
Checks Active Directory replication health across domain controllers.
.DESCRIPTION
This script performs comprehensive AD replication health checks including
replication status, partner connectivity, and identifies any replication failures.
.PARAMETER OutputPath
Optional. Path to export results. If not specified, outputs to console.
.PARAMETER Detailed
Switch to show detailed replication information per DC.
.EXAMPLE
.\Get-ReplicationHealth.ps1
Basic replication health check.
.EXAMPLE
.\Get-ReplicationHealth.ps1 -Detailed -OutputPath "C:\ClaudeTools\Logs\repl-health.txt"
Detailed check with output to file.
.NOTES
Author: ClaudeTools Automation
Version: 1.0
Requires: ActiveDirectory PowerShell module, repadmin.exe
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$false)]
[string]$OutputPath,
[Parameter(Mandatory=$false)]
[switch]$Detailed
)
# Import AD module
Import-Module ActiveDirectory -ErrorAction Stop
$output = @()
$output += "=" * 60
$output += "AD REPLICATION HEALTH REPORT"
$output += "Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
$output += "=" * 60
Write-Host "Checking AD Replication Health..." -ForegroundColor Cyan
# Get all DCs
$dcs = Get-ADDomainController -Filter *
$output += "`nDomain Controllers Found: $($dcs.Count)"
foreach ($dc in $dcs) {
$output += "`n--- $($dc.HostName) ---"
Write-Host "Checking $($dc.HostName)..." -ForegroundColor Gray
}
# Check replication summary using repadmin
$output += "`n" + "=" * 60
$output += "REPLICATION SUMMARY (repadmin /replsummary)"
$output += "=" * 60
try {
$replSummary = repadmin /replsummary 2>&1
$output += $replSummary
Write-Host "Replication summary retrieved." -ForegroundColor Green
} catch {
$output += "ERROR: Unable to run repadmin /replsummary"
Write-Host "Error running repadmin" -ForegroundColor Red
}
# Check for replication failures
$output += "`n" + "=" * 60
$output += "REPLICATION FAILURES (repadmin /showrepl * /errorsonly)"
$output += "=" * 60
try {
$replErrors = repadmin /showrepl * /errorsonly 2>&1
if ($replErrors -match "error" -or $replErrors -match "fail") {
$output += $replErrors
Write-Host "Replication ERRORS detected!" -ForegroundColor Red
} else {
$output += "No replication errors detected."
Write-Host "No replication errors." -ForegroundColor Green
}
} catch {
$output += "ERROR: Unable to check replication errors"
}
# Queue length
$output += "`n" + "=" * 60
$output += "REPLICATION QUEUE (repadmin /queue)"
$output += "=" * 60
try {
$replQueue = repadmin /queue 2>&1
$output += $replQueue
} catch {
$output += "ERROR: Unable to check replication queue"
}
if ($Detailed) {
$output += "`n" + "=" * 60
$output += "DETAILED REPLICATION STATUS (repadmin /showrepl)"
$output += "=" * 60
try {
$replDetail = repadmin /showrepl 2>&1
$output += $replDetail
} catch {
$output += "ERROR: Unable to get detailed replication status"
}
# DFSR Health (if applicable)
$output += "`n" + "=" * 60
$output += "DFSR SYSVOL REPLICATION STATUS"
$output += "=" * 60
try {
$dfsrStatus = Get-DfsrMember -ErrorAction SilentlyContinue
if ($dfsrStatus) {
$output += "DFSR Members:"
foreach ($member in $dfsrStatus) {
$output += " - $($member.ComputerName): $($member.DomainName)"
}
} else {
$output += "DFSR not configured or FRS in use."
}
} catch {
$output += "Unable to query DFSR status (may be using FRS)"
}
}
# AD Database health
$output += "`n" + "=" * 60
$output += "AD DATABASE INTEGRITY"
$output += "=" * 60
$adDb = Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" -ErrorAction SilentlyContinue
if ($adDb) {
$dbPath = $adDb.'DSA Database file'
$logPath = $adDb.'Database log files path'
$output += "Database Path: $dbPath"
$output += "Log Path: $logPath"
if (Test-Path $dbPath) {
$dbSize = (Get-Item $dbPath).Length / 1MB
$output += "Database Size: $([math]::Round($dbSize, 2)) MB"
}
}
# Final summary
$output += "`n" + "=" * 60
$output += "HEALTH CHECK COMPLETE"
$output += "=" * 60
# Output results
if ($OutputPath) {
$output | Out-File -FilePath $OutputPath -Encoding UTF8
Write-Host "`nReport saved to: $OutputPath" -ForegroundColor Green
} else {
$output | ForEach-Object { Write-Host $_ }
}
# Quick status summary
Write-Host "`n--- Quick Status ---" -ForegroundColor Yellow
Write-Host "Domain Controllers: $($dcs.Count)"
$errorMatch = $replErrors -match "error|fail"
if ($errorMatch) {
Write-Host "Replication Status: ERRORS DETECTED" -ForegroundColor Red
} else {
Write-Host "Replication Status: HEALTHY" -ForegroundColor Green
}

View File

@@ -0,0 +1,107 @@
<#
.SYNOPSIS
Rotates and cleans up old log files.
.DESCRIPTION
Removes transcript and log files older than the specified retention period.
Designed to run as a scheduled task daily.
.PARAMETER RetentionDays
Number of days to retain log files. Default is 30.
.PARAMETER LogPath
Path to the logs directory. Default is C:\ClaudeTools\Logs.
.PARAMETER WhatIf
Shows what would be deleted without actually deleting.
.EXAMPLE
.\Invoke-LogRotation.ps1
Removes logs older than 30 days.
.EXAMPLE
.\Invoke-LogRotation.ps1 -RetentionDays 14 -WhatIf
Shows what would be deleted with 14-day retention.
.NOTES
Author: ClaudeTools Automation
Version: 1.0
#>
[CmdletBinding(SupportsShouldProcess)]
param(
[Parameter(Mandatory=$false)]
[int]$RetentionDays = 30,
[Parameter(Mandatory=$false)]
[string]$LogPath = "C:\ClaudeTools\Logs"
)
$rotationLog = Join-Path $LogPath "rotation.log"
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
function Write-Log {
param([string]$Message)
$logEntry = "[$timestamp] $Message"
Add-Content -Path $rotationLog -Value $logEntry
Write-Host $logEntry
}
Write-Log "=== Log Rotation Started ==="
Write-Log "Retention Period: $RetentionDays days"
Write-Log "Log Path: $LogPath"
$cutoffDate = (Get-Date).AddDays(-$RetentionDays)
$totalDeleted = 0
$totalSizeFreed = 0
# Find and delete old files
$oldFiles = Get-ChildItem -Path $LogPath -Recurse -File |
Where-Object { $_.LastWriteTime -lt $cutoffDate -and $_.Name -ne "rotation.log" }
$fileCount = ($oldFiles | Measure-Object).Count
Write-Log "Found $fileCount files older than $RetentionDays days"
foreach ($file in $oldFiles) {
$fileSize = $file.Length
$filePath = $file.FullName
if ($PSCmdlet.ShouldProcess($filePath, "Delete")) {
try {
Remove-Item $filePath -Force
$totalDeleted++
$totalSizeFreed += $fileSize
Write-Log "Deleted: $filePath ($([math]::Round($fileSize/1KB, 2)) KB)"
} catch {
Write-Log "ERROR deleting $filePath : $_"
}
} else {
Write-Log "WhatIf: Would delete $filePath ($([math]::Round($fileSize/1KB, 2)) KB)"
}
}
# Delete empty subdirectories
$emptyDirs = Get-ChildItem -Path $LogPath -Directory -Recurse |
Where-Object { (Get-ChildItem $_.FullName -Force).Count -eq 0 }
foreach ($dir in $emptyDirs) {
if ($PSCmdlet.ShouldProcess($dir.FullName, "Remove empty directory")) {
try {
Remove-Item $dir.FullName -Force
Write-Log "Removed empty directory: $($dir.FullName)"
} catch {
Write-Log "ERROR removing directory $($dir.FullName) : $_"
}
}
}
# Summary
$sizeMB = [math]::Round($totalSizeFreed / 1MB, 2)
Write-Log "=== Rotation Complete ==="
Write-Log "Files Deleted: $totalDeleted"
Write-Log "Space Freed: $sizeMB MB"
# Show current disk usage
$currentSize = (Get-ChildItem -Path $LogPath -Recurse -File | Measure-Object -Property Length -Sum).Sum
$currentSizeMB = [math]::Round($currentSize / 1MB, 2)
Write-Log "Current Log Directory Size: $currentSizeMB MB"