PowerShell Fundamentals  ›  Windows Server 2022  ›  Lesson 1

Lesson 1

PowerShell Fundamentals on Windows Server 2022

From your first cmdlet to your first working script. No prior scripting experience required.

Learning objectives

  • Explain what PowerShell is and how it differs from Command Prompt
  • Identify and run cmdlets using the Verb-Noun convention
  • Use Get-Help, Get-Command, and Get-Member to teach yourself any cmdlet
  • Chain cmdlets together with the pipeline to filter, sort, and export data
  • Configure an execution policy, then write, save, and run a .ps1 script
  • Automate a real administrative task: a server health report

How this lesson works

Use the navigation pane on the left (or the Next button below) to move through the modules in order. Modules 1–4 build vocabulary, Modules 5–8 build skills, and Modules 9–11 put them to work on real server tasks.

The Practice Terminal is a simulated Windows PowerShell console built into this lesson. You can type real cmdlets into it and get realistic output — without any risk to an actual server. Look for the "Try it in the Practice Terminal" links throughout the modules.

EnvironmentThis lesson assumes Windows Server 2022 with Windows PowerShell 5.1 (built in). Everything shown also works in the Practice Terminal on this page.
Module 1

What Is PowerShell?

A command-line shell and a scripting language, purpose-built for Windows administration.

PowerShell is the primary administrative tool for Windows Server 2022. Some server tasks can only be performed in PowerShell, and on Server Core installations (servers with no desktop GUI) it is essentially your entire interface. Every hour you invest here pays back in every Windows course and every IT job that follows.

PowerShell vs. Command Prompt (cmd.exe)

Command PromptPowerShell
Outputs plain textOutputs objects with properties you can sort, filter, and export
Small set of built-in commandsThousands of cmdlets — plus everything cmd can do
Batch files (.bat) with limited syntaxA full scripting language (.ps1) with variables, loops, and logic
Manages one machine at a timeCan manage hundreds of servers remotely at once
Key conceptWhen PowerShell lists your services, it isn't producing text — it's producing service objects. Each object carries properties (Name, Status, StartType) and methods (Start, Stop). This single idea is why the pipeline in Module 5 is so powerful.
Module 2

Launching PowerShell on Server 2022

Windows Server 2022 ships with Windows PowerShell 5.1 installed. Three ways to open it:

  1. Start menu: right-click Start → Windows PowerShell (Admin)
  2. Run box: press Win + R, type powershell, then press Ctrl + Shift + Enter (this shortcut launches it elevated)
  3. Server Manager: Tools menu → Windows PowerShell
Always run as AdministratorFor server administration, always launch PowerShell elevated. The title bar must read "Administrator: Windows PowerShell." Cmdlets that install roles, manage services, or create users will fail with permission errors otherwise.

Verify your version

Administrator: Windows PowerShell
PS C:\> $PSVersionTable.PSVersion Major Minor Build Revision ----- ----- ----- -------- 5 1 20348 2652

You also have the PowerShell ISE (Integrated Scripting Environment) pre-installed — a simple editor with a script pane on top and a console below. We'll use it in Module 7 to write our first script.

Module 3

Cmdlet Anatomy: Verb-Noun

Every PowerShell command — called a cmdlet — follows the same predictable pattern.

The pattern
Verb-Noun -ParameterName Value # Examples: Get-Service # get all services Get-Service -Name Spooler # get one specific service Stop-Service -Name Spooler # stop it Start-Service -Name Spooler # start it again

Standard verbs

The verbs are standardized across all of PowerShell. Learn a handful and you can guess cmdlets you've never seen — and usually be right:

VerbMeaningExample
Get-Retrieve information (safe, read-only)Get-Process
Set-Change a settingSet-Service
New-Create somethingNew-LocalUser
Remove-Delete somethingRemove-Item
Start- / Stop- / Restart-Control something runningRestart-Service
Test-Check or verifyTest-Connection
Try it now — zero riskGet- cmdlets never change anything, so you can't break the server while exploring. Run these three in the Practice Terminal: Get-Date, Get-Process, Get-Service
Module 4

The Three Discovery Cmdlets

Nobody memorizes thousands of cmdlets. Professionals memorize three that find everything else.

1. Get-Command — "What cmdlet does X?"

Administrator: Windows PowerShell
PS C:\> Get-Command -Noun Service CommandType Name ----------- ---- Cmdlet Get-Service Cmdlet Restart-Service Cmdlet Set-Service Cmdlet Start-Service Cmdlet Stop-Service

2. Get-Help — "How do I use this cmdlet?"

Administrator: Windows PowerShell
PS C:\> Update-Help # run once (needs internet) PS C:\> Get-Help Get-Service -Examples # the most useful switch PS C:\> Get-Help Get-Service -Full # everything

3. Get-Member — "What can I do with this output?"

Pipe any cmdlet's output into Get-Member to see every property and method its objects carry:

Administrator: Windows PowerShell
PS C:\> Get-Service | Get-Member TypeName: System.ServiceProcess.ServiceController Name MemberType Definition ---- ---------- ---------- Start Method void Start() Stop Method void Stop() DisplayName Property string DisplayName {get;set;} Status Property ServiceControllerStatus Status {get;} StartType Property ServiceStartMode StartType {get;}
The administrator's workflowGet-Command to find the cmdlet → Get-Help -Examples to learn its syntax → Get-Member to explore its output. This loop replaces memorization.
Module 5

The Pipeline

The pipe symbol | feeds the objects from one cmdlet into the next. Read pipelines left to right, like a sentence.

Administrator: Windows PowerShell
# "Get the services, keep only the stopped ones, sort them by name" PS C:\> Get-Service | Where-Object { $_.Status -eq 'Stopped' } | Sort-Object Name # "Get processes, sort by CPU descending, show the top 5" PS C:\> Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 # "Get services and save the results to a CSV file" PS C:\> Get-Service | Export-Csv C:\Reports\services.csv -NoTypeInformation

The Big Four pipeline cmdlets

CmdletJob
Where-ObjectFilter — keep only objects matching a condition
Sort-ObjectSort by any property
Select-ObjectChoose which properties (columns) or how many objects to keep
Export-CsvSend results to a file you can open in Excel
What is $_ ?Inside a Where-Object block, $_ means "the current object coming through the pipe." So $_.Status -eq 'Stopped' reads: "the current object's Status property equals Stopped." Comparison operators use dashes: -eq (equals), -ne (not equal), -gt / -lt (greater/less than), -like (wildcard match).

Quick Lab 5.1 — Pipeline practice

  1. List only the services that are currently Running.
  2. Show the 5 processes using the most memory (the property is WorkingSet).
  3. Create a Reports folder with New-Item -ItemType Directory -Path C:\Reports, then export all running services to C:\Reports\running-services.csv.
Reveal solutions
Solutions
Get-Service | Where-Object { $_.Status -eq 'Running' } Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First 5 New-Item -ItemType Directory -Path C:\Reports Get-Service | Where-Object { $_.Status -eq 'Running' } | Export-Csv C:\Reports\running-services.csv -NoTypeInformation
Module 6

Variables

Variables start with a dollar sign. No type declaration needed — PowerShell figures it out.

Administrator: Windows PowerShell
PS C:\> $serverName = "SRV-2022-01" PS C:\> $maxUsers = 25 PS C:\> $services = Get-Service # a variable can hold objects PS C:\> $services.Count 14 # Double quotes expand variables inside strings: PS C:\> Write-Host "Auditing $serverName for $maxUsers users" Auditing SRV-2022-01 for 25 users
RememberDouble quotes = variables get expanded. Single quotes = printed literally, exactly as typed.
Module 7

Your First Script (.ps1)

A script is just a text file of the same commands you've been typing — saved with a .ps1 extension so you can run it again and again.

Step 1 — Execution policy

As a security measure, Windows Server blocks script execution by default. Check yours, then set it to RemoteSigned — the standard for administrators. It runs local scripts freely but requires downloaded scripts to be digitally signed:

Administrator: Windows PowerShell
PS C:\> Get-ExecutionPolicy Restricted PS C:\> Set-ExecutionPolicy RemoteSigned (press Y to confirm)
Security noteNever set the policy to Unrestricted or Bypass on a production server just to make errors go away. Execution policy exists to stop malicious scripts from running silently. RemoteSigned is the professional balance.

Step 2 — Write the script

Open the PowerShell ISE (Start → type "ise") or Notepad, and type:

Hello-Server.ps1
# Hello-Server.ps1 # My first PowerShell script — anything after a # is a comment $serverName = $env:COMPUTERNAME $today = Get-Date -Format "dddd, MMMM dd yyyy" Write-Host "==============================" -ForegroundColor Cyan Write-Host " Hello from $serverName" -ForegroundColor Green Write-Host " Today is $today" Write-Host "==============================" -ForegroundColor Cyan

Step 3 — Save and run it

Administrator: Windows PowerShell
# Save as C:\Scripts\Hello-Server.ps1, then: PS C:\> cd C:\Scripts PS C:\Scripts> .\Hello-Server.ps1 ============================== Hello from SRV-2022-01 Today is Monday, July 06 2026 ==============================
Why the .\ ?PowerShell requires .\ ("in this folder") to run a script from the current directory. It's a deliberate safety feature — it prevents a malicious script named ping.ps1 from hijacking a command you meant to run.
Module 8

Adding Logic: Read-Host, If, ForEach

Three building blocks turn a list of commands into a real program.

Read-Host — get input from the user

snippet
$name = Read-Host "Enter your name" Write-Host "Welcome, $name!"

If / Else — make decisions

snippet
$freeGB = [math]::Round((Get-PSDrive C).Free / 1GB, 1) if ($freeGB -lt 20) { Write-Host "WARNING: Only $freeGB GB free on C:" -ForegroundColor Red } else { Write-Host "Disk OK: $freeGB GB free" -ForegroundColor Green }

ForEach — repeat for every item in a list

snippet
$criticalServices = "Spooler", "W32Time", "Dnscache" foreach ($svc in $criticalServices) { $status = (Get-Service -Name $svc).Status Write-Host "$svc is $status" }
Module 9

Real Server Admin Tasks

Each of these one-liners replaces several minutes of clicking through the GUI.

Administrator: Windows PowerShell
# --- Roles & Features --- PS C:\> Get-WindowsFeature | Where-Object Installed # what's installed? PS C:\> Install-WindowsFeature -Name Web-Server -IncludeManagementTools # install IIS # --- Services --- PS C:\> Restart-Service -Name Spooler PS C:\> Set-Service -Name Spooler -StartupType Automatic # --- Event Logs --- PS C:\> Get-EventLog -LogName System -EntryType Error -Newest 5 # --- Local Users --- PS C:\> New-LocalUser -Name "labstudent" -FullName "Lab Student" # --- Networking --- PS C:\> Test-Connection 8.8.8.8 -Count 2
Module 10 · Capstone

Capstone: Server Health Report Script

Combine everything — variables, cmdlets, the pipeline, if/else, foreach — into one useful tool. Build this in the ISE and save it as C:\Scripts\Get-ServerHealth.ps1.

Get-ServerHealth.ps1
# Get-ServerHealth.ps1 # A daily health-check report for Windows Server 2022 $server = $env:COMPUTERNAME $date = Get-Date -Format "yyyy-MM-dd HH:mm" Write-Host "===== SERVER HEALTH REPORT =====" -ForegroundColor Cyan Write-Host "Server: $server | $date" # --- 1. Uptime --- $os = Get-CimInstance Win32_OperatingSystem $uptime = (Get-Date) - $os.LastBootUpTime Write-Host "Uptime: $($uptime.Days) days, $($uptime.Hours) hours" # --- 2. Disk space check --- $freeGB = [math]::Round((Get-PSDrive C).Free / 1GB, 1) if ($freeGB -lt 20) { Write-Host "Disk C: LOW - $freeGB GB free" -ForegroundColor Red } else { Write-Host "Disk C: OK - $freeGB GB free" -ForegroundColor Green } # --- 3. Critical services check --- $critical = "W32Time", "Dnscache", "LanmanServer" foreach ($svc in $critical) { $s = Get-Service -Name $svc if ($s.Status -eq 'Running') { Write-Host "Service $($s.Name): Running" -ForegroundColor Green } else { Write-Host "Service $($s.Name): $($s.Status)" -ForegroundColor Red } } # --- 4. Last 5 system errors --- Get-EventLog -LogName System -EntryType Error -Newest 5 | Select-Object TimeGenerated, Source | Format-Table -AutoSize # --- 5. Save a copy to CSV --- Get-Service | Where-Object { $_.Status -eq 'Running' } | Export-Csv "C:\Reports\services-$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation Write-Host "Report complete. CSV saved to C:\Reports" -ForegroundColor Cyan
New syntax spotted$($s.Name) is a subexpression — when you need an object's property inside a double-quoted string, wrap it in $( ). Also, `n is a newline character (backtick, not apostrophe).
Module 11

Knowledge Check & Practice Exercises

All hands-on exercises can be completed in the Practice Terminal.

Knowledge check

  1. What naming convention do all cmdlets follow, and why does it help you guess commands you've never used?
  2. What is the key difference between PowerShell output and Command Prompt output?
  3. What does $_ represent inside a Where-Object script block?
  4. Why is RemoteSigned the recommended execution policy instead of Unrestricted?
  5. Which discovery cmdlet shows you the properties a service object has?

Exercise A — Cmdlet scavenger hunt

  1. Using only Get-Command and Get-Help, find the cmdlet that lists local user accounts. Run it.
  2. Find a cmdlet with the verb Test- that checks network connectivity. Use it on 8.8.8.8.

Exercise B — Pipeline builder

  1. Build one pipeline that finds all services whose name starts with "W" (hint: -like "W*"), sorts them by Status, and displays only the Name and Status columns.
  2. Export the result to C:\Reports\w-services.csv. (Create C:\Reports first if it doesn't exist.)
Reveal solution
Solution
Get-Service | Where-Object { $_.Name -like "W*" } | Sort-Object Status | Select-Object Name, Status New-Item -ItemType Directory -Path C:\Reports Get-Service | Where-Object { $_.Name -like "W*" } | Export-Csv C:\Reports\w-services.csv -NoTypeInformation

Exercise C — Script it (graded, on your lab VM)

Write a script named New-LabUser.ps1 that:

  1. Uses Read-Host to ask for a username
  2. Checks with an if statement whether that local user already exists (hint: Get-LocalUser with -ErrorAction SilentlyContinue)
  3. If not, creates the user with New-LocalUser and prints a green success message; if the user exists, prints a red warning instead
  4. Includes at least three comment lines explaining what the script does
Where to go nextLesson 2 covers functions, parameters, and error handling — turning scripts into reusable tools. For a head start, run Get-Help about_Functions on your lab VM. PowerShell ships with its own textbook: Get-Help about_* lists every conceptual topic.
Hands-On Lab Environment

Practice Terminal

A simulated Windows PowerShell 5.1 console. Type cmdlets below and press Enter — output is generated locally in your browser, so you can experiment freely.

Administrator: Windows PowerShell

Tips: press / for command history · press Tab to auto-complete a cmdlet name · type help to list everything this simulator supports.

Suggested things to try