PowerShell SysAdmin Documentation

PowerShell is Microsoft's command-line shell and scripting environment designed for Windows administration, automation, configuration management, troubleshooting, networking, security, and system monitoring.

Unlike traditional CMD commands, PowerShell works primarily with objects rather than plain text. This makes it extremely powerful when managing Windows servers and workstations.

Introduction

PowerShell commands are called cmdlets. Most cmdlets follow a Verb-Noun naming convention.

# Get information
Get-Date
Get-Process
Get-Service

``` # Set or modify something
Set-Service

# Create something
New-Item

# Remove something
Remove-Item ```

To discover commands:

Get-Command
Get-Command *Service*
Get-Help Get-Service
Get-Help Get-Service -Examples
Update-Help

PowerShell Basics

``` # Display the current date and time
Get-Date

# Display current location
Get-Location

# Change directory
Set-Location C:\Windows

# List directory contents
Get-ChildItem

# Clear screen
Clear-Host

# Display text
Write-Output "Hello World"

# Short aliases
ls
cd C:\Windows
pwd ```

Variables & Data Types

PowerShell variables begin with the $ character.

``` # String
$name = "Daudi"

# Integer
$age = 30

# Boolean
$enabled = $true

# Array
$servers = @("server01","server02","server03")

# Display variable
$name

# Check variable type
$age.GetType()

# Environment variable
$env:COMPUTERNAME
$env:USERNAME ```

Pipeline

The PowerShell pipeline (|) sends the output of one command as input to another command.

``` # Command1 | Command2 | Command3

"Hello World" | ForEach-Object {$_.ToUpper()}

# Find a running Notepad process
Get-Process | Where-Object {$_.Name -eq "Notepad"}

# Select specific properties
Get-Process | Select-Object Id,Name,CPU

# Find running services
Get-Service | Where-Object {$_.Status -eq "Running"}

# Find files larger than 1 MB
Get-ChildItem -Path "Downloads" | Where-Object {$_.Length -gt 1MB} ```

Filtering, Sorting & Selecting

``` # Filter processes
Get-Process | Where-Object {$_.CPU -gt 100}

# Select properties
Get-Process | Select-Object Id,Name,CPU

# Sort processes by CPU
Get-Process | Sort-Object CPU -Descending

# Select first 10 processes
Get-Process | Select-Object -First 10

# Select last 10 processes
Get-Process | Select-Object -Last 10

# Count objects
(Get-Process).Count ```

If, ElseIf & Else

``` $age = 30

if ($age -le 18) {
    Write-Output "You are a Minor"
}
elseif ($age -gt 18 -and $age -le 60) {
    Write-Output "You are an Adult"
}
else {
    Write-Output "You are a senior citizen"
} ```

Common comparison operators:

-eq Equal
-ne Not equal
-gt Greater than
-ge Greater than or equal
-lt Less than
-le Less than or equal
-like Wildcard comparison
-match Regular expression comparison

Switch Statement

``` $input = "Yellow"

switch ($input) {
    "Red" { Write-Output "Stop" }
    "Yellow" { Write-Output "Caution" }
    "Green" { Write-Output "Go" }
    Default { Write-Output "Unknown Color" }
} ```

Loops

For Loop

for ($i = 0; $i -lt 5; $i++) {
    Write-Output $i
}

ForEach Loop

$servers = @("server01","server02","server03")

``` foreach ($server in $servers) {
    Write-Output $server
} ```

While Loop

$count = 0

``` while ($count -lt 5) {
    Write-Output $count
    $count++
} ```

Do While Loop

$count = 0

``` do {
    Write-Output $count
    $count++
} while ($count -lt 5) ```

Functions

``` # Simple function
function Say-Hello {
    Write-Output "Hello Administrator"
}

Say-Hello

# Function with parameter
function Get-ServerInfo {
    param([string]$ComputerName)

    Get-CimInstance Win32_OperatingSystem -ComputerName $ComputerName
}

Get-ServerInfo -ComputerName "SERVER01" ```

Error Handling

Use try, catch, and finally when writing reliable administrative scripts.

``` try {
    Get-Content -Path "C:\NonExistingFile.txt" -ErrorAction Stop
    Write-Output "File exists"
}
catch {
    Write-Output "Error: $($_.Exception.Message)"
}
finally {
    Write-Output "File operation closed"
} ```

-ErrorAction Stop is important because many PowerShell errors are non-terminating errors and otherwise may not trigger catch.

Files & Directories

``` # List files
Get-ChildItem C:\Users

# Include subdirectories
Get-ChildItem C:\Users -Recurse

# Find specific files
Get-ChildItem C:\ -Filter "*.log" -Recurse

# Create directory
New-Item -Path C:\Backup -ItemType Directory

# Create file
New-Item -Path C:\Backup\test.txt -ItemType File

# Copy
Copy-Item C:\test.txt C:\Backup\

# Move
Move-Item C:\test.txt C:\Backup\

# Rename
Rename-Item C:\Backup\test.txt backup.txt

# Delete
Remove-Item C:\Backup\backup.txt

# Read file
Get-Content C:\Backup\log.txt

# Write text to file
"Server started" | Out-File C:\Backup\server.log

# Append text
"Server running" | Out-File C:\Backup\server.log -Append ```

Process Management

``` # List processes
Get-Process

# Find a process
Get-Process -Name notepad

# Process details
Get-Process | Select-Object Id,Name,CPU,WorkingSet

# Stop process
Stop-Process -Name notepad

# Force stop
Stop-Process -Name notepad -Force

# Start application
Start-Process notepad.exe

# Find processes consuming high CPU
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 ```

Windows Services

``` # List services
Get-Service

# Find running services
Get-Service | Where-Object {$_.Status -eq "Running"}

# Find stopped services
Get-Service | Where-Object {$_.Status -eq "Stopped"}

# Get specific service
Get-Service -Name Spooler

# Start service
Start-Service -Name Spooler

# Stop service
Stop-Service -Name Spooler

# Restart service
Restart-Service -Name Spooler

# Set service startup mode
Set-Service -Name Spooler -StartupType Automatic ```

Users & Groups

Modern Windows administration can use the Microsoft.PowerShell.LocalAccounts cmdlets for local users and groups.

``` # List local users
Get-LocalUser

# Get a user
Get-LocalUser -Name Administrator

# Create local user
$Password = Read-Host "Password" -AsSecureString
New-LocalUser -Name sysadmin -Password $Password

# Disable account
Disable-LocalUser -Name sysadmin

# Enable account
Enable-LocalUser -Name sysadmin

# List local groups
Get-LocalGroup

# Add user to Administrators
Add-LocalGroupMember -Group "Administrators" -Member "sysadmin"

# Remove user from group
Remove-LocalGroupMember -Group "Administrators" -Member "sysadmin" ```

NTFS Permissions

``` # View permissions
Get-Acl C:\Data

# Store ACL in variable
$acl = Get-Acl C:\Data

# Display access rules
$acl.Access

# Use icacls for detailed permission administration
icacls C:\Data

# Grant user Modify permission
icacls C:\Data /grant "username:(M)"

# Remove inherited permissions
icacls C:\Data /inheritance:d ```

System Information

``` # Computer name
$env:COMPUTERNAME

# Operating system information
Get-CimInstance Win32_OperatingSystem

# Computer hardware
Get-CimInstance Win32_ComputerSystem

# BIOS information
Get-CimInstance Win32_BIOS

# CPU information
Get-CimInstance Win32_Processor

# RAM information
Get-CimInstance Win32_PhysicalMemory

# Windows version
Get-ComputerInfo

# Uptime
(Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime ```

Networking

``` # Display IP configuration
Get-NetIPConfiguration

# List network adapters
Get-NetAdapter

# IP addresses
Get-NetIPAddress

# Routing table
Get-NetRoute

# Test connectivity
Test-Connection 8.8.8.8

# Test TCP port
Test-NetConnection google.com -Port 443

# DNS lookup
Resolve-DnsName google.com

# Display ARP cache
Get-NetNeighbor

# Display listening TCP ports
Get-NetTCPConnection -State Listen

# Find what is using a port
Get-NetTCPConnection -LocalPort 443 ```

Windows Firewall

``` # Firewall profiles
Get-NetFirewallProfile

# List firewall rules
Get-NetFirewallRule

# Find enabled inbound rules
Get-NetFirewallRule -Direction Inbound -Enabled True

# Create inbound TCP rule
New-NetFirewallRule -DisplayName "Allow Web 8080" -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow

# Remove firewall rule
Remove-NetFirewallRule -DisplayName "Allow Web 8080"

# Enable firewall
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True ```

Windows Event Logs

``` # List event logs
Get-WinEvent -ListLog *

# Latest System events
Get-WinEvent -LogName System -MaxEvents 20

# Latest Application events
Get-WinEvent -LogName Application -MaxEvents 20

# Show only errors
Get-WinEvent -LogName System | Where-Object {$_.LevelDisplayName -eq "Error"}

# Export events
Get-WinEvent -LogName System -MaxEvents 100 | Export-Csv system-events.csv -NoTypeInformation ```

Windows Registry

PowerShell exposes the Windows Registry through the registry provider. Use caution when modifying registry values.

``` # Browse registry
Get-ChildItem HKLM:\

# Browse Windows configuration
Get-ChildItem HKLM:\SOFTWARE\Microsoft\Windows

# Read registry key
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"

# Create registry key
New-Item -Path "HKCU:\Software\MyApp"

# Set registry value
New-ItemProperty -Path "HKCU:\Software\MyApp" -Name "Enabled" -Value 1 ```

Environment Variables

``` # List environment variables
Get-ChildItem Env:

# Current computer name
$env:COMPUTERNAME

# Current username
$env:USERNAME

# PATH
$env:PATH

# Set environment variable for current session
$env:MY_VARIABLE = "Hello" ```

Scheduled Tasks

``` # List scheduled tasks
Get-ScheduledTask

# Get a specific task
Get-ScheduledTask -TaskName "MyTask"

# Run task immediately
Start-ScheduledTask -TaskName "MyTask"

# Stop task
Stop-ScheduledTask -TaskName "MyTask"

# Disable task
Disable-ScheduledTask -TaskName "MyTask"

# Enable task
Enable-ScheduledTask -TaskName "MyTask" ```

Remote Administration

PowerShell Remoting allows administrators to execute commands on remote Windows machines, normally using WinRM.

``` # Test WinRM connectivity
Test-WSMan SERVER01

# Run command remotely
Invoke-Command -ComputerName SERVER01 -ScriptBlock { Get-Service }

# Execute command on multiple servers
$servers = "SERVER01","SERVER02","SERVER03"
Invoke-Command -ComputerName $servers -ScriptBlock { hostname }

# Open interactive remote session
Enter-PSSession -ComputerName SERVER01

# Exit remote session
Exit-PSSession ```

Disk & Storage Management

``` # List disks
Get-Disk

# List partitions
Get-Partition

# List volumes
Get-Volume

# Check free space
Get-Volume | Select-Object DriveLetter,FileSystemLabel,Size,SizeRemaining

# Find large files
Get-ChildItem C:\ -File -Recurse -ErrorAction SilentlyContinue | Sort-Object Length -Descending | Select-Object -First 20 FullName,Length ```

Software & Windows Features

``` # List installed Windows capabilities
Get-WindowsCapability -Online

# List Windows optional features
Get-WindowsOptionalFeature -Online

# Find a feature
Get-WindowsOptionalFeature -Online | Where-Object {$_.FeatureName -like "*Telnet*"}

# Enable Windows feature
Enable-WindowsOptionalFeature -Online -FeatureName TelnetClient

# Disable Windows feature
Disable-WindowsOptionalFeature -Online -FeatureName TelnetClient ```

SysAdmin Automation

PowerShell becomes especially useful when repetitive administrative tasks are converted into scripts.

``` # Check several servers
$servers = @("SERVER01","SERVER02","SERVER03")

foreach ($server in $servers) {
    if (Test-Connection $server -Count 1 -Quiet) {
        Write-Output "$server is ONLINE"
    } else {
        Write-Output "$server is OFFLINE"
    }
} ```

Useful SysAdmin Scripts

Check Disk Space

``` $volumes = Get-Volume | Where-Object {$_.DriveLetter}

foreach ($volume in $volumes) {
    $free = [math]::Round($volume.SizeRemaining / 1GB, 2)
    $total = [math]::Round($volume.Size / 1GB, 2)

    Write-Output "$($volume.DriveLetter): $free GB free of $total GB"
} ```

Find Stopped Services

``` Get-Service |
Where-Object {$_.Status -eq "Stopped"} |
Select-Object Name,DisplayName,Status ```

Export System Information

``` $info = [PSCustomObject]@{
    ComputerName = $env:COMPUTERNAME
    User = $env:USERNAME
    OS = (Get-CimInstance Win32_OperatingSystem).Caption
    LastBoot = (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
}

$info | Export-Csv system-info.csv -NoTypeInformation ```

Monitor a Service

``` $service = Get-Service -Name "Spooler"

if ($service.Status -ne "Running") {
    Start-Service -Name "Spooler"
    Write-Output "Spooler was restarted."
}
else {
    Write-Output "Spooler is running."
} ```

Generate a Server Report

``` $report = [PSCustomObject]@{
    ComputerName = $env:COMPUTERNAME
    OS = (Get-CimInstance Win32_OperatingSystem).Caption
    CPU = (Get-CimInstance Win32_Processor).Name
    RAM_GB = [math]::Round((Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1GB, 2)
    IP = (Get-NetIPAddress -AddressFamily IPv4 | Where-Object {$_.IPAddress -notlike "127.*"}).IPAddress -join ", "
}

$report | Format-List ```

Important Notes

  • PowerShell works primarily with objects, not plain text.
  • The pipeline | is one of the most important PowerShell features.
  • Use Get-Help and Get-Command to discover PowerShell functionality.
  • Run administrative commands from an elevated PowerShell session when required.
  • Use -WhatIf when available before performing destructive operations.
  • Use -Confirm when you want PowerShell to ask before performing a potentially destructive operation.
  • Use -ErrorAction Stop when errors need to be handled by try/catch.
  • Be careful when modifying the Windows Registry.
  • Be careful when changing firewall rules, network configuration, services, and permissions on production servers.
  • PowerShell scripts normally use the .ps1 extension.
  • PowerShell execution policy can affect whether scripts are allowed to run.
  • PowerShell 7 and Windows PowerShell 5.1 are different editions; some modules and commands differ between them.

Useful Safety Options

``` # See whether a command supports WhatIf
Get-Help Remove-Item -Parameter WhatIf

# Preview a potentially destructive operation
Remove-Item C:\Temp\*.log -WhatIf

# Ask for confirmation
Remove-Item C:\Temp\*.log -Confirm ```

Execution Policy

``` # View execution policies
Get-ExecutionPolicy -List

# View current policy
Get-ExecutionPolicy ```