Windows 11 · Lesson 14

PowerShell for Defensive Administration

Use PowerShell to inventory Windows quickly, filter evidence, verify security state, and make small controlled changes without turning automation into blind hardening.

PowerShell is most valuable when it makes reasoning faster and more repeatable. The defensive pattern is simple: inspect, narrow, change carefully, re-query, test, and document.

Lesson Snapshot

Core principles6
Pipeline concepts6
Primary skillFast verified inventory
GoalControlled administration

Learning objectives

What this lesson should help you do

01

Explain where PowerShell is most useful during defensive Windows administration.

02

Use read-only inventory commands before making configuration changes.

03

Filter, sort, and select results so large system inventories become useful evidence.

04

Recognize the difference between inspection, controlled change, and bulk automation.

05

Use PowerShell to review users, services, firewall, Defender, updates, tasks, and event logs efficiently.

06

Verify the result of every meaningful administrative change instead of assuming the command worked as intended.

Core concept

PowerShell should make your reasoning more precise

The best commands answer a clear question and return structured objects that can be filtered, sorted, compared, and verified.

Automation warning

Fast commands can create fast mistakes

Bulk scripts can disable required services, remove valid users, or break network access before the team knows what changed.

Avoid broad destructive automation unless every target, dependency, and verification step is understood.

Defensive PowerShell principles

Six habits that keep command-line work controlled

Inspect before changing

Start with read-only commands that show the current state. A command should answer a specific question before it modifies anything.

Narrow the target

Avoid commands that affect large groups of users, services, files, or rules unless the scope is fully understood.

Prefer explicit filters

Use names, properties, paths, states, and other filters so the command acts on the exact object you intend.

Record important output

Capture relevant evidence before high-impact changes, especially for accounts, services, tasks, firewall rules, and event logs.

Change one thing at a time

Small changes are easier to verify and troubleshoot than broad scripts that alter many controls at once.

Re-query after change

The same command family used for inspection can often verify that the intended state actually exists afterward.

Pipeline basics

Turn large inventories into useful evidence

Get

Retrieve objects from the system, such as users, services, firewall rules, scheduled tasks, or events.

Where-Object

Filter objects based on properties such as status, name, startup mode, profile, or account state.

Select-Object

Choose only the properties that matter so output is easier to read and compare.

Sort-Object

Order results by properties such as time, state, display name, or install date.

Format-Table / Format-List

Present selected output in a useful layout for review. Formatting changes presentation, not the underlying object.

Export-Csv

Save structured inventory output for later comparison or documentation in an authorized practice environment.

High-value inventory commands

Review major Windows security areas quickly

Local users

Get-LocalUser

Review account names, enabled state, and password-related properties.

Local administrators

Get-LocalGroupMember -Group "Administrators"

Review privileged local group membership.

Services

Get-Service | Sort-Object Status, DisplayName

Review running and stopped services without changing them.

Service details

Get-CimInstance Win32_Service | Select-Object Name, DisplayName, State, StartMode, StartName, PathName

Adds startup type, account context, and executable path to service review.

Firewall profiles

Get-NetFirewallProfile

Review Domain, Private, and Public firewall profile state.

Enabled inbound rules

Get-NetFirewallRule -Enabled True -Direction Inbound | Select-Object DisplayName, Action, Profile

Build a quick view of active inbound firewall rules.

Defender status

Get-MpComputerStatus

Review Defender protection state and health information.

Defender preferences

Get-MpPreference

Inspect Defender exclusions and protection-related preferences.

Filtering examples

Ask smaller questions of large inventories

Find disabled local users

Get-LocalUser | Where-Object {$_.Enabled -eq $false}

Filters the local user inventory to accounts that are currently disabled.

Find running services

Get-Service | Where-Object {$_.Status -eq 'Running'}

Shows only services currently running.

Find automatic services

Get-CimInstance Win32_Service | Where-Object {$_.StartMode -eq "Auto"}

Shows services configured for automatic startup.

Find enabled inbound allow rules

Get-NetFirewallRule | Where-Object {$_.Enabled -eq "True" -and $_.Direction -eq "Inbound" -and $_.Action -eq "Allow"}

Narrows firewall review to active inbound allow rules.

Defensive administration map

One shell, multiple security domains

Identity

Get-LocalUserGet-LocalGroupGet-LocalGroupMember

Quickly review authorized users, privileged groups, and unexpected membership.

Protection

Get-MpComputerStatusGet-MpPreferenceGet-NetFirewallProfileGet-NetFirewallRule

Review Defender and firewall posture from one console.

System

Get-ServiceGet-CimInstance Win32_ServiceGet-HotFixGet-ComputerInfo

Review services, updates, Windows version, and core system state.

Persistence

Get-ScheduledTaskGet-ScheduledTaskInfoGet-CimInstance Win32_StartupCommand

Review recurring execution and startup behavior without opening multiple tools.

Evidence

Get-WinEventGet-AclGet-ItemProperty

Inspect logs, permissions, and configuration evidence with repeatable queries.

Controlled change examples

Every change needs a matching verification command

Disable an unnecessary local user

Change

Disable-LocalUser -Name "exampleuser"

Use only after confirming the account is not required by the scenario or a service.

Verify

Get-LocalUser -Name "exampleuser"

Remove a user from Administrators

Change

Remove-LocalGroupMember -Group "Administrators" -Member "exampleuser"

Confirm the user still needs the account but does not need administrative privilege.

Verify

Get-LocalGroupMember -Group "Administrators"

Start a required service

Change

Start-Service -Name "Spooler"

Use only when the service is required and its configuration is understood.

Verify

Get-Service -Name "Spooler"

Disable an unnecessary scheduled task

Change

Disable-ScheduledTask -TaskName "ExampleTask"

Preserve task evidence first if the task may matter to forensics.

Verify

Get-ScheduledTask -TaskName "ExampleTask"

Bulk-change risks

Commands that sound efficient but can create major problems

Disable every stopped service

Stopped does not mean unnecessary. Many services start only when needed.

Remove every unfamiliar administrator

Some accounts may be required by the scenario or an application. Investigate first.

Delete every scheduled task outside Microsoft folders

Legitimate applications often create their own tasks.

Block every inbound firewall rule

Required RDP, file sharing, management, or applications can depend on specific rules.

Remove every Defender exclusion

Some narrow exclusions may support required applications.

Apply one giant hardening script

Bulk changes are difficult to attribute, troubleshoot, and verify during a timed competition.

Output techniques

Make the evidence readable and reusable

Select only useful properties

Get-LocalUser | Select-Object Name, Enabled, PasswordRequired, PasswordExpires

Removes visual noise and keeps the columns that answer the question.

Sort by time

Get-WinEvent -LogName System -MaxEvents 50 | Sort-Object TimeCreated -Descending

Keeps recent evidence easy to follow.

Export an inventory

Get-Service | Select-Object Name, DisplayName, Status | Export-Csv ".\services-inventory.csv" -NoTypeInformation

Creates a structured snapshot that can support documentation or before/after comparison.

Save plain text when needed

Get-LocalGroupMember -Group "Administrators" | Out-File ".\admins-before.txt"

Useful for preserving a small before-state record in an authorized lab.

Error handling

When the command does not behave as expected

Command not found

Confirm the cmdlet exists on the Windows version and edition you are using, and that the relevant module or feature is available.

Access denied

Some administrative queries require an elevated PowerShell session. Do not assume lack of access means the object does not exist.

No output

A filter may be too narrow or the object name may be wrong. Remove filters gradually and inspect the underlying object.

Property missing

Different cmdlets return different object types. Use Get-Member or Format-List * in a lab to inspect available properties.

Verification pattern

A repeatable defensive PowerShell rhythm

01

Query before

Record the exact object and current state.

02

Apply one controlled change

Change only the confirmed weakness.

03

Query after

Re-run a read-only inspection command to confirm the configuration state.

04

Test the function

Verify the related user, service, application, network path, or security control still works.

05

Check logs

Look for errors or expected evidence after high-impact changes.

06

Document

Record what changed, why, and what verification proved.

Decision cases

PowerShell-assisted reasoning in context

Unexpected administrator account

PowerShell shows an unfamiliar account in the local Administrators group.

The finding is important, but the account must be compared with the scenario and service dependencies before removal.

Response

Inspect the account, document membership, identify purpose, then remove only the unnecessary privilege or disable the account if evidence supports it.

Automatic service with unusual path

A service inventory shows an automatic service running from a user-profile directory.

The path is unusual enough to investigate, but the service may belong to a legitimate application.

Response

Review service name, account, executable, dependencies, installed software, and event evidence before making a change.

Broad firewall exposure

A filtered rule list shows a required service allowed inbound on all profiles.

The service may be required while the scope is excessive.

Response

Inspect the specific rule and remote scope, narrow only what is justified, then test the required service.

Suspicious scheduled task

A task query shows a logon-triggered task that launches a script from an unusual user path.

This is an investigation lead, not automatic proof of malicious persistence.

Response

Preserve the task details, correlate with logs and file evidence, then disable or remove only when justified.

Fictional defensive lab

Use PowerShell to investigate before hardening

Step 01

Read the fictional scenario

Morgan is the authorized administrator. RDP, Defender, Windows Update, and a project share are required. One unknown local administrator and one unknown scheduled task need review.

Step 02

Build an inventory

Use read-only commands to review local users, administrators, firewall profiles, Defender status, services, tasks, and recent events.

Step 03

Filter the findings

Narrow the output to the unexpected administrator, the unusual task, and the specific services or rules related to required functionality.

Step 04

Preserve evidence

Save the relevant before-state output for the administrator group and the scheduled task before making any change.

Step 05

Apply controlled remediation

Remove only the confirmed unnecessary privilege and disable the suspicious task after evidence has been preserved.

Step 06

Verify

Re-query the administrator group and task state, then test RDP, Defender, firewall, and the required project share.

Common mistakes

PowerShell habits that create avoidable problems

Running commands without reading output

PowerShell is fast enough to make mistakes quickly. Read the object state before changing it.

Copying large scripts blindly

A script may assume a different Windows edition, network, scenario, or application set.

Using broad wildcards

Wildcards can match far more objects than expected. Prefer explicit names and filters.

Skipping verification

A command completing without an error does not prove the system is secure or functional.

Treating no output as proof

Permissions, filters, or object types may explain empty output.

Mixing evidence collection and destructive changes

Gather and preserve evidence first, then remediate.

Reflection

Test your defensive PowerShell reasoning

Question 1

Why is PowerShell especially useful for defensive inventory?

Question 2

What is the difference between Get, Where-Object, and Select-Object?

Question 3

Why can a large hardening script be risky during a competition?

Question 4

What should happen before and after a destructive PowerShell command?

Question 5

Why should empty output not automatically be treated as proof that nothing exists?

Question 6

What makes a PowerShell workflow defensive rather than blind automation?

PowerShell checklist

Before leaving command-line administration

01

Start with read-only inventory commands.

02

Use Select-Object to keep output focused.

03

Use Where-Object to narrow large result sets.

04

Use Sort-Object when order matters.

05

Preserve important before-state evidence.

06

Target one confirmed object at a time.

07

Avoid broad wildcards and bulk disable/remove commands.

08

Re-run inspection commands after every high-impact change.

09

Test the related user, service, application, or network path.

10

Check Event Viewer or Get-WinEvent when a change causes errors.

11

Document what changed and why.

Next Windows lesson

Windows Forensics & Evidence Preservation

Next, learn how to preserve and correlate Windows evidence before remediation so forensic questions can be answered with defensible facts instead of assumptions.

Open Lesson 15 →