Updated
This commit is contained in:
parent
286e684254
commit
1d07addf7f
1 changed files with 400 additions and 69 deletions
459
cleanup.ps1
459
cleanup.ps1
|
|
@ -1,17 +1,100 @@
|
||||||
|
#================================================================================
|
||||||
|
# System Cleanup Script
|
||||||
|
#================================================================================
|
||||||
|
# Purpose: Automates system maintenance tasks including:
|
||||||
|
# - Directory creation
|
||||||
|
# - Quest Help installation
|
||||||
|
# - Windows Defender exclusions
|
||||||
|
# - Restore point configuration
|
||||||
|
# - Application updates
|
||||||
|
# - Windows updates
|
||||||
|
# - Structured webhook logging
|
||||||
|
#================================================================================
|
||||||
|
|
||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
# Logging setup
|
# Logging setup and structured data collection
|
||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
$LogDirectory = "C:\Quest"
|
$LogDirectory = "C:\Quest"
|
||||||
$LogDate = Get-Date -Format "yyyy-MM-dd"
|
$LogDate = Get-Date -Format "yyyy-MM-dd"
|
||||||
$RandomSuffix = Get-Random -Minimum 1000 -Maximum 9999
|
$RandomSuffix = Get-Random -Minimum 1000 -Maximum 9999
|
||||||
$LogFile = Join-Path $LogDirectory "cleanup-${LogDate}-${RandomSuffix}.log"
|
$LogFile = Join-Path $LogDirectory "cleanup-${LogDate}-${RandomSuffix}.log"
|
||||||
|
$WebhookUrl = "https://n8n.questcomputers.be/webhook-test/99077b7d-140f-477e-9241-2b9581ddaf34"
|
||||||
|
$ScriptStartTime = Get-Date
|
||||||
|
|
||||||
# Create log directory if it doesn't exist
|
# Create log directory if it doesn't exist
|
||||||
if (-not (Test-Path $LogDirectory)) {
|
if (-not (Test-Path $LogDirectory)) {
|
||||||
New-Item -Path $LogDirectory -ItemType Directory -Force | Out-Null
|
New-Item -Path $LogDirectory -ItemType Directory -Force | Out-Null
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function for timestamped logging
|
# Initialize structured data object
|
||||||
|
$ScriptResult = [ordered]@{
|
||||||
|
"script_name" = "System Cleanup Script"
|
||||||
|
"version" = "1.0"
|
||||||
|
"execution_info" = @{
|
||||||
|
"started_at" = $ScriptStartTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||||
|
"computer_name" = $env:COMPUTERNAME
|
||||||
|
"username" = $env:USERNAME
|
||||||
|
"os_version" = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name ProductName).ProductName
|
||||||
|
"os_build" = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name CurrentBuild).CurrentBuild
|
||||||
|
"log_file" = $LogFile
|
||||||
|
}
|
||||||
|
"directory_check" = @{
|
||||||
|
"path" = "C:\Quest"
|
||||||
|
"exists" = $false
|
||||||
|
"created" = $false
|
||||||
|
"action_taken" = ""
|
||||||
|
}
|
||||||
|
"quest_help" = @{
|
||||||
|
"installed" = $false
|
||||||
|
"action_taken" = ""
|
||||||
|
"download_successful" = $false
|
||||||
|
"installer_started" = $false
|
||||||
|
"installer_path" = "C:\Program Files\Quest Help\Quest Help.exe"
|
||||||
|
}
|
||||||
|
"defender_exclusions" = @{
|
||||||
|
"paths_added" = @()
|
||||||
|
"processes_added" = @()
|
||||||
|
"errors" = @()
|
||||||
|
}
|
||||||
|
"restore_points" = @{
|
||||||
|
"system_restore_enabled" = $false
|
||||||
|
"scheduled_task_exists" = $false
|
||||||
|
"scheduled_task_created" = $false
|
||||||
|
"scheduled_task_updated" = $false
|
||||||
|
"frequency_configured" = $false
|
||||||
|
}
|
||||||
|
"app_updates" = @{
|
||||||
|
"winget_available" = $false
|
||||||
|
"apps_checked" = 0
|
||||||
|
"apps_updated" = @()
|
||||||
|
"apps_failed" = @()
|
||||||
|
"errors" = @()
|
||||||
|
}
|
||||||
|
"windows_updates" = @{
|
||||||
|
"nuget_installed" = $false
|
||||||
|
"pswindowsupdate_installed" = $false
|
||||||
|
"updates_available" = 0
|
||||||
|
"updates_installed" = @()
|
||||||
|
"updates_failed" = @()
|
||||||
|
"reboot_required" = $false
|
||||||
|
"errors" = @()
|
||||||
|
}
|
||||||
|
"webhook" = @{
|
||||||
|
"url_configured" = $true
|
||||||
|
"sent" = $false
|
||||||
|
"status_code" = $null
|
||||||
|
"error" = $null
|
||||||
|
}
|
||||||
|
"summary" = @{
|
||||||
|
"completed_at" = $null
|
||||||
|
"total_duration_seconds" = $null
|
||||||
|
"total_errors" = 0
|
||||||
|
"total_warnings" = 0
|
||||||
|
"overall_status" = "unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function for logging
|
||||||
function Write-Log {
|
function Write-Log {
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
|
|
@ -31,25 +114,77 @@ function Write-Log {
|
||||||
|
|
||||||
# Initialize log file
|
# Initialize log file
|
||||||
"================================================================================" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
"================================================================================" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
||||||
"Script started at $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
"System Cleanup Script - Started at $ScriptStartTime" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
||||||
"Log file: $LogFile" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
"Log file: $LogFile" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
||||||
|
"Computer: $($env:COMPUTERNAME)" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
||||||
|
"User: $($env:USERNAME)" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
||||||
"================================================================================" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
"================================================================================" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
||||||
"" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
"" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
# Directory check and creation
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
|
Write-Log "SECTION: Directory Check" -Level "INFO"
|
||||||
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
|
Write-Log "Checking if directory C:\Quest exists..."
|
||||||
|
|
||||||
|
if (Test-Path -Path "C:\Quest" -PathType Container) {
|
||||||
|
Write-Log "Directory C:\Quest already exists." -Level "INFO"
|
||||||
|
$ScriptResult.directory_check.exists = $true
|
||||||
|
$ScriptResult.directory_check.action_taken = "already_exists"
|
||||||
|
} else {
|
||||||
|
Write-Log "Directory C:\Quest does not exist. Creating..." -Level "WARNING"
|
||||||
|
try {
|
||||||
|
New-Item -Path C:\Quest -ItemType Directory -Force | Out-Null
|
||||||
|
$ScriptResult.directory_check.created = $true
|
||||||
|
$ScriptResult.directory_check.action_taken = "created"
|
||||||
|
Write-Log "Directory C:\Quest created successfully." -Level "INFO"
|
||||||
|
} catch {
|
||||||
|
$ScriptResult.directory_check.action_taken = "creation_failed"
|
||||||
|
Write-Log "Failed to create directory C:\Quest: $($_.Exception.Message)" -Level "ERROR"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Log "Directory check completed." -Level "INFO"
|
||||||
|
"" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
||||||
|
|
||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
# Quest Help download and installation
|
# Quest Help download and installation
|
||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
|
Write-Log "SECTION: Quest Help Installation" -Level "INFO"
|
||||||
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
Write-Log "Checking if Quest Help exists..."
|
Write-Log "Checking if Quest Help exists..."
|
||||||
|
|
||||||
if (Test-Path "C:\Program Files\Quest Help\Quest Help.exe") {
|
if (Test-Path "C:\Program Files\Quest Help\Quest Help.exe") {
|
||||||
Write-Log "Quest Help found! Skipping installation..." -Level "INFO"
|
Write-Log "Quest Help found at C:\Program Files\Quest Help\Quest Help.exe" -Level "INFO"
|
||||||
|
$ScriptResult.quest_help.installed = $true
|
||||||
|
$ScriptResult.quest_help.action_taken = "already_installed"
|
||||||
} else {
|
} else {
|
||||||
Write-Log "Quest Help not found! Downloading installer..." -Level "WARNING"
|
Write-Log "Quest Help not found. Proceeding with download..." -Level "WARNING"
|
||||||
Invoke-WebRequest -Uri "https://hulpvanopafstand.be/assets/downloads/quest_help.exe" -OutFile "C:\Quest\quest_help.exe"
|
$ScriptResult.quest_help.action_taken = "downloading"
|
||||||
Write-Log "Download completed." -Level "INFO"
|
|
||||||
Write-Log "Starting installer..." -Level "INFO"
|
try {
|
||||||
|
Write-Log "Downloading Quest Help installer from https://hulpvanopafstand.be/assets/downloads/quest_help.exe" -Level "INFO"
|
||||||
|
Invoke-WebRequest -Uri "https://hulpvanopafstand.be/assets/downloads/quest_help.exe" -OutFile "C:\Quest\quest_help.exe" -ErrorAction Stop
|
||||||
|
$ScriptResult.quest_help.download_successful = $true
|
||||||
|
Write-Log "Download completed. File saved to C:\Quest\quest_help.exe" -Level "INFO"
|
||||||
|
|
||||||
|
if (Test-Path "C:\Quest\quest_help.exe") {
|
||||||
|
Write-Log "Starting Quest Help installer..." -Level "INFO"
|
||||||
Start-Process "C:\Quest\quest_help.exe"
|
Start-Process "C:\Quest\quest_help.exe"
|
||||||
Write-Log "Installer started." -Level "INFO"
|
$ScriptResult.quest_help.installer_started = $true
|
||||||
|
$ScriptResult.quest_help.action_taken = "downloaded_and_started"
|
||||||
|
Write-Log "Installer started successfully." -Level "INFO"
|
||||||
|
} else {
|
||||||
|
Write-Log "Downloaded file not found." -Level "ERROR"
|
||||||
|
$ScriptResult.quest_help.action_taken = "download_failed"
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Log "Failed to download Quest Help: $($_.Exception.Message)" -Level "ERROR"
|
||||||
|
$ScriptResult.quest_help.action_taken = "download_failed"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Log "Quest Help check completed." -Level "INFO"
|
Write-Log "Quest Help check completed." -Level "INFO"
|
||||||
|
|
@ -58,7 +193,9 @@ Write-Log "Quest Help check completed." -Level "INFO"
|
||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
# Add defender exclusions
|
# Add defender exclusions
|
||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
Write-Log "Adding Windows Defender exclusions..."
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
|
Write-Log "SECTION: Windows Defender Exclusions" -Level "INFO"
|
||||||
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
|
|
||||||
$ExclusionPaths = @(
|
$ExclusionPaths = @(
|
||||||
"C:\Quest\*",
|
"C:\Quest\*",
|
||||||
|
|
@ -74,134 +211,328 @@ $ExclusionProcesses = @(
|
||||||
"C:\Windows\Temp\is-*.tmp\tacticalagent*"
|
"C:\Windows\Temp\is-*.tmp\tacticalagent*"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Write-Log "Adding path exclusions..." -Level "INFO"
|
||||||
foreach ($Path in $ExclusionPaths) {
|
foreach ($Path in $ExclusionPaths) {
|
||||||
try {
|
try {
|
||||||
Add-MpPreference -ExclusionPath $Path -ErrorAction Stop | Out-Null
|
Add-MpPreference -ExclusionPath $Path -ErrorAction Stop | Out-Null
|
||||||
Write-Log "Added exclusion path: $Path" -Level "INFO"
|
$ScriptResult.defender_exclusions.paths_added += $Path
|
||||||
|
Write-Log "Added path exclusion: $Path" -Level "INFO"
|
||||||
} catch {
|
} catch {
|
||||||
Write-Log "Failed to add exclusion path: $Path - $($_.Exception.Message)" -Level "ERROR"
|
$ErrorMsg = "Failed to add path exclusion: $Path - $($_.Exception.Message)"
|
||||||
|
$ScriptResult.defender_exclusions.errors += $ErrorMsg
|
||||||
|
Write-Log $ErrorMsg -Level "ERROR"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Write-Log "Adding process exclusions..." -Level "INFO"
|
||||||
foreach ($Process in $ExclusionProcesses) {
|
foreach ($Process in $ExclusionProcesses) {
|
||||||
try {
|
try {
|
||||||
Add-MpPreference -ExclusionProcess $Process -ErrorAction Stop | Out-Null
|
Add-MpPreference -ExclusionProcess $Process -ErrorAction Stop | Out-Null
|
||||||
Write-Log "Added exclusion process: $Process" -Level "INFO"
|
$ScriptResult.defender_exclusions.processes_added += $Process
|
||||||
|
Write-Log "Added process exclusion: $Process" -Level "INFO"
|
||||||
} catch {
|
} catch {
|
||||||
Write-Log "Failed to add exclusion process: $Process - $($_.Exception.Message)" -Level "ERROR"
|
$ErrorMsg = "Failed to add process exclusion: $Process - $($_.Exception.Message)"
|
||||||
|
$ScriptResult.defender_exclusions.errors += $ErrorMsg
|
||||||
|
Write-Log $ErrorMsg -Level "ERROR"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Log "Defender exclusions completed." -Level "INFO"
|
$TotalExclusions = $ScriptResult.defender_exclusions.paths_added.Count + $ScriptResult.defender_exclusions.processes_added.Count
|
||||||
|
Write-Log "Defender exclusions completed. Total exclusions added: $TotalExclusions" -Level "INFO"
|
||||||
"" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
"" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
||||||
|
|
||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
# Enable daily restore points
|
# Enable daily restore points
|
||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
Write-Log "Setting up daily restore points..."
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
|
Write-Log "SECTION: System Restore Configuration" -Level "INFO"
|
||||||
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
|
|
||||||
|
# Enable System Restore
|
||||||
|
Write-Log "Enabling System Restore for C: drive..." -Level "INFO"
|
||||||
try {
|
try {
|
||||||
Enable-ComputerRestore -Drive 'C:' -ErrorAction Stop | Out-Null
|
Enable-ComputerRestore -Drive 'C:' -ErrorAction Stop | Out-Null
|
||||||
|
$ScriptResult.restore_points.system_restore_enabled = $true
|
||||||
Write-Log "System Restore enabled for C: drive." -Level "INFO"
|
Write-Log "System Restore enabled for C: drive." -Level "INFO"
|
||||||
} catch {
|
} catch {
|
||||||
Write-Log "Failed to enable System Restore: $($_.Exception.Message)" -Level "ERROR"
|
Write-Log "Failed to enable System Restore: $($_.Exception.Message)" -Level "ERROR"
|
||||||
}
|
}
|
||||||
|
|
||||||
Register-ScheduledTask -TaskName "Daily System Restore" -Action (New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-ExecutionPolicy Bypass -Command `"Checkpoint-Computer -Description \"\"AUTOMATIC-$(Get-Date -Format 'yyyyMMddHHmmss')\"\" -RestorePointType \"\"MODIFY_SETTINGS\"\"`"") -Trigger (New-ScheduledTaskTrigger -Daily -At 9am) -Settings (New-ScheduledTaskSettingsSet -StartWhenAvailable -DontStopOnIdleEnd -RunOnlyIfNetworkAvailable) -Principal (New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest) -ErrorAction Stop | Out-Null
|
# Check if scheduled task already exists
|
||||||
Write-Log "Scheduled task 'Daily System Restore' created." -Level "INFO"
|
$TaskName = "Daily System Restore"
|
||||||
|
$TaskExists = $false
|
||||||
|
|
||||||
|
Write-Log "Checking for existing scheduled task '$TaskName'..." -Level "INFO"
|
||||||
|
try {
|
||||||
|
$ExistingTask = Get-ScheduledTask -TaskName $TaskName -ErrorAction Stop
|
||||||
|
if ($ExistingTask) {
|
||||||
|
$TaskExists = $true
|
||||||
|
$ScriptResult.restore_points.scheduled_task_exists = $true
|
||||||
|
Write-Log "Scheduled task '$TaskName' already exists." -Level "INFO"
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Log "Scheduled task '$TaskName' not found. Will create new task." -Level "INFO"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $TaskExists) {
|
||||||
|
try {
|
||||||
|
Write-Log "Creating scheduled task '$TaskName'..." -Level "INFO"
|
||||||
|
Register-ScheduledTask -TaskName $TaskName -Action (New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-ExecutionPolicy Bypass -Command `"Checkpoint-Computer -Description \"\"AUTOMATIC-$(Get-Date -Format 'yyyyMMddHHmmss')\"\" -RestorePointType \"\"MODIFY_SETTINGS\"\"`"") -Trigger (New-ScheduledTaskTrigger -Daily -At 9am) -Settings (New-ScheduledTaskSettingsSet -StartWhenAvailable -DontStopOnIdleEnd -RunOnlyIfNetworkAvailable) -Principal (New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest) -ErrorAction Stop | Out-Null
|
||||||
|
$ScriptResult.restore_points.scheduled_task_created = $true
|
||||||
|
Write-Log "Scheduled task '$TaskName' created successfully." -Level "INFO"
|
||||||
|
Write-Log "Task will run daily at 9:00 AM as NT AUTHORITY\SYSTEM" -Level "INFO"
|
||||||
|
} catch {
|
||||||
|
Write-Log "Failed to create scheduled task: $($_.Exception.Message)" -Level "ERROR"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
# Update existing task
|
||||||
|
try {
|
||||||
|
Write-Log "Updating existing scheduled task '$TaskName'..." -Level "INFO"
|
||||||
|
Set-ScheduledTask -TaskName $TaskName -Action (New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-ExecutionPolicy Bypass -Command `"Checkpoint-Computer -Description \"\"AUTOMATIC-$(Get-Date -Format 'yyyyMMddHHmmss')\"\" -RestorePointType \"\"MODIFY_SETTINGS\"\"`"") -Trigger (New-ScheduledTaskTrigger -Daily -At 9am) -Settings (New-ScheduledTaskSettingsSet -StartWhenAvailable -DontStopOnIdleEnd -RunOnlyIfNetworkAvailable) -Principal (New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest) -ErrorAction Stop | Out-Null
|
||||||
|
$ScriptResult.restore_points.scheduled_task_updated = $true
|
||||||
|
Write-Log "Scheduled task '$TaskName' updated successfully." -Level "INFO"
|
||||||
|
} catch {
|
||||||
|
Write-Log "Failed to update scheduled task: $($_.Exception.Message)" -Level "ERROR"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configure restore point frequency
|
||||||
|
Write-Log "Configuring restore point frequency..." -Level "INFO"
|
||||||
try {
|
try {
|
||||||
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRestore" -Name "SystemRestorePointFrequency" -Value 0 -Type DWORD -Force -ErrorAction Stop
|
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRestore" -Name "SystemRestorePointFrequency" -Value 0 -Type DWORD -Force -ErrorAction Stop
|
||||||
|
$ScriptResult.restore_points.frequency_configured = $true
|
||||||
Write-Log "Restore point frequency set to 0 (allows frequent restore points)." -Level "INFO"
|
Write-Log "Restore point frequency set to 0 (allows frequent restore points)." -Level "INFO"
|
||||||
} catch {
|
} catch {
|
||||||
Write-Log "Failed to set restore point frequency: $($_.Exception.Message)" -Level "ERROR"
|
Write-Log "Failed to set restore point frequency: $($_.Exception.Message)" -Level "ERROR"
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Log "Restore points setup completed." -Level "INFO"
|
Write-Log "System Restore configuration completed." -Level "INFO"
|
||||||
"" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
"" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
||||||
|
|
||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
# Updating all apps
|
# Updating all apps
|
||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
Write-Log "Upgrading all applications with winget..."
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
|
Write-Log "SECTION: Application Updates (winget)" -Level "INFO"
|
||||||
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
|
|
||||||
|
# Check if winget is available
|
||||||
try {
|
try {
|
||||||
winget upgrade --all 2>&1 | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
$wingetCheck = Get-Command winget -ErrorAction Stop
|
||||||
Write-Log "Winget upgrade completed." -Level "INFO"
|
$ScriptResult.app_updates.winget_available = $true
|
||||||
|
Write-Log "Winget is available on this system." -Level "INFO"
|
||||||
} catch {
|
} catch {
|
||||||
Write-Log "Winget upgrade failed: $($_.Exception.Message)" -Level "ERROR"
|
Write-Log "Winget is not available on this system. Skipping application updates." -Level "WARNING"
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Log "Application updates completed." -Level "INFO"
|
if ($ScriptResult.app_updates.winget_available) {
|
||||||
|
try {
|
||||||
|
Write-Log "Running winget upgrade for all applications..." -Level "INFO"
|
||||||
|
$wingetOutput = winget upgrade --all 2>&1 | Out-String
|
||||||
|
$wingetOutput | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
||||||
|
|
||||||
|
# Parse winget output to extract updated apps
|
||||||
|
$lines = $wingetOutput -split "`n"
|
||||||
|
$AppsUpdated = @()
|
||||||
|
foreach ($line in $lines) {
|
||||||
|
# Skip header/footer lines and empty lines
|
||||||
|
if ([string]::IsNullOrWhiteSpace($line)) { continue }
|
||||||
|
if ($line -match "^\s*Name\s+Id" -or $line -match "^\s*-{3,}") { continue }
|
||||||
|
if ($line -match "Successfully|No applicable|found\.|upgrade" -and $line.Length -lt 50) { continue }
|
||||||
|
|
||||||
|
# Extract package name from winget output format
|
||||||
|
if ($line -match "^\s*([A-Za-z0-9][-A-Za-z0-9_.]*[A-Za-z0-9])\s+") {
|
||||||
|
$packageName = $matches[1]
|
||||||
|
if ($packageName -and $packageName.Length -gt 1 -and $packageName -notmatch "^-") {
|
||||||
|
$AppsUpdated += $packageName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$ScriptResult.app_updates.apps_updated = $AppsUpdated
|
||||||
|
$ScriptResult.app_updates.apps_checked = $AppsUpdated.Count
|
||||||
|
|
||||||
|
if ($AppsUpdated.Count -gt 0) {
|
||||||
|
Write-Log "Application updates completed. Updated $($AppsUpdated.Count) application(s): $($AppsUpdated -join ', ')" -Level "INFO"
|
||||||
|
} else {
|
||||||
|
Write-Log "Application updates completed. All applications are up to date." -Level "INFO"
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
$ErrorMsg = "Winget upgrade failed: $($_.Exception.Message)"
|
||||||
|
$ScriptResult.app_updates.errors += $ErrorMsg
|
||||||
|
Write-Log $ErrorMsg -Level "ERROR"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Log "Winget not available. Skipping application updates." -Level "INFO"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Log "Application updates section completed." -Level "INFO"
|
||||||
"" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
"" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
||||||
|
|
||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
# Updating Windows
|
# Updating Windows
|
||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
Write-Log "Updating Windows..."
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
|
Write-Log "SECTION: Windows Updates" -Level "INFO"
|
||||||
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
|
|
||||||
|
# Install NuGet provider
|
||||||
|
Write-Log "Installing NuGet package provider..." -Level "INFO"
|
||||||
try {
|
try {
|
||||||
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -ErrorAction Stop | Out-Null
|
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -ErrorAction Stop | Out-Null
|
||||||
Write-Log "NuGet package provider installed." -Level "INFO"
|
$ScriptResult.windows_updates.nuget_installed = $true
|
||||||
|
Write-Log "NuGet package provider installed successfully." -Level "INFO"
|
||||||
} catch {
|
} catch {
|
||||||
Write-Log "Failed to install NuGet: $($_.Exception.Message)" -Level "ERROR"
|
Write-Log "Failed to install NuGet: $($_.Exception.Message)" -Level "ERROR"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Install PSWindowsUpdate module
|
||||||
|
Write-Log "Installing PSWindowsUpdate module..." -Level "INFO"
|
||||||
try {
|
try {
|
||||||
Install-Module PSWindowsUpdate -Force -AllowClobber -ErrorAction Stop | Out-Null
|
Install-Module PSWindowsUpdate -Force -AllowClobber -ErrorAction Stop | Out-Null
|
||||||
Write-Log "PSWindowsUpdate module installed." -Level "INFO"
|
$ScriptResult.windows_updates.pswindowsupdate_installed = $true
|
||||||
|
Write-Log "PSWindowsUpdate module installed successfully." -Level "INFO"
|
||||||
} catch {
|
} catch {
|
||||||
Write-Log "Failed to install PSWindowsUpdate: $($_.Exception.Message)" -Level "ERROR"
|
Write-Log "Failed to install PSWindowsUpdate: $($_.Exception.Message)" -Level "ERROR"
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
# Import PSWindowsUpdate module
|
||||||
|
if ($ScriptResult.windows_updates.pswindowsupdate_installed) {
|
||||||
|
try {
|
||||||
|
Write-Log "Importing PSWindowsUpdate module..." -Level "INFO"
|
||||||
Import-Module PSWindowsUpdate -ErrorAction Stop
|
Import-Module PSWindowsUpdate -ErrorAction Stop
|
||||||
Write-Log "PSWindowsUpdate module imported." -Level "INFO"
|
Write-Log "PSWindowsUpdate module imported successfully." -Level "INFO"
|
||||||
} catch {
|
} catch {
|
||||||
Write-Log "Failed to import PSWindowsUpdate: $($_.Exception.Message)" -Level "ERROR"
|
Write-Log "Failed to import PSWindowsUpdate: $($_.Exception.Message)" -Level "ERROR"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check for and install Windows updates
|
||||||
|
if ($ScriptResult.windows_updates.pswindowsupdate_installed) {
|
||||||
|
try {
|
||||||
|
Write-Log "Checking for Windows updates..." -Level "INFO"
|
||||||
|
|
||||||
|
# Get list of available updates first
|
||||||
|
$AvailableUpdates = Get-WindowsUpdate -AcceptAll -ListOnly -ErrorAction Stop
|
||||||
|
$ScriptResult.windows_updates.updates_available = $AvailableUpdates.Count
|
||||||
|
Write-Log "Found $($AvailableUpdates.Count) Windows update(s)." -Level "INFO"
|
||||||
|
|
||||||
|
# Install updates
|
||||||
|
Write-Log "Installing Windows updates..." -Level "INFO"
|
||||||
|
$InstallOutput = Get-WindowsUpdate -AcceptAll -Install -ErrorAction Stop 2>&1 | Out-String
|
||||||
|
$InstallOutput | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
||||||
|
|
||||||
|
# Parse installed updates
|
||||||
|
foreach ($Update in $AvailableUpdates) {
|
||||||
|
$UpdateInfo = @{
|
||||||
|
"kb" = $Update.KB
|
||||||
|
"title" = $Update.Title
|
||||||
|
"description" = $Update.Description
|
||||||
|
"size_mb" = [math]::Round($Update.Size / 1MB, 2)
|
||||||
|
"is_downloaded" = $Update.IsDownloaded
|
||||||
|
"reboot_required" = $Update.RebootRequired
|
||||||
|
}
|
||||||
|
$ScriptResult.windows_updates.updates_installed += $UpdateInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if reboot is required
|
||||||
|
if ($InstallOutput -match "reboot|Reboot|restart") {
|
||||||
|
$ScriptResult.windows_updates.reboot_required = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Log "Windows updates installation completed." -Level "INFO"
|
||||||
|
if ($AvailableUpdates.Count -gt 0) {
|
||||||
|
Write-Log "Installed $($AvailableUpdates.Count) update(s)." -Level "INFO"
|
||||||
|
} else {
|
||||||
|
Write-Log "No Windows updates were needed." -Level "INFO"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ScriptResult.windows_updates.reboot_required) {
|
||||||
|
Write-Log "A system reboot is required to complete the updates." -Level "WARNING"
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
$ErrorMsg = "Failed to install Windows updates: $($_.Exception.Message)"
|
||||||
|
$ScriptResult.windows_updates.errors += $ErrorMsg
|
||||||
|
Write-Log $ErrorMsg -Level "ERROR"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Log "PSWindowsUpdate not installed. Skipping Windows updates." -Level "INFO"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Log "Windows updates section completed." -Level "INFO"
|
||||||
|
"" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
# Send structured JSON to webhook
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
|
Write-Log "SECTION: Webhook Notification" -Level "INFO"
|
||||||
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Get-WindowsUpdate -AcceptAll -Install -ErrorAction Stop 2>&1 | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
# Complete the summary
|
||||||
Write-Log "Windows updates installed." -Level "INFO"
|
$ScriptEndTime = Get-Date
|
||||||
|
$ScriptResult.summary.completed_at = $ScriptEndTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||||
|
$ScriptResult.summary.total_duration_seconds = [math]::Round(($ScriptEndTime - $ScriptStartTime).TotalSeconds, 2)
|
||||||
|
|
||||||
|
# Count errors and warnings from log file
|
||||||
|
$LogContent = Get-Content $LogFile
|
||||||
|
$ScriptResult.summary.total_errors = ($LogContent | Where-Object { $_ -match '\[ERROR\]' }).Count
|
||||||
|
$ScriptResult.summary.total_warnings = ($LogContent | Where-Object { $_ -match '\[WARNING\]' }).Count
|
||||||
|
|
||||||
|
# Determine overall status
|
||||||
|
if ($ScriptResult.summary.total_errors -gt 0) {
|
||||||
|
$ScriptResult.summary.overall_status = "completed_with_errors"
|
||||||
|
} elseif ($ScriptResult.summary.total_warnings -gt 0) {
|
||||||
|
$ScriptResult.summary.overall_status = "completed_with_warnings"
|
||||||
|
} else {
|
||||||
|
$ScriptResult.summary.overall_status = "completed_successfully"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Convert to JSON with proper formatting
|
||||||
|
$WebhookPayload = $ScriptResult | ConvertTo-Json -Depth 10
|
||||||
|
|
||||||
|
Write-Log "Sending structured JSON to webhook..." -Level "INFO"
|
||||||
|
Write-Log "Webhook URL: $WebhookUrl" -Level "INFO"
|
||||||
|
|
||||||
|
# Send to webhook
|
||||||
|
$WebhookResponse = Invoke-WebRequest -Uri $WebhookUrl -Method POST -Body $WebhookPayload -ContentType "application/json" -ErrorAction Stop
|
||||||
|
|
||||||
|
$ScriptResult.webhook.sent = $true
|
||||||
|
$ScriptResult.webhook.status_code = $WebhookResponse.StatusCode
|
||||||
|
Write-Log "Webhook notification sent successfully. Status: $($WebhookResponse.StatusCode)" -Level "INFO"
|
||||||
} catch {
|
} catch {
|
||||||
Write-Log "Failed to install Windows updates: $($_.Exception.Message)" -Level "ERROR"
|
$ScriptResult.webhook.error = $_.Exception.Message
|
||||||
|
Write-Log "Failed to send webhook notification: $($_.Exception.Message)" -Level "ERROR"
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Log "Windows update completed." -LEVEL "INFO"
|
Write-Log "Webhook section completed." -Level "INFO"
|
||||||
"" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
"" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
||||||
|
|
||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
# Script completion
|
# Script completion
|
||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
Write-Log "Script completed at $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -Level "INFO"
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
Write-Log "Log file saved to: $LogFile" -Level "INFO"
|
Write-Log "Script Execution Summary" -Level "INFO"
|
||||||
"================================================================================" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
|
Write-Log "Completed at: $(Get-Date)" -Level "INFO"
|
||||||
# --------------------------------------------------------------------------------
|
Write-Log "Duration: $($ScriptResult.summary.total_duration_seconds) seconds" -Level "INFO"
|
||||||
# Send log to webhook
|
Write-Log "Overall Status: $($ScriptResult.summary.overall_status)" -Level "INFO"
|
||||||
# --------------------------------------------------------------------------------
|
Write-Log "Total Errors: $($ScriptResult.summary.total_errors)" -Level "INFO"
|
||||||
Write-Log "Sending log file to webhook..."
|
Write-Log "Total Warnings: $($ScriptResult.summary.total_warnings)" -Level "INFO"
|
||||||
|
Write-Log "Log File: $LogFile" -Level "INFO"
|
||||||
try {
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
# Read log file content
|
Write-Log "System Cleanup Script Completed" -Level "INFO"
|
||||||
$LogContent = Get-Content -Path $LogFile -Raw -ErrorAction Stop
|
Write-Log "================================================================================" -Level "INFO"
|
||||||
|
|
||||||
# Prepare webhook payload
|
|
||||||
$WebhookPayload = @{
|
|
||||||
"log_file" = $LogFile
|
|
||||||
"log_content" = $LogContent
|
|
||||||
"timestamp" = (Get-Date -Format "yyyy-MM-dd HH:mm:ss")
|
|
||||||
"status" = "completed"
|
|
||||||
} | ConvertTo-Json -Depth 3
|
|
||||||
|
|
||||||
# Send to webhook
|
|
||||||
$WebhookResponse = Invoke-WebRequest -Uri "https://n8n.questcomputers.be/webhook-test/99077b7d-140f-477e-9241-2b9581ddaf34" -Method POST -Body $WebhookPayload -ContentType "application/json" -ErrorAction Stop
|
|
||||||
|
|
||||||
Write-Log "Log file sent to webhook successfully. Status: $($WebhookResponse.StatusCode)" -Level "INFO"
|
|
||||||
} catch {
|
|
||||||
Write-Log "Failed to send log to webhook: $($_.Exception.Message)" -Level "ERROR"
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Log "Webhook notification completed." -Level "INFO"
|
|
||||||
"" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
"" | Out-File -FilePath $LogFile -Append -Encoding UTF8
|
||||||
|
|
||||||
|
# Display completion message
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "===========================================" -ForegroundColor Green
|
||||||
|
Write-Host "Script completed successfully!" -ForegroundColor Green
|
||||||
|
Write-Host "Duration: $($ScriptResult.summary.total_duration_seconds) seconds" -ForegroundColor Green
|
||||||
|
Write-Host "Status: $($ScriptResult.summary.overall_status)" -ForegroundColor Green
|
||||||
|
Write-Host "Errors: $($ScriptResult.summary.total_errors)" -ForegroundColor $(if ($ScriptResult.summary.total_errors -gt 0) { "Red" } else { "Green" })
|
||||||
|
Write-Host "Warnings: $($ScriptResult.summary.total_warnings)" -ForegroundColor $(if ($ScriptResult.summary.total_warnings -gt 0) { "Yellow" } else { "Green" })
|
||||||
|
Write-Host "Log file: $LogFile" -ForegroundColor Cyan
|
||||||
|
Write-Host "===========================================" -ForegroundColor Green
|
||||||
Loading…
Add table
Add a link
Reference in a new issue