PowerShell vs Linux Commands Guide
A comprehensive comparison between PowerShell and Linux/bash commands for system administrators working across platforms.
Philosophy Differences
Aspect |
PowerShell |
Linux/Bash |
Data Type |
Works with objects |
Works with text streams |
Output |
Structured objects |
Plain text |
Approach |
Verb-Noun commands |
Short cryptic commands |
Case Sensitivity |
Case insensitive |
Case sensitive |
Help System |
Built-in comprehensive help |
Man pages + various docs |
Basic Navigation and File Operations
Directory Operations
Task |
PowerShell |
Linux |
Current directory |
Get-Location or pwd |
pwd |
Change directory |
Set-Location C:\temp or cd C:\temp |
cd /tmp |
List files |
Get-ChildItem or ls or dir |
ls |
List with details |
Get-ChildItem -Force |
ls -la |
List recursively |
Get-ChildItem -Recurse |
find . or ls -R |
Examples
# PowerShell
Get-ChildItem -Path C:\temp -Recurse -Force | Where-Object {$_.Extension -eq ".txt"}
# Linux equivalent
find /tmp -name "*.txt" -type f
File Operations
Task |
PowerShell |
Linux |
Create directory |
New-Item -Type Directory -Path C:\folder |
mkdir /folder |
Create file |
New-Item -Type File -Path C:\file.txt |
touch /file.txt |
Copy file |
Copy-Item source.txt dest.txt |
cp source.txt dest.txt |
Copy directory |
Copy-Item -Recurse C:\src C:\dest |
cp -r /src /dest |
Move/rename |
Move-Item old.txt new.txt |
mv old.txt new.txt |
Delete file |
Remove-Item file.txt |
rm file.txt |
Delete directory |
Remove-Item -Recurse -Force folder |
rm -rf folder |
Examples
# PowerShell - Copy all .txt files
Get-ChildItem *.txt | Copy-Item -Destination C:\backup
# Linux equivalent
cp *.txt /backup/
File Content Operations
Reading Files
Task |
PowerShell |
Linux |
Display file |
Get-Content file.txt |
cat file.txt |
First 10 lines |
Get-Content file.txt -TotalCount 10 |
head file.txt |
Last 10 lines |
Get-Content file.txt -Tail 10 |
tail file.txt |
Follow/monitor |
Get-Content file.txt -Wait |
tail -f file.txt |
Display with line numbers |
Get-Content file.txt \| ForEach-Object {$i=1} {"$i : $_"; $i++}| cat -n file.txt` |
|
Writing Files
Task |
PowerShell |
Linux |
Write to file |
"Hello" \| Out-File file.txt |
echo "Hello" > file.txt |
Append to file |
"Hello" \| Add-Content file.txt |
echo "Hello" >> file.txt |
Write multiple lines |
@("Line1","Line2") \| Out-File file.txt |
printf "Line1\nLine2\n" > file.txt |
Text Processing
Task |
PowerShell |
Linux |
Search in files |
Select-String "pattern" *.txt |
grep "pattern" *.txt |
Case insensitive search |
Select-String "pattern" *.txt |
grep -i "pattern" *.txt |
Count lines |
(Get-Content file.txt).Count |
wc -l file.txt |
Sort lines |
Get-Content file.txt \| Sort-Object |
sort file.txt |
Unique lines |
Get-Content file.txt \| Sort-Object -Unique |
sort file.txt \| uniq |
Replace text |
(Get-Content file.txt) -replace "old","new" |
sed 's/old/new/g' file.txt |
Examples
# PowerShell - Find files containing "error" and show line numbers
Get-ChildItem *.log | Select-String "error" | Select-Object Filename,LineNumber,Line
# Linux equivalent
grep -n "error" *.log
System Details
Task |
PowerShell |
Linux |
OS Information |
Get-ComputerInfo |
uname -a |
Hostname |
$env:COMPUTERNAME |
hostname |
Current user |
$env:USERNAME |
whoami |
Uptime |
(Get-CimInstance Win32_OperatingSystem).LastBootUpTime |
uptime |
System load |
Get-Counter "\Processor(_Total)\% Processor Time" |
top or htop |
Memory usage |
Get-CimInstance Win32_OperatingSystem |
free -h |
Disk usage |
Get-CimInstance Win32_LogicalDisk |
df -h |
Examples
# PowerShell - Memory usage percentage
$os = Get-CimInstance Win32_OperatingSystem
$memUsed = ($os.TotalVisibleMemorySize - $os.FreePhysicalMemory) / $os.TotalVisibleMemorySize * 100
Write-Host "Memory Usage: $([math]::Round($memUsed,1))%"
# Linux equivalent
free | awk 'NR==2{printf "Memory Usage: %.1f%%\n", $3*100/$2}'
Process Management
Process Operations
Task |
PowerShell |
Linux |
List processes |
Get-Process |
ps aux |
Find process |
Get-Process -Name "notepad" |
ps aux \| grep notepad |
Kill process by name |
Stop-Process -Name "notepad" |
pkill notepad |
Kill process by PID |
Stop-Process -Id 1234 |
kill 1234 |
Force kill |
Stop-Process -Name "app" -Force |
kill -9 1234 |
Start process |
Start-Process "notepad.exe" |
notepad.exe & |
Background process |
Start-Job { Start-Process "app.exe" } |
app.exe & |
Examples
# PowerShell - Find processes using most memory
Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First 5 Name,WorkingSet
# Linux equivalent
ps aux --sort=-%mem | head -5
Services Management
Task |
PowerShell |
Linux (systemd) |
List services |
Get-Service |
systemctl list-units --type=service |
Service status |
Get-Service -Name "Spooler" |
systemctl status sshd |
Start service |
Start-Service -Name "Spooler" |
systemctl start sshd |
Stop service |
Stop-Service -Name "Spooler" |
systemctl stop sshd |
Restart service |
Restart-Service -Name "Spooler" |
systemctl restart sshd |
Enable at boot |
Set-Service -Name "Spooler" -StartupType Automatic |
systemctl enable sshd |
Disable at boot |
Set-Service -Name "Spooler" -StartupType Disabled |
systemctl disable sshd |
Network Operations
Network Commands
Task |
PowerShell |
Linux |
Test connectivity |
Test-NetConnection google.com |
ping google.com |
Test specific port |
Test-NetConnection google.com -Port 80 |
telnet google.com 80 |
Show IP config |
Get-NetIPAddress |
ip addr show |
Show routing table |
Get-NetRoute |
ip route show |
DNS lookup |
Resolve-DnsName google.com |
nslookup google.com |
Download file |
Invoke-WebRequest url -OutFile file |
wget url or curl -o file url |
Show open ports |
Get-NetTCPConnection |
netstat -tuln |
Examples
# PowerShell - Check if multiple servers are reachable
$servers = @("server1", "server2", "server3")
$servers | ForEach-Object {
$result = Test-NetConnection $_ -Port 80 -WarningAction SilentlyContinue
[PSCustomObject]@{Server=$_; Reachable=$result.TcpTestSucceeded}
}
# Linux equivalent
for server in server1 server2 server3; do
if timeout 5 bash -c "</dev/tcp/$server/80"; then
echo "$server: Reachable"
else
echo "$server: Not reachable"
fi
done
Variables and Environment
Variable Syntax
Concept |
PowerShell |
Linux/Bash |
Variable assignment |
$name = "John" |
name="John" |
Variable access |
$name |
$name |
Environment variables |
$env:PATH |
$PATH |
Command substitution |
$date = Get-Date |
date=$(date) |
Array |
$arr = @("a","b","c") |
arr=("a" "b" "c") |
Array access |
$arr[0] |
${arr[0]} |
Environment Variables
Task |
PowerShell |
Linux |
List all env vars |
Get-ChildItem env: |
env or printenv |
Get specific var |
$env:PATH |
echo $PATH |
Set env var |
$env:MYVAR = "value" |
export MYVAR="value" |
Set permanent var |
[Environment]::SetEnvironmentVariable("MYVAR","value","User") |
Add to ~/.bashrc |
Scripting Concepts
Basic Script Structure
PowerShell Script (.ps1)
#!/usr/bin/env pwsh
# Parameters
param(
[string]$ServerName = "localhost",
[int]$Port = 80
)
# Function
function Test-Connection {
param($Server, $Port)
$result = Test-NetConnection $Server -Port $Port
return $result.TcpTestSucceeded
}
# Main logic
if (Test-Connection $ServerName $Port) {
Write-Host "Server $ServerName is reachable on port $Port" -ForegroundColor Green
} else {
Write-Host "Server $ServerName is NOT reachable on port $Port" -ForegroundColor Red
}
Bash Script (.sh)
#!/bin/bash
# Parameters with defaults
SERVER_NAME=${1:-localhost}
PORT=${2:-80}
# Function
test_connection() {
local server=$1
local port=$2
timeout 5 bash -c "</dev/tcp/$server/$port" 2>/dev/null
return $?
}
# Main logic
if test_connection "$SERVER_NAME" "$PORT"; then
echo -e "\033[32mServer $SERVER_NAME is reachable on port $PORT\033[0m"
else
echo -e "\033[31mServer $SERVER_NAME is NOT reachable on port $PORT\033[0m"
fi
Conditional Logic
PowerShell
if ($age -ge 18) {
Write-Host "Adult"
} elseif ($age -ge 13) {
Write-Host "Teenager"
} else {
Write-Host "Child"
}
# Switch statement
switch ($day) {
"Monday" { "Start of work week" }
"Friday" { "TGIF!" }
default { "Regular day" }
}
Bash
if [ $age -ge 18 ]; then
echo "Adult"
elif [ $age -ge 13 ]; then
echo "Teenager"
else
echo "Child"
fi
# Case statement
case $day in
"Monday") echo "Start of work week" ;;
"Friday") echo "TGIF!" ;;
*) echo "Regular day" ;;
esac
Loops
PowerShell
# ForEach
$fruits = @("apple", "banana", "cherry")
foreach ($fruit in $fruits) {
Write-Host "I like $fruit"
}
# For loop
for ($i = 1; $i -le 10; $i++) {
Write-Host "Count: $i"
}
# While loop
$count = 1
while ($count -le 5) {
Write-Host "Count: $count"
$count++
}
Bash
# For loop with array
fruits=("apple" "banana" "cherry")
for fruit in "${fruits[@]}"; do
echo "I like $fruit"
done
# For loop with range
for i in {1..10}; do
echo "Count: $i"
done
# While loop
count=1
while [ $count -le 5 ]; do
echo "Count: $count"
((count++))
done
Error Handling
PowerShell
try {
$result = Get-Content "nonexistent.txt"
} catch {
Write-Error "File not found: $($_.Exception.Message)"
} finally {
Write-Host "Cleanup code here"
}
# Check last command success
if ($?) {
Write-Host "Command succeeded"
} else {
Write-Host "Command failed"
}
Bash
# Simple error handling
if ! cp source.txt dest.txt 2>/dev/null; then
echo "Copy failed" >&2
exit 1
fi
# Check exit code
if [ $? -eq 0 ]; then
echo "Command succeeded"
else
echo "Command failed"
fi
# Set error handling
set -e # Exit on any error
set -u # Exit on undefined variable
Package Management
Task |
PowerShell |
Linux (Ubuntu/Debian) |
Linux (RHEL/CentOS) |
Install package |
Install-Module ModuleName |
apt install package |
yum install package |
Update packages |
Update-Module |
apt update && apt upgrade |
yum update |
Search packages |
Find-Module *keyword* |
apt search keyword |
yum search keyword |
List installed |
Get-InstalledModule |
apt list --installed |
yum list installed |
Remove package |
Uninstall-Module ModuleName |
apt remove package |
yum remove package |
File Permissions and Users
Permissions
Task |
PowerShell |
Linux |
Show permissions |
Get-Acl C:\file.txt |
ls -l file.txt |
Change permissions |
Set-Acl -Path C:\file.txt -AclObject $acl |
chmod 755 file.txt |
Change owner |
Complex ACL operations |
chown user:group file.txt |
User Management
Task |
PowerShell |
Linux |
Current user |
$env:USERNAME |
whoami |
List users |
Get-LocalUser |
cat /etc/passwd |
Add user |
New-LocalUser -Name "user" |
useradd user |
User groups |
Get-LocalGroup |
groups or id |
Useful One-liners
PowerShell
# Find large files
Get-ChildItem C:\ -Recurse | Where-Object {$_.Length -gt 100MB} | Sort-Object Length -Descending
# Find files modified in last 7 days
Get-ChildItem -Recurse | Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-7)}
# Check disk space on all drives
Get-CimInstance Win32_LogicalDisk | Select-Object DeviceID,@{n='Size(GB)';e={[math]::Round($_.Size/1GB,2)}},@{n='Free(GB)';e={[math]::Round($_.FreeSpace/1GB,2)}}
# Find duplicate files by hash
Get-ChildItem -Recurse | Get-FileHash | Group-Object Hash | Where-Object {$_.Count -gt 1}
Linux
# Find large files
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | sort -k5 -hr
# Find files modified in last 7 days
find . -type f -mtime -7
# Check disk space
df -h
# Find duplicate files by hash
find . -type f -exec md5sum {} \; | sort | uniq -d -w 32
Key Differences Summary
PowerShell Advantages
- Object-oriented: Rich data structures, easy property access
- Consistent syntax: Verb-Noun pattern, predictable parameters
- Built-in help: Comprehensive documentation with examples
- Cross-platform: Runs on Windows, Linux, macOS
- Integration: Deep Windows system integration
- Type safety: Strong typing prevents many errors
Linux/Bash Advantages
- Performance: Generally faster for text processing
- Ubiquity: Available on virtually all Unix-like systems
- Simplicity: Short commands for common tasks
- Pipes: Excellent text stream processing
- History: Decades of scripts and knowledge
- Resource usage: Lower memory footprint
When to Use What
Use PowerShell when:
- Working primarily on Windows
- Need rich object manipulation
- Want consistent, discoverable commands
- Working with .NET applications
- Need strong error handling
Use Linux/Bash when:
- Working on Unix-like systems
- Processing large text files
- Need maximum performance
- Working with traditional Unix tools
- Want minimal system dependencies
PowerShell Core (6+) runs on Linux too! Install with:
# Ubuntu/Debian
sudo apt install powershell
# RHEL/CentOS
sudo yum install powershell
# Run PowerShell on Linux
pwsh
This gives you PowerShell's object-oriented approach on Linux systems, combining the best of both worlds!