How to Use Get-Process and Stop-Process in PowerShell

PowerShell: use Get-Process to list running processes and retrieve Id/Name; use Stop-Process -Id <id> or -Name <name> to terminate processes (may require admin), confirm first. FYI

How to Use Get-Process and Stop-Process in PowerShell
SPONSORED

Sponsor message — This article is made possible by Dargslan.com, a publisher of practical, no-fluff IT & developer workbooks.

Why Dargslan.com?

If you prefer doing over endless theory, Dargslan’s titles are built for you. Every workbook focuses on skills you can apply the same day—server hardening, Linux one-liners, PowerShell for admins, Python automation, cloud basics, and more.


Process management stands as one of the fundamental pillars of system administration, directly impacting system performance, security, and stability. Whether you're troubleshooting a frozen application, investigating unusual resource consumption, or maintaining a healthy server environment, understanding how to monitor and control processes becomes essential. Every running program, service, and background task represents a process that consumes system resources, and knowing how to interact with these processes empowers you to maintain control over your computing environment.

PowerShell's Get-Process and Stop-Process cmdlets provide a powerful, flexible approach to process management that goes far beyond clicking "End Task" in Task Manager. Get-Process retrieves detailed information about processes running on local or remote computers, while Stop-Process terminates those processes when necessary. Together, these cmdlets form a comprehensive toolkit that enables administrators and power users to automate process monitoring, implement sophisticated filtering logic, and execute bulk operations that would be tedious or impossible through graphical interfaces.

This guide will walk you through everything you need to know about these essential PowerShell cmdlets. You'll discover how to retrieve process information in various formats, filter results to find exactly what you're looking for, terminate problematic processes safely, and combine these cmdlets with other PowerShell features to create powerful automation scripts. Whether you're a system administrator managing dozens of servers or a developer optimizing your local development environment, mastering these tools will significantly enhance your productivity and troubleshooting capabilities.

Understanding the Get-Process Cmdlet

The Get-Process cmdlet serves as your window into all running processes on a system. When executed without parameters, it returns a comprehensive list of every process currently running, including system processes, user applications, and background services. Each process object contains rich information including the process ID (PID), CPU usage, memory consumption, and the process name.

At its most basic level, you can execute Get-Process by simply typing the command:

Get-Process

This returns a default view showing the most commonly needed properties. However, the real power of Get-Process emerges when you start using its parameters and combining it with other PowerShell features. The cmdlet supports numerous parameters that allow you to filter, sort, and format the output according to your specific needs.

Key Properties of Process Objects

Each process object returned by Get-Process contains dozens of properties that provide detailed insights into the process's behavior and resource consumption. Understanding these properties helps you make informed decisions about which processes to monitor or terminate.

Property Description Use Case
Id The unique Process ID (PID) assigned by the operating system Essential for targeting specific process instances when multiple processes share the same name
ProcessName The name of the process executable without the .exe extension Used for filtering and identifying processes by their application name
CPU Total processor time used by the process in seconds Identifying CPU-intensive processes that may be causing performance issues
WorkingSet Amount of physical memory currently allocated to the process (in bytes) Monitoring memory consumption and identifying memory leaks
Handles Number of handles the process has opened to system resources Detecting handle leaks that can cause system instability
StartTime When the process was started Identifying long-running processes or determining process uptime
Path Full path to the process executable Verifying process legitimacy and location for security purposes

Filtering Processes by Name

Rather than viewing all processes, you'll often want to examine specific applications or services. The -Name parameter allows you to filter processes by their name. You can specify a single process name or use wildcards for pattern matching:

Get-Process -Name chrome
Get-Process -Name *sql*
Get-Process -Name notepad, powershell, code

The wildcard approach proves particularly useful when you're searching for related processes or when you're unsure of the exact process name. The third example demonstrates how you can retrieve multiple specific processes in a single command by providing a comma-separated list.

"Understanding process identification is crucial because many applications spawn multiple processes, and terminating the wrong one can lead to data loss or system instability."

Retrieving Processes by ID

When you need absolute precision, using the Process ID (PID) ensures you're targeting exactly the right process instance. This becomes critical when multiple instances of the same application are running, such as several browser windows or multiple PowerShell sessions:

Get-Process -Id 1234
Get-Process -Id 1234, 5678, 9012

The PID remains unique throughout the process's lifetime, making it the most reliable identifier. However, PIDs are reassigned after a process terminates, so they're not suitable for long-term process tracking across system reboots.

Accessing Additional Process Properties

The default output of Get-Process shows only a subset of available properties. To access the complete set of information, you can pipe the output to Select-Object or Format-List:

Get-Process -Name chrome | Select-Object *
Get-Process -Name chrome | Format-List *

This reveals properties like Threads, Modules, MainWindowTitle, and Company, which can be invaluable for detailed analysis. For example, the MainWindowTitle property helps you distinguish between multiple browser windows by showing their page titles.

Advanced Get-Process Techniques

Moving beyond basic process retrieval, PowerShell provides sophisticated capabilities for analyzing, sorting, and filtering process information. These advanced techniques enable you to create powerful monitoring solutions and troubleshooting scripts.

Sorting and Measuring Resource Consumption

Identifying resource-hungry processes often requires sorting by CPU time or memory usage. PowerShell's pipeline architecture makes this straightforward:

# Top 10 processes by CPU usage
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10

# Top 10 processes by memory consumption
Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First 10

# Processes using more than 100MB of memory
Get-Process | Where-Object {$_.WorkingSet -gt 100MB}

These commands provide immediate insights into which processes are consuming the most resources. The WorkingSet property represents physical memory usage, while VirtualMemorySize shows the total virtual address space allocated to the process.

"Memory leaks and runaway processes are among the most common causes of system degradation, and being able to quickly identify the culprits saves countless hours of troubleshooting."

Calculating Total Resource Usage

Sometimes you need aggregate statistics rather than individual process details. The Measure-Object cmdlet provides this capability:

# Total memory used by all Chrome processes
Get-Process -Name chrome | Measure-Object WorkingSet -Sum

# Average CPU time across all processes
Get-Process | Measure-Object CPU -Average

# Count of processes by name
Get-Process | Group-Object ProcessName | Sort-Object Count -Descending

These aggregation techniques prove especially useful when monitoring application behavior over time or comparing resource consumption across different systems.

Monitoring Process Performance Over Time

For ongoing monitoring, you can create loops that repeatedly sample process information:

while ($true) {
    Clear-Host
    Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 | Format-Table
    Start-Sleep -Seconds 5
}

This creates a simple performance monitor that refreshes every five seconds, always showing the top CPU consumers. For production monitoring, you'd typically log this information to files or send it to monitoring systems rather than displaying it on screen.

Querying Remote Computers

Get-Process includes a -ComputerName parameter that enables remote process querying, though it requires appropriate permissions and network connectivity:

Get-Process -ComputerName SERVER01, SERVER02 -Name sqlservr
Get-Process -ComputerName (Get-Content servers.txt) | Where-Object {$_.CPU -gt 100}

This remote capability allows centralized monitoring of multiple systems, essential for enterprise environments. However, for more robust remote management, consider using PowerShell Remoting with Invoke-Command instead, as it provides better error handling and credential management.

Mastering the Stop-Process Cmdlet

While Get-Process provides information, Stop-Process takes action by terminating running processes. This powerful cmdlet must be used judiciously, as forcefully terminating processes can lead to data loss, corruption, or system instability if not handled properly.

The Stop-Process cmdlet accepts several parameters that determine how processes are identified and terminated. Understanding these parameters and their implications ensures you can safely and effectively manage problematic processes.

Basic Process Termination

The simplest form of Stop-Process targets a process by name or ID:

Stop-Process -Name notepad
Stop-Process -Id 1234

By default, Stop-Process terminates processes forcefully without giving them an opportunity to save data or perform cleanup operations. This immediate termination resembles using Task Manager's "End Task" function and should be reserved for unresponsive applications or processes that refuse to close normally.

"Always attempt graceful application closure through normal means before resorting to Stop-Process, especially for applications that maintain open files or database connections."

Handling Multiple Process Instances

When multiple instances of an application are running, Stop-Process will terminate all instances matching the specified name unless you use the -Id parameter for precision:

# Terminates ALL Chrome processes
Stop-Process -Name chrome

# Terminates only the specified Chrome instance
Stop-Process -Id 5678

# Terminates multiple specific instances
Stop-Process -Id 1234, 5678, 9012

This behavior requires careful consideration. Terminating all Chrome processes, for example, closes every open browser window and tab, potentially causing data loss if users have unsaved work in web applications.

Using Confirmation and WhatIf Parameters

PowerShell provides safety mechanisms to prevent accidental process termination. The -Confirm parameter prompts for confirmation before each termination, while -WhatIf shows what would happen without actually terminating anything:

Stop-Process -Name notepad -Confirm
Stop-Process -Name chrome -WhatIf

These parameters prove invaluable when testing scripts or performing operations that might affect multiple processes. The WhatIf parameter is particularly useful during script development, allowing you to verify your filtering logic before executing potentially destructive operations.

Forcing Process Termination

Some processes resist normal termination attempts, especially system services or applications with elevated privileges. The -Force parameter overrides these protections:

Stop-Process -Name problematic_app -Force

Use the Force parameter cautiously, as it bypasses normal shutdown procedures and can cause data corruption or system instability. Reserve it for situations where a process is truly unresponsive and cannot be terminated through normal means.

Combining Get-Process and Stop-Process

The true power of these cmdlets emerges when you combine them through PowerShell's pipeline. This enables sophisticated filtering and conditional process termination based on various criteria.

Terminating Processes Based on Resource Consumption

You can create intelligent process management scripts that terminate processes exceeding specific resource thresholds:

# Stop processes using more than 1GB of memory
Get-Process | Where-Object {$_.WorkingSet -gt 1GB} | Stop-Process -Force

# Stop processes running for more than 24 hours
Get-Process | Where-Object {$_.StartTime -lt (Get-Date).AddHours(-24)} | Stop-Process

# Stop non-responsive processes
Get-Process | Where-Object {$_.Responding -eq $false} | Stop-Process

These examples demonstrate how filtering criteria can target specific problematic behaviors rather than simply terminating by name. The Responding property is particularly useful for identifying frozen applications that require termination.

"Automated process management based on resource thresholds can prevent small issues from escalating into system-wide performance problems, but always include appropriate logging and alerting."

Selective Process Termination with Exclusions

Sometimes you need to terminate most instances of a process while preserving specific ones. PowerShell's filtering capabilities make this possible:

# Stop all Chrome processes except those started in the last 5 minutes
Get-Process -Name chrome | Where-Object {$_.StartTime -lt (Get-Date).AddMinutes(-5)} | Stop-Process

# Stop all PowerShell processes except the current session
Get-Process -Name powershell | Where-Object {$_.Id -ne $PID} | Stop-Process

The $PID automatic variable contains the Process ID of the current PowerShell session, preventing you from accidentally terminating your own session. This self-preservation logic is essential in automated scripts.

Graceful Termination with CloseMainWindow

For GUI applications, you can attempt graceful closure before resorting to forced termination. The CloseMainWindow() method sends a close message to the application's main window:

$process = Get-Process -Name notepad
$process.CloseMainWindow()
Start-Sleep -Seconds 5

# Force termination if still running
if (Get-Process -Id $process.Id -ErrorAction SilentlyContinue) {
    Stop-Process -Id $process.Id -Force
}

This approach gives the application an opportunity to prompt users to save work and perform cleanup operations. The timeout and forced termination provide a fallback for unresponsive applications.

Error Handling and Best Practices

Professional process management requires robust error handling to deal with processes that don't exist, insufficient permissions, and other common failure scenarios. PowerShell provides several mechanisms for graceful error management.

Using ErrorAction Parameter

The -ErrorAction parameter controls how cmdlets respond to errors. Common values include SilentlyContinue (suppress errors), Continue (display errors but continue), and Stop (treat errors as terminating exceptions):

# Suppress errors if process doesn't exist
Get-Process -Name nonexistent -ErrorAction SilentlyContinue

# Capture error information
$result = Get-Process -Name test -ErrorAction SilentlyContinue
if ($result) {
    Stop-Process -InputObject $result
} else {
    Write-Host "Process not found"
}

This approach prevents scripts from failing when processes don't exist or have already terminated. Always consider what should happen when expected processes aren't found—sometimes this indicates a problem that requires investigation.

Try-Catch Error Handling

For more sophisticated error handling, use try-catch blocks to capture and respond to specific error conditions:

try {
    $process = Get-Process -Name application -ErrorAction Stop
    Stop-Process -InputObject $process -Force -ErrorAction Stop
    Write-Host "Process terminated successfully"
} catch [Microsoft.PowerShell.Commands.ProcessCommandException] {
    Write-Warning "Process not found or already terminated"
} catch {
    Write-Error "Unexpected error: $_"
}

This structure allows different responses to different error types, enabling more intelligent script behavior. The generic catch block handles unexpected errors, ensuring your script doesn't fail silently.

"Proper error handling isn't just about preventing script failures—it's about providing meaningful feedback that helps diagnose issues when things don't go as expected."

Permission and Access Considerations

Process management often requires elevated privileges, especially when dealing with system processes or processes running under different user accounts. Always consider permission requirements:

# Check if running as administrator
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

if (-not $isAdmin) {
    Write-Warning "This operation requires administrator privileges"
    exit
}

# Proceed with process management
Get-Process | Where-Object {$_.ProcessName -like "system*"} | Stop-Process -Force

This check prevents confusing error messages and provides clear guidance when insufficient permissions prevent operations from succeeding.

Practical Process Management Scenarios

Understanding cmdlet syntax is only the beginning. Real-world process management involves combining these tools into practical solutions for common administrative challenges.

Automated Memory Management

Create a monitoring script that automatically terminates processes exceeding memory thresholds while logging the action:

$memoryThreshold = 2GB
$logPath = "C:\Logs\ProcessManagement.log"

Get-Process | Where-Object {$_.WorkingSet -gt $memoryThreshold} | ForEach-Object {
    $logEntry = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Terminating $($_.ProcessName) (PID: $($_.Id)) - Memory: $([math]::Round($_.WorkingSet / 1GB, 2))GB"
    Add-Content -Path $logPath -Value $logEntry
    Stop-Process -Id $_.Id -Force
}

This script provides accountability through logging while automatically managing runaway processes. Schedule it to run periodically using Task Scheduler for continuous monitoring.

Application Restart Script

Some applications require periodic restarts to maintain performance or apply configuration changes. Create a safe restart script:

$appName = "MyApplication"
$appPath = "C:\Program Files\MyApp\MyApplication.exe"

# Attempt graceful shutdown
$process = Get-Process -Name $appName -ErrorAction SilentlyContinue
if ($process) {
    $process.CloseMainWindow() | Out-Null
    Start-Sleep -Seconds 10
    
    # Force termination if still running
    if (Get-Process -Id $process.Id -ErrorAction SilentlyContinue) {
        Stop-Process -Id $process.Id -Force
    }
}

# Wait for complete termination
Start-Sleep -Seconds 5

# Restart application
Start-Process -FilePath $appPath

This script ensures clean application shutdown before restarting, minimizing the risk of data corruption or incomplete cleanup operations.

Process Monitoring and Alerting

Implement continuous monitoring that alerts when critical processes aren't running:

$criticalProcesses = @("sqlservr", "w3wp", "MyBusinessApp")
$alertEmail = "admin@company.com"

foreach ($processName in $criticalProcesses) {
    $process = Get-Process -Name $processName -ErrorAction SilentlyContinue
    
    if (-not $process) {
        $subject = "ALERT: Critical process $processName not running"
        $body = "The critical process $processName was not found running on $env:COMPUTERNAME at $(Get-Date)"
        
        # Send alert (requires configured SMTP)
        Send-MailMessage -To $alertEmail -Subject $subject -Body $body -SmtpServer "smtp.company.com"
    }
}

Schedule this script to run at regular intervals, creating a simple but effective process monitoring solution without requiring expensive monitoring software.

Performance Optimization and Reporting

Beyond basic process management, PowerShell enables comprehensive performance analysis and reporting capabilities that provide insights into system behavior over time.

Creating Process Performance Reports

Generate detailed reports showing process resource consumption patterns:

$report = Get-Process | Select-Object ProcessName, 
    @{Name="CPU(s)"; Expression={$_.CPU}},
    @{Name="Memory(MB)"; Expression={[math]::Round($_.WorkingSet / 1MB, 2)}},
    @{Name="Handles"; Expression={$_.Handles}},
    @{Name="Threads"; Expression={$_.Threads.Count}},
    StartTime

$report | Export-Csv -Path "C:\Reports\ProcessReport_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv" -NoTypeInformation
$report | Out-GridView -Title "Current Process Status"

This creates both a permanent CSV record and an interactive grid view for immediate analysis. The calculated properties format data in more readable units.

Reporting Technique Use Case Output Format
Export-Csv Long-term trend analysis and archival Comma-separated values for Excel or database import
Out-GridView Interactive exploration and filtering Sortable, filterable GUI table
ConvertTo-Html Web-based dashboards and email reports HTML table for browser viewing
Export-Clixml Preserving complete object structure for later analysis XML representation of PowerShell objects

Tracking Process Lifecycle Events

Monitor process creation and termination events to understand system behavior:

$baseline = Get-Process | Select-Object ProcessName, Id

while ($true) {
    Start-Sleep -Seconds 10
    $current = Get-Process | Select-Object ProcessName, Id
    
    # Find new processes
    $newProcesses = Compare-Object -ReferenceObject $baseline -DifferenceObject $current -Property ProcessName, Id | 
        Where-Object {$_.SideIndicator -eq "=>"} 
    
    foreach ($proc in $newProcesses) {
        Write-Host "New process started: $($proc.ProcessName) (PID: $($proc.Id))" -ForegroundColor Green
    }
    
    # Find terminated processes
    $terminatedProcesses = Compare-Object -ReferenceObject $baseline -DifferenceObject $current -Property ProcessName, Id | 
        Where-Object {$_.SideIndicator -eq "<="} 
    
    foreach ($proc in $terminatedProcesses) {
        Write-Host "Process terminated: $($proc.ProcessName) (PID: $($proc.Id))" -ForegroundColor Red
    }
    
    $baseline = $current
}

This continuous monitoring reveals process behavior patterns, helping identify applications that frequently crash and restart or unexpected process activity that might indicate malware.

Resource Trend Analysis

Track resource consumption over time to identify gradual degradation or memory leaks:

$processName = "MyApplication"
$samples = @()

for ($i = 0; $i -lt 60; $i++) {
    $process = Get-Process -Name $processName -ErrorAction SilentlyContinue
    
    if ($process) {
        $samples += [PSCustomObject]@{
            Timestamp = Get-Date
            CPU = $process.CPU
            MemoryMB = [math]::Round($process.WorkingSet / 1MB, 2)
            Handles = $process.Handles
        }
    }
    
    Start-Sleep -Seconds 60
}

# Analyze trends
$memoryGrowth = ($samples[-1].MemoryMB - $samples[0].MemoryMB) / $samples[0].MemoryMB * 100
Write-Host "Memory growth over monitoring period: $([math]::Round($memoryGrowth, 2))%"

$samples | Export-Csv -Path "C:\Logs\ProcessTrend_$processName_$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation

This hourly sampling over a 60-hour period reveals whether memory consumption is stable or growing, indicating potential memory leaks that require investigation.

Security Considerations in Process Management

Process management carries security implications that administrators must understand. Malicious processes can masquerade as legitimate applications, and improper process termination can create security vulnerabilities.

Verifying Process Authenticity

Check process properties to verify legitimacy and detect potentially malicious software:

Get-Process | Select-Object ProcessName, Id, Path, Company, ProductVersion | 
    Where-Object {$_.Path -ne $null} |
    Where-Object {$_.Company -eq $null -or $_.Company -notlike "*Microsoft*"} |
    Format-Table -AutoSize

Legitimate processes typically have company information and digital signatures. Processes without these attributes or running from unusual locations warrant investigation. However, this isn't foolproof—some legitimate applications lack complete metadata.

"Process names can be easily spoofed by malware. Always verify the process path and digital signature rather than relying solely on the process name for security decisions."

Identifying Suspicious Process Behavior

Create detection scripts for common indicators of compromise:

# Processes running from temporary directories
Get-Process | Where-Object {$_.Path -like "*\Temp\*" -or $_.Path -like "*\AppData\Local\Temp\*"} | 
    Select-Object ProcessName, Id, Path

# Processes with unusual parent-child relationships
Get-WmiObject Win32_Process | Select-Object ProcessId, Name, ParentProcessId, 
    @{Name="ParentName"; Expression={(Get-Process -Id $_.ParentProcessId -ErrorAction SilentlyContinue).ProcessName}} |
    Where-Object {$_.ParentName -eq "explorer" -and $_.Name -like "powershell*"}

# Processes consuming network resources without visible windows
Get-Process | Where-Object {$_.MainWindowTitle -eq "" -and $_.Threads.Count -gt 5} |
    Select-Object ProcessName, Id, Path

These checks identify common malware behaviors, though false positives occur with legitimate background services and scheduled tasks. Always investigate suspicious findings rather than automatically terminating processes.

Audit Logging for Process Termination

Maintain detailed logs of process termination activities for security auditing and troubleshooting:

function Stop-ProcessWithLogging {
    param(
        [Parameter(Mandatory=$true)]
        [string]$ProcessName,
        [string]$Reason = "Not specified"
    )
    
    $logPath = "C:\Logs\ProcessTermination.log"
    $process = Get-Process -Name $ProcessName -ErrorAction SilentlyContinue
    
    if ($process) {
        $logEntry = @"
Timestamp: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
User: $env:USERNAME
Computer: $env:COMPUTERNAME
Process: $($process.ProcessName)
PID: $($process.Id)
Path: $($process.Path)
Reason: $Reason
"@
        Add-Content -Path $logPath -Value $logEntry
        Add-Content -Path $logPath -Value "---"
        
        Stop-Process -InputObject $process -Force
        return $true
    }
    return $false
}

# Usage
Stop-ProcessWithLogging -ProcessName "suspicious_app" -Reason "Consuming excessive memory"

This logging function creates an audit trail showing who terminated which processes and why, essential for security investigations and compliance requirements.

How do I find processes using a specific port?

Use the Get-NetTCPConnection cmdlet combined with Get-Process: Get-NetTCPConnection -LocalPort 80 | Select-Object -Property OwningProcess | Get-Process. This shows which process is listening on port 80. For UDP connections, use Get-NetUDPEndpoint instead.

Can I restart a process instead of just stopping it?

PowerShell doesn't have a built-in Restart-Process cmdlet, but you can achieve this by capturing the process path before termination and starting it again: $path = (Get-Process -Name notepad).Path; Stop-Process -Name notepad; Start-Process $path. For services, use Restart-Service instead.

Why does Stop-Process sometimes fail even with -Force?

Several factors can prevent process termination: insufficient permissions (requires administrator rights for system processes), protected processes (like antivirus software), or processes with active kernel-mode components. Try running PowerShell as administrator, or use taskkill /F /PID [processid] as a last resort.

How can I prevent accidentally stopping critical system processes?

Create a whitelist of protected processes and check against it before termination: $protected = @("svchost", "csrss", "winlogon", "explorer"); if ($protected -contains $processName) { Write-Warning "Cannot terminate protected process"; return }. Always use -WhatIf when testing new scripts.

What's the difference between WorkingSet and PrivateMemorySize?

WorkingSet represents the total physical memory currently allocated to the process, including shared libraries. PrivateMemorySize shows only the memory exclusively used by the process. For identifying memory leaks, monitor PrivateMemorySize as it better reflects the process's actual memory consumption growth.

How do I get process information for a specific user account?

Use WMI to access owner information: Get-WmiObject Win32_Process | Select-Object ProcessName, ProcessId, @{Name="Owner";Expression={$_.GetOwner().User}} | Where-Object {$_.Owner -eq "username"}. This requires administrator privileges to view processes owned by other users.