Module 15 Lesson 4 of 6 🕑 ~55 min

> cat module-15-4-systems-administration.md

Systems Administration

The bread and butter of enterprise PowerShell: Active Directory, services, processes, disk space, and reaching dozens or hundreds of servers at once through remoting — instead of logging into each one by hand.

1 PowerShell and Active Directory

Import the module with Import-Module ActiveDirectory. Common cmdlets: Get-ADUser, Get-ADGroup, Get-ADComputer, New-ADUser, Disable-ADAccount, Enable-ADAccount, Set-ADUser, Add-ADGroupMember, Remove-ADGroupMember, Unlock-ADAccount. Find one user with Get-ADUser -Identity asmith; search broadly with Get-ADUser -Filter * — but be careful in very large directories, where a query returning hundreds of thousands of objects can create unnecessary load (Module 4's Active Directory content covers the directory structure this all sits on top of).

A support administrator investigating locked accounts might run Search-ADAccount -LockedOut, then Unlock-ADAccount -Identity asmith. During offboarding: Disable-ADAccount -Identity asmith. In a real enterprise, offboarding involves far more than one AD command — AD, Entra ID, Microsoft 365, VPN, privileged accounts, SaaS applications, certificates, tokens, devices, and even physical access all need addressing (Module 10, Lesson 4 covers the full Leaver lifecycle). PowerShell is often the tool used to orchestrate several of these steps together.

2 Bulk IAM Automation

Given HR-provided offboarding.csv:

Username,Department,Action
asmith,Finance,Disable
jjones,IT,Disable
spatel,Security,Keep
$Users = Import-Csv ".\offboarding.csv"

foreach ($User in $Users) {
    if ($User.Action -eq "Disable") {
        Write-Host "Would disable $($User.Username)"
    }
}

Notice this says "Would disable" rather than actually disabling anyone. This is a genuinely valuable safety technique — verify what the automation would do first, then only enable the actual destructive operation once you trust the logic. This same pattern reappears throughout Lesson 5's safe-automation rules, and it's worth internalising here first, where the stakes of a mistake are exactly "500 people's accounts."

3 Windows Services

Get-Service lists all services; Get-Service -Name Spooler gets one specifically. Start-Service, Stop-Service, and Restart-Service Spooler control it.

Suppose a customer reports authentication stopped working after a server reboot. Start by checking what's actually stopped:

Get-Service |
Where-Object Status -eq "Stopped"

Then investigate the relevant application services specifically. PowerShell should never automatically restart a service without understanding its dependencies, HA architecture, database connectivity, maintenance windows, customer impact, and change-management procedures — automation doesn't remove operational responsibility, it just makes the decision execute faster once you've actually made it.

4 Process Investigation & Disk Space Monitoring

Get-Process shows running processes; Get-Process powershell targets one specifically. Sort by resource usage:

Get-Process |
Sort-Object CPU -Descending |
Select-Object -First 10

Get-Process |
Sort-Object WorkingSet -Descending |
Select-Object -First 10

Genuinely useful during general troubleshooting, and a natural companion to Module 14's process-investigation content. A very common support task is checking disk space:

Get-CimInstance Win32_LogicalDisk |
Where-Object DriveType -eq 3 |
Select-Object DeviceID,
    @{Name="SizeGB";Expression={[math]::Round($_.Size / 1GB,2)}},
    @{Name="FreeGB";Expression={[math]::Round($_.FreeSpace / 1GB,2)}}

This one example demonstrates CIM, objects, filtering, and calculated properties (the @{Name=...; Expression=...} pattern) all working together — a small script, but genuinely representative of real automation.

5 WMI vs CIM

Older PowerShell scripts frequently use Get-WmiObject (e.g. Get-WmiObject Win32_OperatingSystem). Modern scripts normally use Get-CimInstance instead (Get-CimInstance Win32_OperatingSystem). You'll routinely inherit older WMI-based scripts in large enterprises — older scripts lean on Get-WmiObject, newer ones on Get-CimInstance.

Never rewrite a production script just because its syntax looks old. First understand why it exists, what systems it supports, what modules it requires, how it authenticates, and what else depends on it — the same discipline Module 8 and Module 12 both taught about legacy technology generally, now applied specifically to scripts you didn't write yourself.

6 PowerShell Remoting

PowerShell can execute commands remotely — genuinely important for enterprise administration. Traditional Windows PowerShell remoting commonly uses WinRM/WS-Management, which Microsoft documents as the standard remoting mechanism for Windows PowerShell environments; modern PowerShell 7 can also remote over SSH to Windows, macOS and Linux hosts.

An interactive remote session: Enter-PSSession -ComputerName SERVER01, with Exit-PSSession to leave. A one-off remote command:

Invoke-Command `
    -ComputerName SERVER01 `
    -ScriptBlock {
        Get-Service
    }

Across multiple servers at once:

Invoke-Command `
    -ComputerName SERVER01,SERVER02,SERVER03 `
    -ScriptBlock {
        Get-ComputerInfo
    }

This is one big reason PowerShell matters so much in Windows infrastructure — instead of manually logging into 100 servers, an administrator can query all of them at once from a single command.

Remote administration needs careful control, though. Organisations restrict PowerShell remoting through firewall rules, network segmentation, administrative groups, Just Enough Administration, Privileged Access Workstations, PAM systems, WinRM/SSH configuration, certificate authentication, and endpoint security controls. Don't teach "enable WinRM everywhere" — teach "understand the organisation's remote-management architecture and security policy" instead. Module 9's Kerberos/NTLM content and Module 10's privileged-access content both feed directly into how remoting actually gets secured in a real environment.

Lesson Outcome

You should now be able to query, unlock and disable Active Directory accounts, run bulk IAM changes safely using a "would do" dry-run pattern before enabling the real operation, manage Windows services and investigate processes, monitor disk space with calculated properties, distinguish Get-WmiObject from Get-CimInstance in inherited scripts, and use Invoke-Command/Enter-PSSession to administer multiple remote servers at once. Lesson 5 covers what turns a working script into something safe to actually run in production.