Windows services, Task Scheduler and event logs from PowerShell
Manage the three things Windows administrators touch most: query and restart services, create and inspect scheduled tasks, and search the event logs with Get-WinEvent instead of clicking through Event Viewer.
Drafted with AI from official documentation. Scripts were run in a test environment and repository links verified. Awaiting a human check. Did it work for you? Last edited Outdated?
Services, scheduled tasks and event logs all have graphical tools, but they are slow to click through and impossible to repeat on twenty servers. The PowerShell cmdlets below cover the daily work. Most need an elevated prompt (run as administrator) when they change something; reading is usually allowed for any user.
Services
Get-Service # every service with Status and Name
Get-Service -Name Spooler # one service by short name
Get-Service -DisplayName '*update*' # search by display name
Get-Service | Where-Object Status -eq 'Running'
Get-Service | Where-Object { $_.StartType -eq 'Automatic' -and $_.Status -ne 'Running' } # should be running but is not
To see which account a service runs under, its executable and its description, ask the CIM class behind it:
Get-CimInstance Win32_Service -Filter "Name = 'Spooler'" |
Select-Object Name, State, StartMode, StartName, PathName, Description
Start-Service -Name Spooler
Stop-Service -Name Spooler
Restart-Service -Name Spooler
Set-Service -Name Spooler -StartupType Disabled # Automatic, AutomaticDelayedStart, Manual, Disabled
Set-Service -Name Spooler -StartupType Automatic
Careful: stopping or disabling a service affects everything that depends on it. Check dependants first with Get-Service -Name Spooler -DependentServices. The way back is the opposite verb (Start-Service) or setting the previous startup type again; note it beforehand with Get-Service -Name Spooler | Select-Object StartType.
Services on a remote machine: Get-Service -ComputerName server01 works in Windows PowerShell 5.1. In PowerShell 7 that parameter is gone; use Invoke-Command -ComputerName server01 -ScriptBlock { Get-Service } instead.
Scheduled tasks: look around
Get-ScheduledTask # every task, grouped by folder
Get-ScheduledTask -TaskPath '\' # only the top-level folder (your own tasks)
Get-ScheduledTask -TaskName 'Nightly backup'
Get-ScheduledTask -TaskName 'Nightly backup' | Get-ScheduledTaskInfo # last run, result, next run
Get-ScheduledTask | Where-Object State -eq 'Ready' | Get-ScheduledTaskInfo |
Where-Object LastTaskResult -ne 0 | Select-Object TaskName, LastRunTime, LastTaskResult
LastTaskResult is 0 for success. 267011 (0x41303) means the task has never run; other values are Windows error codes, and 267009 means it is currently running.
Scheduled tasks: create one that runs a script
$action = New-ScheduledTaskAction -Execute 'pwsh.exe' `
-Argument '-NoProfile -ExecutionPolicy Bypass -File C:\Scripts\backup.ps1'
$trigger = New-ScheduledTaskTrigger -Daily -At 3:00AM
$settings = New-ScheduledTaskSettingsSet -StartWhenAvailable -ExecutionTimeLimit (New-TimeSpan -Hours 2)
Register-ScheduledTask -TaskName 'Nightly backup' -Action $action -Trigger $trigger `
-Settings $settings -Description 'Runs backup.ps1 every night' -User 'SYSTEM' -RunLevel Highest
Running as SYSTEM means no password to store and the task runs whether or not anyone is logged in, but the script then has no access to your network drives or user profile. To run under a service account instead, pass -User 'DOMAIN\svc_backup' -Password '...', or build a principal with New-ScheduledTaskPrincipal.
Careful: Register-ScheduledTask creates a task that will keep running your script on schedule until someone removes it. The way back is Unregister-ScheduledTask -TaskName 'Nightly backup' -Confirm:$false. To pause it without deleting, use Disable-ScheduledTask and later Enable-ScheduledTask.
Start-ScheduledTask -TaskName 'Nightly backup' # run it now to test
Disable-ScheduledTask -TaskName 'Nightly backup'
Enable-ScheduledTask -TaskName 'Nightly backup'
Unregister-ScheduledTask -TaskName 'Nightly backup' -Confirm:$false
Other triggers: New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday,Thursday -At 6am, -AtStartup, -AtLogOn, and -Once -At (Get-Date).AddMinutes(5) for a one-off. When a scheduled script fails silently, the usual causes are the execution policy, a relative path, or a drive letter that only exists for your interactive session.
Event logs with Get-WinEvent
Get-WinEvent reads both the classic logs (System, Application, Security) and the hundreds of Applications and Services logs. Get-EventLog still exists in Windows PowerShell 5.1 but was removed from PowerShell 7, so learn the newer one.
Get-WinEvent -ListLog * # every log and how many entries it has
Get-WinEvent -ListLog * | Where-Object RecordCount -gt 0 | Sort-Object RecordCount -Descending | Select-Object -First 10
Get-WinEvent -LogName System -MaxEvents 20 # the newest 20 entries
Get-WinEvent -LogName 'Microsoft-Windows-TaskScheduler/Operational' -MaxEvents 20
For anything more specific, use -FilterHashtable. It filters on the server side and is far faster than piping everything to Where-Object:
# Errors (Level 2) and critical (1) in System during the last 24 hours
Get-WinEvent -FilterHashtable @{
LogName = 'System'
Level = 1, 2
StartTime = (Get-Date).AddDays(-1)
} | Select-Object TimeCreated, Id, ProviderName, Message | Format-Table -Wrap
# Failed logons (event 4625) in the Security log, needs administrator
Get-WinEvent -FilterHashtable @{ LogName = 'Security'; Id = 4625 } -MaxEvents 50
# One provider only
Get-WinEvent -FilterHashtable @{ LogName = 'Application'; ProviderName = 'Application Error' } -MaxEvents 10
# Unexpected shutdowns and crashes
Get-WinEvent -FilterHashtable @{ LogName = 'System'; Id = 41, 1074, 6008 }
Levels: 1 Critical, 2 Error, 3 Warning, 4 Information. If nothing matches, Get-WinEvent reports an error that no events were found; that is expected, not a failure. Export results with Export-Csv or read them on another machine with -ComputerName.
Put it together: a morning check
$since = (Get-Date).AddHours(-12)
Get-Service | Where-Object { $_.StartType -eq 'Automatic' -and $_.Status -ne 'Running' }
Get-ScheduledTask -TaskPath '\' | Get-ScheduledTaskInfo | Where-Object { $_.LastTaskResult -ne 0 -and $_.LastRunTime -gt $since }
Get-WinEvent -FilterHashtable @{ LogName = 'System', 'Application'; Level = 1, 2; StartTime = $since } -ErrorAction SilentlyContinue |
Group-Object ProviderName | Sort-Object Count -Descending | Select-Object Count, Name
Official documentation
- Get-Service and the Microsoft.PowerShell.Management module
- ScheduledTasks module
- Get-WinEvent
Did this work for you?
No votes yet. Be the first.
If it did not work, the report form below tells the editors what went wrong.
See also
- 0396 PowerShell basics: cmdlets, objects and the pipeline PowerShell commands are called cmdlets, they return objects instead of text, and the pipeline passes those objects between them. Once that clicks,… Beginner · Explains an idea · Linux, macOS, Windows Article PowerShell 15 Oct 2026
- 0397 PowerShell cheat sheet The PowerShell cmdlets and patterns you use every day: files, text, processes, services, filtering, exporting, remoting and the operators that trip up… Beginner · Cheat sheet · Linux, macOS, Windows Article PowerShell 15 Oct 2026
- 0398 Install WSL2 and Ubuntu on Windows One command installs the Windows Subsystem for Linux and Ubuntu. Then learn how to pick a distribution, check which WSL version you… Beginner · Step by step · Windows Article Windows administration · WSL 15 Oct 2026
- 0399 Fix: running scripts is disabled on this system (execution policy) PowerShell refuses to run .ps1 files until the execution policy allows it. The usual fix is RemoteSigned for your own user; here… Beginner · Fixes an error · Windows Article PowerShell · Windows administration 15 Oct 2026
- 0400 winget: install and update software from the command line winget is the package manager built into Windows. Search for a program, install it by id, update everything with one command and… Beginner · Step by step · Windows Article Installing languages & tools · Windows administration 15 Oct 2026
- 0402 Fix: WSL2 has no network or DNS does not resolve apt update hangs, ping works by IP but not by name, or nothing reaches the internet from Ubuntu while Windows is fine.… Intermediate · Fixes an error · Windows Article Windows administration · WSL 15 Oct 2026
Repos in the wild
- PowerShell: the cross-platform shell and scripting language PowerShell/PowerShell The open-source PowerShell 7 project from Microsoft: an object-based shell and automation language that runs on Windows, Linux and macOS and is the successor to Windows PowerShell 5.1. GitHub
- Windows Terminal: tabs, panes and profiles for every shell on Windows microsoft/terminal Microsoft's modern terminal for Windows, with tabs, split panes, GPU rendering, Unicode and emoji support and profiles for PowerShell, cmd, WSL distributions and SSH connections. GitHub
History
Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.
- Dominik +6,851 chars