Sync all scripts from website downloads — 352 scripts total
Includes updated JS challenge scripts with Claude-User whitelist, same-site referer bypass, Blackbox-Exporter allowed bot, and all new exporters, cheat sheets, and automation scripts.
This commit is contained in:
@@ -0,0 +1,389 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Deploy the password expiry checker to Windows machines.
|
||||
.DESCRIPTION
|
||||
Downloads password-expiry-check.ps1, installs it to a configurable
|
||||
directory, creates a scheduled task for recurring checks, and
|
||||
optionally copies the script to NETLOGON for GPO deployment.
|
||||
.NOTES
|
||||
Author: Phil Connor <contact@mylinux.work>
|
||||
License: MIT (https://opensource.org/licenses/MIT)
|
||||
Version: 1.01
|
||||
#>
|
||||
|
||||
param(
|
||||
[string]$InstallDir = "C:\Scripts",
|
||||
[int]$WarningDays = 14,
|
||||
[int]$IntervalHours = 4,
|
||||
[switch]$NetlogonCopy,
|
||||
[switch]$CmdPrompt,
|
||||
[switch]$NoProfile,
|
||||
[switch]$Remove,
|
||||
[switch]$DryRun,
|
||||
[Alias("h")]
|
||||
[switch]$Help
|
||||
)
|
||||
|
||||
$ScriptUrl = "https://mylinux.work/downloads/password-expiry-check.ps1.zip"
|
||||
$ScriptName = "password-expiry-check.ps1"
|
||||
$TaskName = "PasswordExpiryCheck"
|
||||
|
||||
# ── Colors ────────────────────────────────────────────────────────────
|
||||
|
||||
function Write-OK { param([string]$Msg) Write-Host "[OK] $Msg" -ForegroundColor Green }
|
||||
function Write-Warn { param([string]$Msg) Write-Host "[WARN] $Msg" -ForegroundColor Yellow }
|
||||
function Write-Err { param([string]$Msg) Write-Host "[ERROR] $Msg" -ForegroundColor Red }
|
||||
function Write-Info { param([string]$Msg) Write-Host "[INFO] $Msg" -ForegroundColor Cyan }
|
||||
|
||||
# ── Help ──────────────────────────────────────────────────────────────
|
||||
|
||||
if ($Help) {
|
||||
Write-Host @"
|
||||
Usage: .\deploy-password-expiry-checker.ps1 [OPTIONS]
|
||||
|
||||
Deploy password expiry notifications on Windows machines.
|
||||
|
||||
Installs:
|
||||
1. password-expiry-check.ps1 to C:\Scripts\ (configurable)
|
||||
2. Scheduled task - runs every 4 hours (configurable) under logged-on user
|
||||
3. Logon-triggered task - fires on every user logon
|
||||
4. PowerShell profile hook - warning banner in every new PowerShell window
|
||||
5. Optional cmd.exe AutoRun hook - warning banner in every new cmd window
|
||||
6. Optional NETLOGON copy for GPO deployment
|
||||
|
||||
Options:
|
||||
-InstallDir PATH Installation directory (default: C:\Scripts)
|
||||
-WarningDays N Warning threshold in days (default: 14)
|
||||
-IntervalHours N Scheduled task interval in hours (default: 4)
|
||||
-CmdPrompt Also add warning to cmd.exe via AutoRun registry key
|
||||
-NoProfile Skip PowerShell profile hook (scheduled tasks only)
|
||||
-NetlogonCopy Copy script to NETLOGON share for GPO deployment
|
||||
-Remove Remove deployed components
|
||||
-DryRun Show what would be done without making changes
|
||||
-Help Show this help
|
||||
|
||||
Examples:
|
||||
.\deploy-password-expiry-checker.ps1 # install with defaults
|
||||
.\deploy-password-expiry-checker.ps1 -CmdPrompt # also hook into cmd.exe
|
||||
.\deploy-password-expiry-checker.ps1 -NoProfile # skip profile hook
|
||||
.\deploy-password-expiry-checker.ps1 -WarningDays 30 # 30-day warning threshold
|
||||
.\deploy-password-expiry-checker.ps1 -IntervalHours 8 # check every 8 hours
|
||||
.\deploy-password-expiry-checker.ps1 -NetlogonCopy # also copy to NETLOGON
|
||||
.\deploy-password-expiry-checker.ps1 -DryRun # preview changes
|
||||
.\deploy-password-expiry-checker.ps1 -Remove # uninstall
|
||||
"@
|
||||
exit 0
|
||||
}
|
||||
|
||||
# ── Admin check ───────────────────────────────────────────────────────
|
||||
|
||||
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
|
||||
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
||||
Write-Err "Must run as Administrator"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$ScriptPath = Join-Path $InstallDir $ScriptName
|
||||
|
||||
# ── Remove mode ───────────────────────────────────────────────────────
|
||||
|
||||
if ($Remove) {
|
||||
Write-Info "Removing password expiry checker deployment..."
|
||||
Write-Host ""
|
||||
|
||||
# Remove scheduled tasks
|
||||
foreach ($name in @($TaskName, "${TaskName}Logon")) {
|
||||
$task = Get-ScheduledTask -TaskName $name -ErrorAction SilentlyContinue
|
||||
if ($task) {
|
||||
if ($DryRun) {
|
||||
Write-Info "Would remove scheduled task: $name"
|
||||
} else {
|
||||
Unregister-ScheduledTask -TaskName $name -Confirm:$false
|
||||
Write-OK "Removed scheduled task: $name"
|
||||
}
|
||||
} else {
|
||||
Write-Info "Scheduled task '$name' not found, skipping"
|
||||
}
|
||||
}
|
||||
|
||||
# Remove script
|
||||
if (Test-Path $ScriptPath) {
|
||||
if ($DryRun) {
|
||||
Write-Info "Would remove: $ScriptPath"
|
||||
} else {
|
||||
Remove-Item -Path $ScriptPath -Force
|
||||
Write-OK "Removed $ScriptPath"
|
||||
}
|
||||
}
|
||||
|
||||
# Remove PowerShell profile hook
|
||||
$profileMarker = "# PasswordExpiryCheck"
|
||||
$allUsersProfile = $PROFILE.AllUsersAllHosts
|
||||
if ((Test-Path $allUsersProfile) -and (Select-String -Path $allUsersProfile -Pattern $profileMarker -Quiet)) {
|
||||
if ($DryRun) {
|
||||
Write-Info "Would remove profile hook from $allUsersProfile"
|
||||
} else {
|
||||
$content = Get-Content $allUsersProfile | Where-Object { $_ -notmatch $profileMarker }
|
||||
if ($content) {
|
||||
Set-Content -Path $allUsersProfile -Value $content
|
||||
} else {
|
||||
Remove-Item -Path $allUsersProfile -Force
|
||||
}
|
||||
Write-OK "Removed PowerShell profile hook"
|
||||
}
|
||||
}
|
||||
|
||||
# Remove cmd.exe AutoRun
|
||||
$cmdAutoRun = Get-ItemProperty -Path "HKLM:\Software\Microsoft\Command Processor" -Name "AutoRun" -ErrorAction SilentlyContinue
|
||||
if ($cmdAutoRun -and $cmdAutoRun.AutoRun -match "password-expiry-check") {
|
||||
if ($DryRun) {
|
||||
Write-Info "Would remove cmd.exe AutoRun registry key"
|
||||
} else {
|
||||
$existing = $cmdAutoRun.AutoRun
|
||||
# Remove our command, handle single command or chained with ampersand
|
||||
$cleaned = ($existing -split '\s*&\s*' | Where-Object { $_ -notmatch 'password-expiry-check' }) -join ' & '
|
||||
if ($cleaned.Trim()) {
|
||||
Set-ItemProperty -Path "HKLM:\Software\Microsoft\Command Processor" -Name "AutoRun" -Value $cleaned.Trim()
|
||||
} else {
|
||||
Remove-ItemProperty -Path "HKLM:\Software\Microsoft\Command Processor" -Name "AutoRun" -ErrorAction SilentlyContinue
|
||||
}
|
||||
Write-OK "Removed cmd.exe AutoRun hook"
|
||||
}
|
||||
}
|
||||
|
||||
# Remove install dir if empty
|
||||
if ((Test-Path $InstallDir) -and @(Get-ChildItem $InstallDir -Force).Count -eq 0) {
|
||||
if ($DryRun) {
|
||||
Write-Info "Would remove empty directory: $InstallDir"
|
||||
} else {
|
||||
Remove-Item -Path $InstallDir -Force
|
||||
Write-OK "Removed empty directory: $InstallDir"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
if (-not $DryRun) {
|
||||
Write-OK "Removal complete."
|
||||
}
|
||||
exit 0
|
||||
}
|
||||
|
||||
# ── Install mode ──────────────────────────────────────────────────────
|
||||
|
||||
Write-Info "Deploying password expiry checker..."
|
||||
Write-Host ""
|
||||
|
||||
# 1. Create install directory
|
||||
if (-not (Test-Path $InstallDir)) {
|
||||
if ($DryRun) {
|
||||
Write-Info "Would create directory: $InstallDir"
|
||||
} else {
|
||||
New-Item -Path $InstallDir -ItemType Directory -Force | Out-Null
|
||||
Write-OK "Created directory: $InstallDir"
|
||||
}
|
||||
}
|
||||
|
||||
# 2. Download script
|
||||
if (Test-Path $ScriptPath) {
|
||||
Write-Info "Script already exists at $ScriptPath - downloading latest version"
|
||||
}
|
||||
|
||||
if ($DryRun) {
|
||||
Write-Info "Would download $ScriptUrl and extract to $ScriptPath"
|
||||
} else {
|
||||
$zipPath = Join-Path $env:TEMP "password-expiry-check.ps1.zip"
|
||||
try {
|
||||
Invoke-WebRequest -Uri $ScriptUrl -OutFile $zipPath -UseBasicParsing -ErrorAction Stop
|
||||
Expand-Archive -Path $zipPath -DestinationPath $InstallDir -Force
|
||||
Remove-Item $zipPath -Force -ErrorAction SilentlyContinue
|
||||
if (Test-Path $ScriptPath) {
|
||||
Write-OK "Downloaded and extracted $ScriptPath"
|
||||
} else {
|
||||
Write-Err "Zip extracted but $ScriptName not found in $InstallDir"
|
||||
exit 1
|
||||
}
|
||||
} catch {
|
||||
Write-Err "Failed to download: $($_.Exception.Message)"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# 3. Scheduled task - recurring interval
|
||||
$taskArgs = "-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$ScriptPath`" -Quiet -WarningDays $WarningDays"
|
||||
|
||||
$existingTask = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
||||
if ($existingTask) {
|
||||
Write-Info "Scheduled task '$TaskName' already exists - recreating"
|
||||
if (-not $DryRun) {
|
||||
Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false
|
||||
}
|
||||
}
|
||||
|
||||
if ($DryRun) {
|
||||
Write-Info "Would create scheduled task: $TaskName (every ${IntervalHours}h)"
|
||||
} else {
|
||||
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument $taskArgs
|
||||
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).Date.AddHours(9) `
|
||||
-RepetitionInterval (New-TimeSpan -Hours $IntervalHours) `
|
||||
-RepetitionDuration (New-TimeSpan -Days 365)
|
||||
$settings = New-ScheduledTaskSettingsSet `
|
||||
-AllowStartIfOnBatteries `
|
||||
-DontStopIfGoingOnBatteries `
|
||||
-StartWhenAvailable `
|
||||
-RunOnlyIfNetworkAvailable:$false
|
||||
$principal = New-ScheduledTaskPrincipal -GroupId "S-1-5-32-545" -RunLevel Limited
|
||||
|
||||
Register-ScheduledTask -TaskName $TaskName -Action $action -Trigger $trigger `
|
||||
-Settings $settings -Principal $principal `
|
||||
-Description "Check password expiry every $IntervalHours hours (mylinux.work)" | Out-Null
|
||||
Write-OK "Created scheduled task: $TaskName (every ${IntervalHours}h)"
|
||||
}
|
||||
|
||||
# 4. Logon trigger task
|
||||
$logonTaskName = "${TaskName}Logon"
|
||||
$existingLogon = Get-ScheduledTask -TaskName $logonTaskName -ErrorAction SilentlyContinue
|
||||
if ($existingLogon) {
|
||||
Write-Info "Logon task '$logonTaskName' already exists - recreating"
|
||||
if (-not $DryRun) {
|
||||
Unregister-ScheduledTask -TaskName $logonTaskName -Confirm:$false
|
||||
}
|
||||
}
|
||||
|
||||
if ($DryRun) {
|
||||
Write-Info "Would create logon trigger task: $logonTaskName"
|
||||
} else {
|
||||
$logonAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument $taskArgs
|
||||
$logonTrigger = New-ScheduledTaskTrigger -AtLogOn
|
||||
$logonSettings = New-ScheduledTaskSettingsSet `
|
||||
-AllowStartIfOnBatteries `
|
||||
-DontStopIfGoingOnBatteries `
|
||||
-StartWhenAvailable `
|
||||
-ExecutionTimeLimit (New-TimeSpan -Minutes 5)
|
||||
# Delay 30 seconds after logon to let the desktop load
|
||||
$logonTrigger.Delay = "PT30S"
|
||||
$logonPrincipal = New-ScheduledTaskPrincipal -GroupId "S-1-5-32-545" -RunLevel Limited
|
||||
|
||||
Register-ScheduledTask -TaskName $logonTaskName -Action $logonAction -Trigger $logonTrigger `
|
||||
-Settings $logonSettings -Principal $logonPrincipal `
|
||||
-Description "Check password expiry at logon (mylinux.work)" | Out-Null
|
||||
Write-OK "Created logon trigger task: $logonTaskName"
|
||||
}
|
||||
|
||||
# 5. NETLOGON copy (optional)
|
||||
if ($NetlogonCopy) {
|
||||
$logonServer = $env:LOGONSERVER
|
||||
if ($logonServer) {
|
||||
$netlogonPath = Join-Path "$logonServer\NETLOGON" $ScriptName
|
||||
if ($DryRun) {
|
||||
Write-Info "Would copy $ScriptPath to $netlogonPath"
|
||||
} else {
|
||||
try {
|
||||
Copy-Item -Path $ScriptPath -Destination $netlogonPath -Force -ErrorAction Stop
|
||||
Write-OK "Copied to $netlogonPath"
|
||||
} catch {
|
||||
Write-Warn "Could not copy to NETLOGON: $($_.Exception.Message)"
|
||||
Write-Warn "Copy manually: Copy-Item '$ScriptPath' '$netlogonPath'"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Warn "LOGONSERVER not set - machine may not be domain-joined"
|
||||
Write-Warn "Copy manually to \\DC\NETLOGON\$ScriptName"
|
||||
}
|
||||
}
|
||||
|
||||
# 6. PowerShell profile hook (default, skip with -NoProfile)
|
||||
$profileMarker = "# PasswordExpiryCheck"
|
||||
$profileLine = "& `"$ScriptPath`" -Quiet -WarningDays $WarningDays $profileMarker"
|
||||
|
||||
if (-not $NoProfile) {
|
||||
$allUsersProfile = $PROFILE.AllUsersAllHosts
|
||||
$profileDir = Split-Path $allUsersProfile -Parent
|
||||
|
||||
# Check if hook already exists
|
||||
$hookExists = (Test-Path $allUsersProfile) -and (Select-String -Path $allUsersProfile -Pattern $profileMarker -Quiet)
|
||||
|
||||
if ($hookExists) {
|
||||
Write-Info "PowerShell profile hook already present - updating"
|
||||
if (-not $DryRun) {
|
||||
$content = Get-Content $allUsersProfile | Where-Object { $_ -notmatch $profileMarker }
|
||||
$content += $profileLine
|
||||
Set-Content -Path $allUsersProfile -Value $content
|
||||
}
|
||||
} else {
|
||||
if ($DryRun) {
|
||||
Write-Info "Would add profile hook to $allUsersProfile"
|
||||
} else {
|
||||
if (-not (Test-Path $profileDir)) {
|
||||
New-Item -Path $profileDir -ItemType Directory -Force | Out-Null
|
||||
}
|
||||
Add-Content -Path $allUsersProfile -Value $profileLine
|
||||
}
|
||||
}
|
||||
Write-OK "PowerShell profile hook: $allUsersProfile"
|
||||
} else {
|
||||
Write-Info "Skipping PowerShell profile hook (-NoProfile)"
|
||||
}
|
||||
|
||||
# 7. cmd.exe AutoRun hook (optional, enable with -CmdPrompt)
|
||||
if ($CmdPrompt) {
|
||||
$cmdCommand = '@powershell.exe -NoProfile -ExecutionPolicy Bypass -File "' + $ScriptPath + '" -Quiet -WarningDays ' + $WarningDays
|
||||
$regPath = "HKLM:\Software\Microsoft\Command Processor"
|
||||
|
||||
$existing = Get-ItemProperty -Path $regPath -Name "AutoRun" -ErrorAction SilentlyContinue
|
||||
if ($existing -and $existing.AutoRun -match "password-expiry-check") {
|
||||
Write-Info "cmd.exe AutoRun hook already present - updating"
|
||||
if (-not $DryRun) {
|
||||
$cleaned = ($existing.AutoRun -split '\s*&\s*' | Where-Object { $_ -notmatch 'password-expiry-check' }) -join ' & '
|
||||
if ($cleaned.Trim()) {
|
||||
$newValue = $cleaned.Trim() + " & " + $cmdCommand
|
||||
} else {
|
||||
$newValue = $cmdCommand
|
||||
}
|
||||
Set-ItemProperty -Path $regPath -Name "AutoRun" -Value $newValue
|
||||
}
|
||||
} elseif ($existing -and $existing.AutoRun.Trim()) {
|
||||
if ($DryRun) {
|
||||
Write-Info "Would append to existing cmd.exe AutoRun"
|
||||
} else {
|
||||
$newValue = $existing.AutoRun.Trim() + " & " + $cmdCommand
|
||||
Set-ItemProperty -Path $regPath -Name "AutoRun" -Value $newValue
|
||||
}
|
||||
} else {
|
||||
if ($DryRun) {
|
||||
Write-Info "Would create cmd.exe AutoRun registry key"
|
||||
} else {
|
||||
Set-ItemProperty -Path $regPath -Name "AutoRun" -Value $cmdCommand
|
||||
}
|
||||
}
|
||||
Write-OK "cmd.exe AutoRun hook: $regPath"
|
||||
}
|
||||
|
||||
# ── Summary ───────────────────────────────────────────────────────────
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Deployment summary:" -ForegroundColor White
|
||||
Write-Host " Script: $ScriptPath"
|
||||
Write-Host " Warning: $WarningDays days"
|
||||
Write-Host " Interval task: $TaskName (every ${IntervalHours}h)"
|
||||
Write-Host " Logon task: $logonTaskName (at user logon, 30s delay)"
|
||||
if (-not $NoProfile) {
|
||||
Write-Host " PS profile: $($PROFILE.AllUsersAllHosts) (all users)"
|
||||
}
|
||||
if ($CmdPrompt) {
|
||||
Write-Host " cmd.exe: AutoRun registry hook (HKLM)"
|
||||
}
|
||||
if ($NetlogonCopy) {
|
||||
Write-Host " NETLOGON: $env:LOGONSERVER\NETLOGON\$ScriptName"
|
||||
}
|
||||
Write-Host ""
|
||||
Write-Host "Users will see warnings via:" -ForegroundColor White
|
||||
Write-Host " MessageBox popup every $IntervalHours hours (scheduled task)"
|
||||
Write-Host " MessageBox popup at logon (logon trigger task)"
|
||||
Write-Host " Terminal banner in new PowerShell windows (profile hook)"
|
||||
if ($CmdPrompt) {
|
||||
Write-Host " Terminal banner in new cmd.exe windows (AutoRun hook)"
|
||||
}
|
||||
Write-Host ""
|
||||
Write-Info "Test with: & '$ScriptPath' -Test"
|
||||
Write-Info "Remove with: .\deploy-password-expiry-checker.ps1 -Remove"
|
||||
Reference in New Issue
Block a user