Arkendia Classrooms
Lesson 19 of 28 · 17 min

PowerShell: Basics and Use Cases

On Linux you have bash. On Windows you have PowerShell: a command shell and a scripting language built to administer systems, from a single laptop to a whole cloud. Its commands return structured objects rather than plain text, which makes it remarkably powerful. For defenders it is a daily tool; for attackers it is a favourite too, precisely because it is already installed everywhere. In this lesson you learn to read it, to run harmless inspection commands, and to understand why it is a major topic for security teams.

You have just seen how Active Directory manages organisations. PowerShell is the command-line language that administrators use to query and manage it, and your tool to inspect the Windows VM of your lab.

Starting PowerShell

Search for "PowerShell" in the Windows start menu and open it. Be aware of two flavours: the Windows PowerShell that ships with the system, and the more recent cross-platform PowerShell, which also runs on Linux and macOS. The basics are the same. The prompt looks like PS C:\Users\student>. Running as administrator requires choosing "Run as administrator", and, as with sudo, you should use it only when necessary.

Cmdlets: verb-noun commands

PowerShell commands are called cmdlets and follow a consistent Verb-Noun naming scheme, which makes them easy to guess and read:

Get-Process          # list running processes
Get-Service          # list services
Get-ChildItem        # list files (alias: ls, dir)
Set-Location C:\     # change directory (alias: cd)
Get-Content file.txt # show a file (alias: cat, type)
Get-Date
Get-Command *service*   # search for commands
Get-Help Get-Service -Examples   # built-in help with examples

Get-Help is your best friend, and it comes with a learning habit: when you do not know how to do something, ask Get-Command for a command whose name contains the keyword, then Get-Help for its examples. Many cmdlets have short aliases (such as ls or cat that mimic Unix) to ease the transition, but scripts are easier to read with full names.

Objects and the pipeline

Here lies the major difference with bash. In bash, a pipe passes text from one command to the next, and you need tools such as grep and awk to cut it up. In PowerShell, the pipe passes objects: each item has properties (like Name or Status) and methods. So filtering and selecting are done on properties, not on text columns.

Get-Service | Where-Object { $_.Status -eq 'Running' }
Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 Name, Id, CPU
Get-Service | Select-Object Name, Status | Format-Table
Get-ChildItem C:\Users -Recurse -Filter *.txt | Measure-Object

The symbol $_ stands for "the current object in the pipeline". Where-Object filters, Select-Object chooses properties, Sort-Object sorts, and Measure-Object counts. To discover what properties an object has, pipe it to Get-Member, for example Get-Process | Get-Member. Output can be exported easily: Export-Csv, ConvertTo-Json or Out-File.

Variables, conditions and loops

The scripting side will look familiar after the bash lesson:

$name = "lab"
$services = Get-Service | Where-Object { $_.Status -eq 'Running' }
Write-Output "Running services: $($services.Count)"

foreach ($svc in $services | Select-Object -First 3) {
    if ($svc.Name -like 'W*') {
        Write-Output "$($svc.Name) starts with W"
    }
}

Variables begin with a dollar sign. Comparison operators are words: -eq, -ne, -gt, -lt, -like and -match. Scripts are saved in files ending in .ps1.

Execution policy

Windows has an execution policy that controls whether script files can run, for instance only if they are signed or created locally. You can see it with Get-ExecutionPolicy. Be clear on one point: the execution policy is a safety guard against accidental execution, not a security boundary, since users can bypass it in several ways. Real protection comes from controlling who can run what, from application control, and from logging.

Everyday administration use cases

Here are practical examples that show why administrators love PowerShell:

# Disk space on local drives
Get-PSDrive -PSProvider FileSystem

# Hotfixes installed
Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 5

# Local users and local administrators
Get-LocalUser
Get-LocalGroupMember -Group "Administrators"

# Network configuration
Get-NetIPAddress
Get-NetTCPConnection -State Listen

On a domain, administrators use an additional module for Active Directory, which provides cmdlets such as Get-ADUser or Get-ADGroupMember, to list accounts or check who belongs to a privileged group. A single script can audit thousands of accounts, find those that have not logged in for months, and produce a report in seconds.

Notice how several of these map to what you learned on Linux: Get-NetTCPConnection -State Listen is the cousin of ss -tuln, Get-LocalGroupMember parallels reading /etc/group, and Get-Content is cat. The tools change; the questions stay the same: who is here, what is running, what is listening, what changed?

PowerShell and security

PowerShell is a double-edged tool. Because it is preinstalled, powerful, and able to reach nearly every part of the system, attackers frequently use it. Using legitimate built-in tools for malicious purposes is a pattern known as "living off the land", and it is described in the MITRE ATT&CK knowledge base (attack.mitre.org) under the technique for command and scripting interpreters. For defenders, this means two things:

  • Enable logging. PowerShell can record script block logging and transcription, which write what was executed to the event logs. Without them, malicious use leaves few traces. Policies deployed with GPOs can turn this on.
  • Constrain and monitor. Limit PowerShell for users who do not need it, use application control, and watch for suspicious patterns such as very long encoded commands, downloads from the Internet launched by scripts, or PowerShell started by an office application.

An encoded command, in particular, is not malicious in itself, because administrators use encoding to pass complex strings, but it is rare enough in normal activity that it is a classic thing to flag and investigate. We deliberately do not show any malicious script in this course. Your goal is to be able to recognise and log this behaviour, and to use PowerShell for good.

Use it on your own systems only

Running administration or inspection commands remotely against machines that are not yours, or against a company network without authorisation, is illegal access in most countries even if the commands are read-only. In your lab, you may try everything on your own VMs.

Your turn: build a small inventory script

On your Windows VM, write a script inventory.ps1 that outputs, in a text file on your desktop: the computer name, the date, the five processes using the most memory, the list of running services, the members of the local Administrators group and the listening TCP ports. Use the cmdlets of this lesson. Run it and compare with the output of the Linux audit script you wrote in chapter 4: what is similar, what is different?

See a solution
$out = "$env:USERPROFILE\Desktop\inventory.txt"
"Computer: $env:COMPUTERNAME" | Out-File $out
"Date: $(Get-Date -Format yyyy-MM-dd)" | Out-File $out -Append
"--- Top 5 processes by memory ---" | Out-File $out -Append
Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First 5 Name, Id, WorkingSet | Out-File $out -Append
"--- Running services ---" | Out-File $out -Append
Get-Service | Where-Object { $_.Status -eq 'Running' } | Select-Object Name | Out-File $out -Append
"--- Local administrators ---" | Out-File $out -Append
Get-LocalGroupMember -Group "Administrators" | Select-Object Name | Out-File $out -Append
"--- Listening TCP ports ---" | Out-File $out -Append
Get-NetTCPConnection -State Listen | Select-Object LocalAddress, LocalPort | Out-File $out -Append

Compared with the Linux script, the structure is the same (header, accounts, ports, services), but PowerShell works with object properties, where the bash script cut text columns with cut and awk. If the script refuses to run, check the execution policy and read the error message calmly: it usually tells you exactly what is blocked.

Key takeaways

  • PowerShell uses Verb-Noun cmdlets and passes objects, not text, through the pipeline.
  • Key cmdlets: Get-Process, Get-Service, Where-Object, Select-Object, Get-Help, Get-Member.
  • The execution policy is a safeguard, not a security boundary.
  • Attackers also use PowerShell ("living off the land"): enable script logging and monitor unusual usage.
  • Next lesson: where Windows records what happened, with event logs.
Advertisement
Log in to save your progress. Log in