Skip to content

Instantly share code, notes, and snippets.

@smmcdonald
Last active January 15, 2026 01:39
Show Gist options
  • Select an option

  • Save smmcdonald/cab08104e304fc7d11677c5e93176bba to your computer and use it in GitHub Desktop.

Select an option

Save smmcdonald/cab08104e304fc7d11677c5e93176bba to your computer and use it in GitHub Desktop.
This Powershell script closes a series of application windows that are opened on Windows 10 startup. This script was tested and working on Windows 10 Version 22H2. This script is intended to be run from a .cmd (see close_application_window.cmd) file when run as a scheduled task (see Close Applications Opened on Startup.xml) of a Windows user log…
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2026-01-08T12:04:32.2243302</Date>
<Author>YOUR-MACHINE-NAME\YOUR-USERNAME</Author>
<Description>Close Applications Opened on Startup</Description>
<URI>\Microsoft\Windows\Close Applications Opened on Startup</URI>
</RegistrationInfo>
<Triggers>
<LogonTrigger>
<Enabled>true</Enabled>
<Delay>PT10S</Delay>
</LogonTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>YOUR-USER-ID</UserId>
<LogonType>InteractiveToken</LogonType>
<RunLevel>LeastPrivilege</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
<UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT1H</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>C:\Users\%USERPROFILE%\Desktop\close_application_window.cmd</Command>
</Exec>
</Actions>
</Task>
:: Please note this expects your Powershell script to be located on your Desktop. Feel free to change it.
powershell.exe -WindowStyle Hidden -ExecutionPolicy Bypass -File "%USERPROFILE%\Desktop\close_application_windows.ps1"
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class WindowHelper {
[DllImport("user32.dll")]
public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
}
"@
$scriptBlock = {
param($TitleContains, $TimeoutSeconds, $UseHide)
try {
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class WindowHelper {
[DllImport("user32.dll")]
public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
}
"@
} catch {
# Type already added
}
$WM_CLOSE = 0x0010
$SW_HIDE = 0
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
Write-Output "[$TitleContains] Waiting for window..."
# Wait for window to appear
while ($stopwatch.Elapsed.TotalSeconds -lt $TimeoutSeconds) {
$process = Get-Process | Where-Object {
$_.MainWindowTitle -and $_.MainWindowTitle -like "*$TitleContains*"
} | Select-Object -First 1
if ($process) {
Write-Output "[$TitleContains] Found: '$($process.MainWindowTitle)' (PID: $($process.Id), Handle: $($process.MainWindowHandle))"
Start-Sleep -Milliseconds 500
# Close/Hide the window
$processes = Get-Process | Where-Object {
$_.MainWindowTitle -and $_.MainWindowTitle -like "*$TitleContains*"
}
foreach ($proc in $processes) {
$handle = $proc.MainWindowHandle
if ($handle -ne 0) {
if ($UseHide) {
Write-Output "[$TitleContains] Hiding window (Handle: $handle)"
$result = [WindowHelper]::ShowWindow($handle, $SW_HIDE)
Write-Output "[$TitleContains] Hide result: $result"
} else {
Write-Output "[$TitleContains] Closing window (Handle: $handle)"
$result = [WindowHelper]::PostMessage($handle, $WM_CLOSE, [IntPtr]::Zero, [IntPtr]::Zero)
Write-Output "[$TitleContains] Close result: $result"
}
}
}
$stopwatch.Stop()
Write-Output "[$TitleContains] Completed in $([int]$stopwatch.Elapsed.TotalSeconds) seconds"
return
}
Start-Sleep -Seconds 2
}
$stopwatch.Stop()
Write-Output "[$TitleContains] Timeout after $([int]$stopwatch.Elapsed.TotalSeconds) seconds - window not found"
}
# Main script
Write-Host "=== Starting Window Closer (Async Mode) ===" -ForegroundColor Cyan
Write-Host ""
# Start all jobs simultaneously
$jobs = @()
$jobs += Start-Job -ScriptBlock $scriptBlock -ArgumentList "Logitech Gaming Software", 120, $false
$jobs += Start-Job -ScriptBlock $scriptBlock -ArgumentList "Intel", 120, $false
$jobs += Start-Job -ScriptBlock $scriptBlock -ArgumentList "Razer Synapse", 120, $false
Write-Host "Started $($jobs.Count) parallel jobs" -ForegroundColor Cyan
Write-Host "Monitoring progress..." -ForegroundColor Cyan
Write-Host ""
# Monitor jobs in real-time
$completed = @()
while ($completed.Count -lt $jobs.Count) {
foreach ($job in $jobs) {
if ($job.State -eq 'Completed' -and $completed -notcontains $job.Id) {
# Get and display output
$output = Receive-Job -Job $job
$output | ForEach-Object { Write-Host $_ }
$completed += $job.Id
Remove-Job -Job $job
}
elseif ($job.State -eq 'Failed') {
Write-Host "Job failed: $($job.Name)" -ForegroundColor Red
$completed += $job.Id
Remove-Job -Job $job
}
}
if ($completed.Count -lt $jobs.Count) {
Start-Sleep -Milliseconds 500
}
}
Write-Host ""
Write-Host "Script completed." -ForegroundColor Green
# List all windows with titles. Useful for finding the real name of application windows which may differ from the process name or window title.
Write-Host "=== All Open Windows ===" -ForegroundColor Green
Write-Host ""
Get-Process |
Where-Object {$_.MainWindowTitle} |
Select-Object Id, ProcessName, MainWindowTitle |
Format-Table -AutoSize |
Out-String |
Tee-Object -FilePath "$env:USERPROFILE\Desktop\window_titles.txt"
Write-Host ""
Write-Host "Output also saved to Desktop\window_titles.txt" -ForegroundColor Yellow
Write-Host ""
Write-Host "Press any key to exit..."
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment