PowerShell System Administration
System administration and maintenance tasks.
System Information
Quick system overview
Get-ComputerInfo | Select-Object CsName, OsName, OsArchitecture, CsProcessors, CsTotalPhysicalMemory, WindowsVersion
CPU info
Get-CimInstance Win32_Processor | Select-Object Name, NumberOfCores, NumberOfLogicalProcessors, MaxClockSpeed
Memory info
$os = Get-CimInstance Win32_OperatingSystem
[PSCustomObject]@{
TotalGB = [math]::Round($os.TotalVisibleMemorySize / 1MB, 2)
FreeGB = [math]::Round($os.FreePhysicalMemory / 1MB, 2)
UsedGB = [math]::Round(($os.TotalVisibleMemorySize - $os.FreePhysicalMemory) / 1MB, 2)
Used_Pct = [math]::Round((($os.TotalVisibleMemorySize - $os.FreePhysicalMemory) / $os.TotalVisibleMemorySize) * 100, 1)
}
Disk space
Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" |
Select-Object DeviceID,
@{N='SizeGB';E={[math]::Round($_.Size/1GB,2)}},
@{N='FreeGB';E={[math]::Round($_.FreeSpace/1GB,2)}},
@{N='Free%';E={[math]::Round($_.FreeSpace/$_.Size*100,1)}}
Physical disks
Get-PhysicalDisk | Select-Object FriendlyName, MediaType, Size, HealthStatus
Battery status (laptops)
Get-CimInstance Win32_Battery | Select-Object Name, EstimatedChargeRemaining,
@{N='Status';E={
switch ($_.BatteryStatus) {
1 {"Discharging"}
2 {"AC Power"}
3 {"Fully Charged"}
default {"Unknown"}
}
}}
Uptime
$boot = (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
$uptime = (Get-Date) - $boot
Write-Host "Uptime: $($uptime.Days)d $($uptime.Hours)h $($uptime.Minutes)m"
BIOS info
Get-CimInstance Win32_BIOS | Select-Object Manufacturer, Name, Version, SerialNumber
GPU info
Get-CimInstance Win32_VideoController | Select-Object Name, AdapterRAM, DriverVersion, CurrentRefreshRate
Full system report
systeminfo | Out-File "$env:TEMP\systeminfo.txt"
Power Management
Get current power plan
powercfg /getactivescheme
List all power plans
powercfg /list
Set power plan (balanced)
powercfg /setactive SCHEME_BALANCED
Set high performance
powercfg /setactive SCHEME_MIN
Set power saver
powercfg /setactive SCHEME_MAX
Set display timeout (AC)
powercfg /change monitor-timeout-ac 15
powercfg /change monitor-timeout-dc 5
Set sleep timeout
powercfg /change standby-timeout-ac 30
powercfg /change standby-timeout-dc 10
Disable sleep
powercfg /change standby-timeout-ac 0
Disable hibernate
powercfg /hibernate off
Enable hibernate
powercfg /hibernate on
Generate battery report (laptops)
powercfg /batteryreport /output "$env:TEMP\battery-report.html"
Start-Process "$env:TEMP\battery-report.html"
Check what’s preventing sleep
powercfg /requests
Lock workstation
rundll32.exe user32.dll,LockWorkStation
Shutdown
Stop-Computer -Force
Restart
Restart-Computer -Force
Scheduled shutdown in 1 hour
shutdown /s /t 3600 /c "Scheduled shutdown in 1 hour"
Cancel scheduled shutdown
shutdown /a
Sleep (programmatic)
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::SetSuspendState("Suspend", $false, $false)
Hibernate (programmatic)
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::SetSuspendState("Hibernate", $false, $false)
Display Settings
Get current resolution
Get-CimInstance -ClassName Win32_VideoController |
Select-Object Name, CurrentHorizontalResolution, CurrentVerticalResolution, CurrentRefreshRate
Open display settings
Start-Process "ms-settings:display"
Enable dark mode (apps)
Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" -Name "AppsUseLightTheme" -Value 0
Enable dark mode (system)
Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" -Name "SystemUsesLightTheme" -Value 0
Enable light mode (both)
Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" -Name "AppsUseLightTheme" -Value 1
Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" -Name "SystemUsesLightTheme" -Value 1
Set wallpaper
Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "Wallpaper" -Value "C:\Path\To\Image.jpg"
rundll32.exe user32.dll, UpdatePerUserSystemParameters
Get current wallpaper
(Get-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name Wallpaper).Wallpaper
Audio Settings
Get audio devices (requires module)
# Install-Module AudioDeviceCmdlets
Get-AudioDevice -List
Set volume (0-100)
Set-AudioDevice -PlaybackVolume 50
Mute
Set-AudioDevice -PlaybackMute $true
Unmute
Set-AudioDevice -PlaybackMute $false
Open sound settings
Start-Process "ms-settings:sound"
Open sound control panel
Start-Process "mmsys.cpl"
Open volume mixer
Start-Process "sndvol.exe"
Services Management
List all services sorted by status
Get-Service | Sort-Object Status, Name
Get running services
Get-Service | Where-Object Status -eq 'Running' | Select-Object Name, DisplayName, StartType
Get stopped auto-start services (problems)
Get-Service | Where-Object { $_.StartType -eq 'Automatic' -and $_.Status -ne 'Running' } |
Select-Object Name, DisplayName, Status
Find service by name (wildcards)
Get-Service -Name "*ssh*"
Get-Service -DisplayName "*Remote Desktop*"
Start service
Start-Service -Name "ssh-agent"
Stop service
Stop-Service -Name "ssh-agent" -Force
Restart service
Restart-Service -Name "Spooler"
Change startup type
Set-Service -Name "ssh-agent" -StartupType Automatic
Set-Service -Name "DiagTrack" -StartupType Disabled
Get service dependencies
Get-Service -Name "LanmanWorkstation" | Select-Object -ExpandProperty DependentServices
Get-Service -Name "LanmanWorkstation" | Select-Object -ExpandProperty ServicesDependedOn
Get service with process ID
Get-CimInstance Win32_Service | Where-Object State -eq 'Running' |
Select-Object Name, ProcessId, StartMode
Get service account (non-default)
Get-CimInstance Win32_Service | Select-Object Name, StartName |
Where-Object StartName -notmatch 'LocalSystem|LocalService|NetworkService'
Change service account
sc.exe config "ServiceName" obj= ".\LocalAdmin" password= "P@ssw0rd"
Get service recovery options
sc.exe qfailure "Spooler"
Set service recovery (restart on failure)
sc.exe failure "MyService" reset= 86400 actions= restart/60000/restart/60000/restart/60000
Create new service
New-Service -Name "MyService" -BinaryPathName "C:\Apps\myapp.exe" -DisplayName "My Service" -StartupType Automatic -Description "My custom service"
Remove service
Remove-Service -Name "MyService"
Remove service (older Windows)
sc.exe delete "MyService"
Process Management
List top processes by CPU
Get-Process | Sort-Object CPU -Descending | Select-Object -First 20 Name, Id, CPU,
@{N='MemMB';E={[math]::Round($_.WorkingSet64/1MB,2)}}
Find process by name
Get-Process -Name "*chrome*"
Get-Process -Name "Teams","Outlook","msedge"
Get process with command line
Get-CimInstance Win32_Process | Select-Object ProcessId, Name, CommandLine |
Where-Object Name -eq "powershell.exe"
Get process owner
Get-CimInstance Win32_Process | ForEach-Object {
$owner = Invoke-CimMethod -InputObject $_ -MethodName GetOwner
[PSCustomObject]@{
Name = $_.Name
PID = $_.ProcessId
User = "$($owner.Domain)\$($owner.User)"
}
} | Where-Object User -notmatch 'SYSTEM|NETWORK'
Start process
Start-Process notepad
Start-Process "C:\Program Files\MyApp\app.exe"
Open URL in default browser
Start-Process "https://google.com"
Start process with arguments
Start-Process -FilePath "cmd.exe" -ArgumentList "/c dir C:\" -NoNewWindow -Wait
Start process as admin
Start-Process powershell -Verb RunAs
Start process hidden
Start-Process -FilePath "script.ps1" -WindowStyle Hidden
Stop process by name
Stop-Process -Name "notepad"
Stop process by ID
Stop-Process -Id 1234 -Force
Kill all instances of process
Get-Process -Name "chrome" | Stop-Process -Force
Start process and wait for exit
Start-Process notepad -PassThru | Wait-Process
Monitor specific process
$proc = "Teams"
while ($true) {
$p = Get-Process -Name $proc -ErrorAction SilentlyContinue
if ($p) {
Write-Host "$(Get-Date -Format 'HH:mm:ss') - $proc - CPU: $([math]::Round($p.CPU,2)) - Mem: $([math]::Round($p.WorkingSet64/1MB,2))MB"
}
Start-Sleep -Seconds 5
}
Scheduled Tasks
List all scheduled tasks
Get-ScheduledTask | Select-Object TaskName, State, TaskPath
Get task details
Get-ScheduledTask -TaskName "MyTask" | Get-ScheduledTaskInfo
Get running tasks
Get-ScheduledTask | Where-Object State -eq 'Running'
Create daily scheduled task at 3am
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-File C:\Scripts\backup.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At 3am
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -TaskName "DailyBackup" -Action $action -Trigger $trigger -Principal $principal -Description "Daily backup script"
Create task at logon
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-File C:\Scripts\startup.ps1"
$trigger = New-ScheduledTaskTrigger -AtLogon
Register-ScheduledTask -TaskName "StartupScript" -Action $action -Trigger $trigger
Create task at system startup
$trigger = New-ScheduledTaskTrigger -AtStartup
Run task immediately
Start-ScheduledTask -TaskName "DailyBackup"
Stop running task
Stop-ScheduledTask -TaskName "DailyBackup"
Disable task
Disable-ScheduledTask -TaskName "DailyBackup"
Enable task
Enable-ScheduledTask -TaskName "DailyBackup"
Export task XML
Export-ScheduledTask -TaskName "DailyBackup" | Out-File "C:\Backup\task-backup.xml"
Import task from XML
Register-ScheduledTask -TaskName "ImportedTask" -Xml (Get-Content "C:\Backup\task-backup.xml" -Raw)
Delete task
Unregister-ScheduledTask -TaskName "OldTask" -Confirm:$false
Get task history
Get-WinEvent -FilterHashtable @{
LogName = 'Microsoft-Windows-TaskScheduler/Operational'
Id = 201
} -MaxEvents 20 | Select-Object TimeCreated, Message
Winget Package Manager
Search for packages
winget search vscode
winget search --name "Visual Studio Code"
Show package info
winget show Microsoft.VisualStudioCode
Install package
winget install Microsoft.VisualStudioCode
Install package with exact ID
winget install --id Microsoft.PowerShell -e
Install silently
winget install --id Microsoft.VisualStudioCode -e --silent
Install specific version
winget install --id Git.Git -v 2.40.0
List installed packages
winget list
Check for upgrades
winget upgrade
Upgrade specific package
winget upgrade Microsoft.VisualStudioCode
Upgrade all packages
winget upgrade --all
Uninstall package
winget uninstall Microsoft.VisualStudioCode
Export installed packages
winget export -o packages.json
Import packages on new machine
winget import -i packages.json
Batch install dev packages
$devPackages = @(
"Microsoft.VisualStudioCode"
"Microsoft.PowerShell"
"Microsoft.WindowsTerminal"
"Git.Git"
"Python.Python.3.11"
"OpenJS.NodeJS"
"Docker.DockerDesktop"
)
foreach ($pkg in $devPackages) {
winget install --id $pkg -e --silent --accept-package-agreements
}
Pin app (prevent auto-upgrade)
winget pin add Microsoft.Edge
View pins
winget pin list
Remove pin
winget pin remove Microsoft.Edge
Installed Applications
Get installed programs from registry
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Where-Object DisplayName | Sort-Object DisplayName
Get all installed programs (32+64 bit)
$apps = @()
$apps += Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*
$apps += Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*
$apps | Where-Object DisplayName |
Select-Object DisplayName, DisplayVersion, Publisher |
Sort-Object DisplayName -Unique
Get Windows Store apps
Get-AppxPackage | Select-Object Name, Version, PackageFullName
Remove Store app
Remove-AppxPackage -Package "Microsoft.XboxApp_1.0.0.0_x64__8wekyb3d8bbwe"
Remove bloatware
Get-AppxPackage *xbox* | Remove-AppxPackage
Get-AppxPackage *bing* | Remove-AppxPackage
Get-AppxPackage *candy* | Remove-AppxPackage
Get enabled Windows features
Get-WindowsOptionalFeature -Online | Where-Object State -eq 'Enabled' | Select-Object FeatureName
Enable Windows feature
Enable-WindowsOptionalFeature -Online -FeatureName "Microsoft-Hyper-V-All" -NoRestart
Disable Windows feature
Disable-WindowsOptionalFeature -Online -FeatureName "WindowsMediaPlayer"
WSL status
wsl --list --verbose
wsl --status
Install WSL
wsl --install
Set default WSL distro
wsl --set-default Arch
Application Control (Teams, Outlook, Browser)
Check if apps are running
Get-Process -Name "Teams","Outlook","msedge" -ErrorAction SilentlyContinue |
Select-Object Name, Id, StartTime, @{N='MemMB';E={[math]::Round($_.WorkingSet64/1MB,2)}}
Start Teams
Start-Process "ms-teams:"
Start Outlook
Start-Process "outlook.exe"
Start Edge with URL
Start-Process "msedge.exe" "https://outlook.office.com"
Start Teams minimized
Start-Process "ms-teams:" -WindowStyle Minimized
Open Outlook calendar
Start-Process "outlook.exe" "/select outlook:calendar"
Open Outlook inbox
Start-Process "outlook.exe" "/select outlook:inbox"
Compose new email
Start-Process "outlook.exe" "/c ipm.note /m user@domain.com?subject=Hello&body=Message"
Start Edge with profile
Start-Process "msedge.exe" "--profile-directory=`"Profile 1`""
Start Edge InPrivate
Start-Process "msedge.exe" "-inprivate https://google.com"
Start Chrome incognito
Start-Process "chrome.exe" "--incognito https://google.com"
Close all Teams instances
Get-Process -Name "Teams" -ErrorAction SilentlyContinue | Stop-Process -Force
Open Teams chat with person
Start-Process "msteams://l/chat/0/0?users=user@domain.com"
Clipboard Operations
Get clipboard content
Get-Clipboard
Set clipboard
Set-Clipboard -Value "Hello World"
Copy command output to clipboard
Get-Process | Set-Clipboard
Copy file paths to clipboard
Get-ChildItem *.ps1 | Select-Object -ExpandProperty FullName | Set-Clipboard
Clear clipboard
Set-Clipboard -Value $null
Windows Update
Install PSWindowsUpdate module
Install-Module PSWindowsUpdate -Force
Check for updates
Import-Module PSWindowsUpdate
Get-WindowsUpdate
List available updates with details
Get-WindowsUpdate | Select-Object KB, Title, Size, MsrcSeverity
Download updates only
Get-WindowsUpdate -Download
Install all updates with auto-reboot
Install-WindowsUpdate -AcceptAll -AutoReboot
Install specific update
Install-WindowsUpdate -KBArticleID "KB5001234"
Install updates without reboot
Install-WindowsUpdate -AcceptAll -IgnoreReboot
Get update history
Get-WUHistory | Select-Object -First 20 Date, Title, Result
View installed updates (native)
Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 20 HotFixID, Description, InstalledOn
Check if reboot is pending
$rebootRequired = Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired"
Write-Host "Reboot Required: $rebootRequired"
Comprehensive pending reboot check
function Test-PendingReboot {
$paths = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired"
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending"
"HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations"
)
foreach ($path in $paths) {
if (Test-Path $path) { return $true }
}
return $false
}
Test-PendingReboot
Pause updates for 7 days
$date = (Get-Date).AddDays(7).ToString("yyyy-MM-dd")
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -Name "PauseUpdatesExpiryTime" -Value $date
Get Windows version info
Get-ComputerInfo | Select-Object WindowsVersion, WindowsBuildLabEx, OsArchitecture
Event Logs
Get recent System events
Get-WinEvent -LogName System -MaxEvents 50 | Select-Object TimeCreated, LevelDisplayName, Id, Message
Get errors and warnings
Get-WinEvent -LogName System -MaxEvents 100 |
Where-Object LevelDisplayName -match "Error|Warning" |
Select-Object TimeCreated, LevelDisplayName, ProviderName, Message
Filter by event ID
Get-WinEvent -FilterHashtable @{
LogName = 'System'
Id = 6005, 6006
} | Select-Object TimeCreated, Id, Message
Filter by time range (last 24h)
Get-WinEvent -FilterHashtable @{
LogName = 'System'
StartTime = (Get-Date).AddHours(-24)
} | Select-Object TimeCreated, LevelDisplayName, Message
Security log login events
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4624, 4625
} -MaxEvents 20 | Select-Object TimeCreated, Id, Message
Get last BSOD info
Get-WinEvent -LogName System | Where-Object Id -eq 41 | Select-Object -First 1 TimeCreated, Message
Export event log
Get-WinEvent -LogName System -MaxEvents 1000 | Export-Csv "$env:TEMP\system-events.csv" -NoTypeInformation
Get Application log errors
Get-WinEvent -FilterHashtable @{
LogName = 'Application'
Level = 2
} -MaxEvents 50 | Select-Object TimeCreated, ProviderName, Message
Search for specific text in events
Get-WinEvent -LogName System -MaxEvents 500 |
Where-Object { $_.Message -match "disk|error" } |
Select-Object TimeCreated, Id, Message
Get PowerShell script block logging
Get-WinEvent -FilterHashtable @{
LogName = 'Microsoft-Windows-PowerShell/Operational'
Id = 4104
} -MaxEvents 20 | Select-Object TimeCreated, Message
List available event logs
Get-WinEvent -ListLog * | Where-Object RecordCount -gt 0 | Sort-Object RecordCount -Descending | Select-Object LogName, RecordCount
Clear event log (Admin)
Clear-EventLog -LogName "Application"
Quick Settings Shortcuts
Open Settings app
Start-Process "ms-settings:"
System settings
Start-Process "ms-settings:display"
Sound settings
Start-Process "ms-settings:sound"
Notifications settings
Start-Process "ms-settings:notifications"
Power & sleep settings
Start-Process "ms-settings:powersleep"
About settings
Start-Process "ms-settings:about"
Network settings
Start-Process "ms-settings:network"
WiFi settings
Start-Process "ms-settings:network-wifi"
Ethernet settings
Start-Process "ms-settings:network-ethernet"
VPN settings
Start-Process "ms-settings:network-vpn"
Apps & features
Start-Process "ms-settings:appsfeatures"
Default apps
Start-Process "ms-settings:defaultapps"
Startup apps
Start-Process "ms-settings:startup"
Privacy settings
Start-Process "ms-settings:privacy"
Location privacy
Start-Process "ms-settings:privacy-location"
Microphone privacy
Start-Process "ms-settings:privacy-microphone"
Windows Update
Start-Process "ms-settings:windowsupdate"
Windows Security (Defender)
Start-Process "ms-settings:windowsdefender"
Bluetooth settings
Start-Process "ms-settings:bluetooth"
Printers settings
Start-Process "ms-settings:printers"
Storage settings
Start-Process "ms-settings:storagesense"
Date & time
Start-Process "ms-settings:dateandtime"
Region & language
Start-Process "ms-settings:regionlanguage"
Personalization (themes)
Start-Process "ms-settings:personalization"
Control Panel shortcuts - Network Connections
Start-Process "ncpa.cpl"
Control Panel shortcuts - Programs and Features
Start-Process "appwiz.cpl"
Control Panel shortcuts - System Properties
Start-Process "sysdm.cpl"
Control Panel shortcuts - Device Manager
Start-Process "devmgmt.msc"
Control Panel shortcuts - Disk Management
Start-Process "diskmgmt.msc"
Control Panel shortcuts - Services
Start-Process "services.msc"
Control Panel shortcuts - Task Scheduler
Start-Process "taskschd.msc"
Control Panel shortcuts - Event Viewer
Start-Process "eventvwr.msc"
Control Panel shortcuts - Group Policy (Pro)
Start-Process "gpedit.msc"
Control Panel shortcuts - Registry Editor
Start-Process "regedit"
Open system folders - Temp
Start-Process $env:TEMP
Open system folders - AppData
Start-Process $env:APPDATA
Open system folders - Startup
Start-Process "shell:startup"
Open system folders - Downloads
Start-Process "shell:downloads"
Common Gotchas
GOTCHA: WiFi needs netsh (no native PS cmdlet)
# WRONG: Get-WiFiProfile doesn't exist
# CORRECT: Use netsh
netsh wlan show profiles
GOTCHA: Get-Service doesn’t show all services
# Use CIM for complete list
Get-CimInstance Win32_Service | Measure-Object
GOTCHA: Start-Process doesn’t wait by default
# WRONG: Continues immediately
Start-Process notepad
Write-Host "Done"
# CORRECT: Wait for exit
Start-Process notepad -Wait
GOTCHA: Admin commands need elevated shell
# Run admin command from non-elevated shell
Start-Process powershell -Verb RunAs -ArgumentList "-Command Restart-Service Spooler"
GOTCHA: Adapter status comparison
# CORRECT: Use proper enum
Get-NetAdapter | Where-Object Status -eq 'Up'
Get-NetAdapter | Where-Object MediaConnectionState -eq 'Connected'
GOTCHA: winget encoding in PS 5.1
# Fix encoding for winget
[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()
GOTCHA: Certificate private key access
# Machine cert private keys need admin
# User cert private keys accessible by user
GOTCHA: Cert:\LocalMachine requires admin
# Reading works, writing requires admin
Get-ChildItem Cert:\LocalMachine\My # OK as user
Import-Certificate -CertStoreLocation Cert:\LocalMachine\Root # Needs admin