Introduction to PowerShell

Summary: in this tutorial, you will learn discover what makes powershell unique — an object-oriented shell and scripting language built on .net. understand its history, editions, and why it is the modern standard for windows automation.

Introduction to PowerShell

PowerShell is far more than a replacement for the old Windows Command Prompt. It is a complete automation platform — a shell, a scripting language, and a configuration management framework all rolled into one.

What is PowerShell?

PowerShell is a task-based command-line shell and scripting language built on the .NET framework. Unlike traditional shells that pass strings around, PowerShell works with objects — structured data with properties and methods.

This architectural choice fundamentally changes how you work with command output. In traditional Unix shells, every command outputs text, which you must parse with tools like awk, sed, or cut. These tools are powerful but brittle — if the output format changes (different column widths, reordered fields), your scripts break.

PowerShell eliminates this entire category of problems. Commands return structured .NET objects with named properties and typed data. You access properties by name, filter by exact values, and compose pipelines without string manipulation.

Think of it this way: in Bash, you pipe text between commands and parse it. In PowerShell, you pipe .NET objects — so you never need to worry about column alignment, string splitting, or fragile text parsing.

The Key Difference: Objects vs Text

In a traditional shell, everything is text. This creates constant parsing challenges:

# Bash: text-based pipeline
# ps aux | grep nginx | awk '{print $2}'
# You're parsing strings, hoping columns don't shift
 

This approach has problems:

  • Fragile: If column positions change, your script breaks
  • Type-unsafe: Everything is a string; you manually convert to numbers
  • Verbose: Extracting data requires complex regex or field splitting
  • Error-prone: Whitespace, special characters, and quoting are constant issues

In PowerShell, commands return objects with properties:

# PowerShell: object-based pipeline
Get-Process -Name nginx | Select-Object -Property Id
# You directly access the .Id property — no parsing needed
 

Why this matters:

  • Robust: Property names never change; your code is resilient
  • Type-safe: CPU is a decimal, memory is an integer, dates are DateTime objects
  • Discoverable: Use Get-Member to see all available properties and methods
  • Composable: Filter and transform objects without text manipulation

This single concept — everything is an object — makes PowerShell fundamentally more powerful and less error-prone than text-based shells. You spend less time parsing output and more time solving problems.

A Brief History

YearMilestone
2002Jeffrey Snover publishes the "Monad Manifesto"
2006PowerShell 1.0 released for Windows XP/Vista/Server 2003
2009PowerShell 2.0 — Remoting, background jobs, modules
2012PowerShell 3.0 — Workflows, improved cmdlet discovery
2016PowerShell goes open-source on GitHub, Linux and macOS support
2018PowerShell Core 6.0 — cross-platform, built on .NET Core
2020PowerShell 7.0 — unification of Windows PowerShell and PowerShell Core
2024PowerShell 7.4+ — latest stable with performance improvements

Windows PowerShell (5.1) ships with Windows and is built on .NET Framework. PowerShell 7+ is cross-platform and built on .NET (Core). For new work, always use PowerShell 7+.

Windows PowerShell vs PowerShell 7

Understanding the two "editions" is essential:

FeatureWindows PowerShell 5.1PowerShell 7+
PlatformWindows onlyWindows, macOS, Linux
.NET Runtime.NET Framework 4.x.NET 8+
Executablepowershell.exepwsh.exe
DevelopmentMaintenance onlyActive development
Side-by-sidePre-installedInstall separately

Both can coexist on the same machine! powershell.exe always launches Windows PowerShell 5.1, while pwsh.exe launches PowerShell 7+.

Why Learn PowerShell?

1. Automation at Scale

PowerShell was built for automation. Everything you can click in Windows, you can script in PowerShell — and do it across thousands of machines.

Why this matters:

  • Repeatability: Script once, run anywhere, anytime
  • Consistency: Eliminate human error from repetitive tasks
  • Speed: Automate operations that take hours manually
  • Auditing: Scripts provide a clear record of what changed
# Create 100 Active Directory users from a CSV
Import-Csv users.csv | ForEach-Object {
    New-ADUser -Name $_.Name -Department $_.Dept -Enabled $true
}
 

This replaces hours of GUI clicking with a 3-line script that's auditable, repeatable, and version-controlled.

2. Consistent Command Structure

Every PowerShell command follows a Verb-Noun naming convention, making commands predictable and discoverable:

Get-Process       # Get running processes
Stop-Process      # Stop a process
Get-Service       # Get services
Start-Service     # Start a service
Get-ChildItem     # Get files and folders
Copy-Item         # Copy files
 

This consistency has major advantages:

  • Guessable: Need to restart a service? Try Restart-Service (it exists!)
  • Discoverable: Get-Command -Verb Get shows all retrieval commands
  • Self-documenting: Command names clearly state their purpose
  • Approved verbs: PowerShell enforces a standard set of verbs (Get, Set, New, Remove, Start, Stop, etc.)

Once you learn the pattern, you can guess command names and often be right. Compare this to Unix commands like ls, cat, grep — abbreviated names you must memorize.

3. Self-Documenting

PowerShell has the best built-in help system of any shell. Every cmdlet includes documentation, examples, and parameter descriptions:

Get-Help Get-Process -Full        # Complete documentation
Get-Help Get-Process -Examples    # Just show examples
Get-Command -Verb Get             # Find all "Get" commands
Get-Command -Noun *User*          # Find commands about users
 

Why this matters:

  • No internet required: Full documentation offline
  • Examples included: Most cmdlets have 5-10 real-world examples
  • Parameter help: -Full shows detailed parameter descriptions
  • Discoverable: Find commands by verb, noun, or keyword
  • Update-Help: Download latest docs with one command

Unlike Unix man pages, PowerShell help is written for humans and includes practical examples you can copy and adapt immediately.

4. Cross-Platform

With PowerShell 7+, your scripts run on Windows, macOS, and Linux:

# This works on all three platforms
Get-Process | Sort-Object CPU -Descending | Select-Object -First 5
 

5. Integration with Everything

PowerShell connects to:

  • Azure (Az module)
  • AWS (AWS.Tools module)
  • Microsoft 365 (Exchange Online, SharePoint, Teams)
  • Active Directory (RSAT module)
  • SQL Server (SqlServer module)
  • REST APIs (Invoke-RestMethod)
  • WMI/CIM (for hardware and OS info)

Your First PowerShell Commands

Open a PowerShell terminal and try these:

# What version am I running?
$PSVersionTable
 
# What's today's date?
Get-Date
 
# What's my computer name?
$env:COMPUTERNAME    # Windows
hostname             # Cross-platform
 

Exploring Objects

This is the most important thing to understand early. Every command returns objects:

# Get the current date
$today = Get-Date
 
# See what properties and methods it has
$today | Get-Member
 
# Access specific properties
$today.DayOfWeek
$today.Year
$today.Month
 
# Call methods
$today.AddDays(30)
$today.ToString("yyyy-MM-dd")
 
# Get a process and explore its properties
$proc = Get-Process -Name "explorer" | Select-Object -First 1
 
$proc.Id
$proc.CPU
$proc.WorkingSet64 / 1MB    # Memory in MB
 

Get-Member (or its alias gm) is your best friend. Pipe any command to it to discover what properties and methods are available.

The PowerShell Console

Keyboard Shortcuts

ShortcutAction
TabAuto-complete commands, parameters, paths
Ctrl+RSearch command history
/ Navigate command history
Ctrl+CCancel running command
Ctrl+LClear screen
F7Show command history window (Windows Terminal)
Ctrl+SpaceShow argument completions

PSReadLine

PowerShell comes with PSReadLine, which gives you a rich editing experience:

# Search history (press Ctrl+R then type)
# Matching commands appear as you type
 
# Predictive IntelliSense (PowerShell 7.2+)
Set-PSReadLineOption -PredictionSource History
Set-PSReadLineOption -PredictionViewStyle ListView
 
# List view shows multiple suggestions you can scroll through
 

Understanding Aliases

PowerShell has built-in aliases for many commands, including aliases that look like Unix commands:

# See all aliases
Get-Alias
 
# Some common ones
Get-Alias ls      # → Get-ChildItem
Get-Alias cd      # → Set-Location
Get-Alias cat     # → Get-Content
Get-Alias rm      # → Remove-Item
Get-Alias echo    # → Write-Output
Get-Alias cls     # → Clear-Host
Get-Alias pwd     # → Get-Location
 

These aliases behave differently from their Unix counterparts! ls in PowerShell is Get-ChildItem, which returns objects, not text. The parameters are different too. When writing scripts, always use the full cmdlet name.

Execution Policies

PowerShell has a safety feature called execution policies that control which scripts can run:

# Check current policy
Get-ExecutionPolicy
 
# Common policies:
# Restricted    — No scripts can run (Windows default)
# RemoteSigned  — Local scripts run; downloaded must be signed
# AllSigned     — All scripts must be signed
# Unrestricted  — All scripts run (with warnings for downloaded)
# Bypass        — Nothing blocked, no warnings
 
# Set for current user (recommended)
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
 

Execution policies are a safety feature, not a security boundary. They protect you from accidentally running untrusted scripts. Set RemoteSigned for your user scope — it's the best balance of usability and safety.

The PowerShell Profile

Your profile is a script that runs every time PowerShell starts — like .bashrc for Bash:

# Check if your profile exists
Test-Path $PROFILE
 
# See the path to your profile
$PROFILE
 
# There are actually multiple profiles
$PROFILE | Format-List -Force
# AllUsersAllHosts
# AllUsersCurrentHost
# CurrentUserAllHosts
# CurrentUserCurrentHost    ← This is $PROFILE
 

Create a starter profile:

# Create the profile file if it doesn't exist
if (!(Test-Path $PROFILE)) {
    New-Item -ItemType File -Path $PROFILE -Force
}
 
# Open it in your editor
code $PROFILE
# or: notepad $PROFILE
 

A starter profile:

# PowerShell Profile
 
# Aliases
Set-Alias -Name g -Value git
Set-Alias -Name open -Value Invoke-Item
 
# Quick navigation
function home { Set-Location ~ }
function proj { Set-Location ~/Projects }
 
# Custom prompt
function prompt {
    $path = (Get-Location).Path.Replace($HOME, '~')
    Write-Host "PS " -NoNewline -ForegroundColor Cyan
    Write-Host "$path" -NoNewline -ForegroundColor Yellow
    return "> "
}
 
# PSReadLine settings
Set-PSReadLineOption -PredictionSource History
Set-PSReadLineOption -EditMode Emacs
 
Write-Host "Profile loaded!" -ForegroundColor Green
 

🏋️ Exercise 1: Explore PowerShell Basics

Run each of these commands and observe the output:

  1. $PSVersionTable — what version are you running?
  2. Get-Date | Get-Member — how many properties does a DateTime have?
  3. Get-Process | Select-Object -First 3 — what columns do you see?
  4. Get-Alias | Measure-Object — how many aliases are defined?
Show Solution

Sample outputs:

# 1. Version
$PSVersionTable
# PSVersion      7.4.x
# PSEdition      Core
# OS             Microsoft Windows ...
 
# 2. DateTime members
Get-Date | Get-Member
# There are roughly 20+ properties (Year, Month, Day, Hour, etc.)
# and 20+ methods (AddDays, AddHours, ToString, etc.)
 
# 3. Process properties
Get-Process | Select-Object -First 3
# Handles  NPM(K)  PM(K)  WS(K)  CPU(s)  Id  ProcessName
# You see structured columns — each is a property of the object
 
# 4. Alias count
Get-Alias | Measure-Object
# Count: typically 140-180 aliases depending on modules loaded
 
🏋️ Exercise 2: Object Exploration

Use Get-Date and its members to answer these questions:

  1. What day of the year is today?
  2. What date is it 100 days from now?
  3. Is this year a leap year?
💡 Hint
Use Get-Date | Get-Member to discover properties and methods. Look for DayOfYear, AddDays(), and IsLeapYear().
Show Solution
$today = Get-Date
 
# 1. Day of the year
$today.DayOfYear
# Example output: 166
 
# 2. 100 days from now
$today.AddDays(100)
# Example output: Wednesday, September 23, 2025 ...
 
# 3. Is this a leap year?
[DateTime]::IsLeapYear($today.Year)
# Output: False (2025 is not a leap year)
 
Was this page helpful?
SR

Written by the ShellRAG Team

The ShellRAG editorial team writes practical, beginner-friendly PowerShell tutorials with tested code examples and real-world use cases. Every article is technically reviewed for accuracy and updated regularly.

Learn more about us →