PowerShell

#23
TIOBE#44
PYPL#18
GitHub#23
RedMonk#18
programming languagescripting languagesystem administrationautomationMicrosoftcross-platform

Programming Language

PowerShell

Overview

PowerShell is an object-oriented command-line shell and scripting language developed by Microsoft.

Details

PowerShell is a task-based command-line shell and scripting language developed by Jeffrey Snover at Microsoft in 2006, built on the .NET Framework. Unlike traditional text-based shells, its key feature is the ability to directly manipulate .NET objects. The evolution from Windows PowerShell to PowerShell Core (now PowerShell 7+) enabled cross-platform operation on Windows, Linux, and macOS. It is widely used in system administration, automation, DevOps, and cloud management, providing rich cmdlets and powerful pipeline functionality.

Code Examples

Hello World

# Basic output
Write-Host "Hello, World!"

# Output using variables
$message = "Hello, PowerShell!"
Write-Host $message

# Formatted output
$name = "John"
$age = 25
Write-Host "My name is $name and I am $age years old."

# Array output
$fruits = @("apple", "banana", "orange")
Write-Host "Fruits: $($fruits -join ', ')"

# Multiple output methods
"Simple string output"
Write-Output "Send to pipeline"
Write-Information "Information message" -InformationAction Continue

Variables and Data Types

# Scalar variables
$number = 42
$float = 3.14
$string = "string"
$boolean = $true

# Arrays
$fruits = @("apple", "banana", "orange")
$numbers = @(1, 2, 3, 4, 5)
$mixed = @("string", 42, $true)

# Hash tables (associative arrays)
$person = @{
    Name = "John Doe"
    Age = 30
    City = "Tokyo"
}

# Strict type specification
[int]$integerVar = 100
[string]$stringVar = "Type-specified string"
[datetime]$dateVar = Get-Date

# Special array creation methods
$range = 1..10           # Consecutive numbers from 1 to 10
$letters = 'A'..'Z'      # Letters from A to Z

Write-Host "Number: $number"
Write-Host "Array count: $($fruits.Count)"
Write-Host "Hash table value: $($person.Name)"
Write-Host "Type info: $($number.GetType().Name)"

Conditional Statements

# Basic if statement
$score = 85
$grade = ""

if ($score -ge 90) {
    $grade = "A"
} elseif ($score -ge 80) {
    $grade = "B"
} elseif ($score -ge 70) {
    $grade = "C"
} else {
    $grade = "D"
}

Write-Host "Score: $score, Grade: $grade"

# Multiple condition combinations
$age = 20
$hasLicense = $true

if ($age -ge 18 -and $hasLicense) {
    Write-Host "You can drive"
} elseif ($age -ge 18) {
    Write-Host "Please get a license"
} else {
    Write-Host "Please get a license after turning 18"
}

# switch statement
$day = "Wednesday"
switch ($day) {
    "Monday" { Write-Host "Start of the week" }
    "Wednesday" { Write-Host "Midweek" }
    "Friday" { Write-Host "Almost weekend" }
    default { Write-Host "Other day" }
}

# Comparison operator examples
$value = 10
if ($value -eq 10) { "Equal" }
if ($value -ne 5) { "Not equal" }
if ($value -gt 5) { "Greater than" }
if ($value -lt 20) { "Less than" }
if ("Hello" -like "He*") { "Pattern match" }
if ("[email protected]" -match "\w+@\w+\.\w+") { "Regex match" }

Arrays and Hash Tables

# Array operations
$fruits = @("apple", "banana", "orange")

# Adding elements
$fruits += "grape"
$fruits = $fruits + @("strawberry", "melon")

# Accessing array elements
Write-Host "First fruit: $($fruits[0])"
Write-Host "Last fruit: $($fruits[-1])"
Write-Host "First 3: $($fruits[0..2] -join ', ')"

# Array operation methods
$fruits | ForEach-Object { Write-Host "Fruit: $_" }
$longFruits = $fruits | Where-Object { $_.Length -gt 5 }
Write-Host "Fruits longer than 5 chars: $($longFruits -join ', ')"

# Hash table operations
$person = @{
    Name = "John Doe"
    Age = 30
    City = "Tokyo"
}

# Adding new key-value pairs
$person.Job = "Engineer"
$person["Hobby"] = "Reading"

# Check key existence
if ($person.ContainsKey("Age")) {
    Write-Host "Age: $($person.Age)"
}

# Get all keys and values
foreach ($key in $person.Keys) {
    Write-Host "$key : $($person[$key])"
}

# Convert hash table to arrays
$keys = $person.Keys
$values = $person.Values
Write-Host "Keys: $($keys -join ', ')"

Loops and Iteration

# ForEach-Object (pipeline)
1..5 | ForEach-Object {
    Write-Host "$_ squared is $($_ * $_)"
}

# for loop
for ($i = 1; $i -le 5; $i++) {
    Write-Host "$i squared is $($i * $i)"
}

# foreach loop
$numbers = @(1, 2, 3, 4, 5)
foreach ($num in $numbers) {
    $double = $num * 2
    Write-Host "Number: $num, Double: $double"
}

# while loop
$count = 0
while ($count -lt 5) {
    Write-Host "Count: $count"
    $count++
}

# do-while loop
$counter = 0
do {
    $counter++
    Write-Host "Execution count: $counter"
} while ($counter -lt 3)

# Array loop with index
for ($i = 0; $i -lt $fruits.Count; $i++) {
    Write-Host "Index $i : $($fruits[$i])"
}

Function Definition and Calling

# Basic function
function Get-Greeting {
    param([string]$Name)
    return "Hello, $Name!"
}

# Function with default parameters
function Get-Area {
    param(
        [int]$Width,
        [int]$Height = 10
    )
    return $Width * $Height
}

# Function returning multiple values
function Get-NameAge {
    return @("John Doe", 25)
}

# Advanced parameter definition
function Get-ProcessInfo {
    param(
        [Parameter(Mandatory=$true)]
        [string]$ProcessName,
        
        [Parameter()]
        [switch]$IncludeModules,
        
        [Parameter()]
        [ValidateSet("Name", "Id", "CPU")]
        [string]$SortBy = "Name"
    )
    
    $processes = Get-Process -Name $ProcessName -ErrorAction SilentlyContinue
    
    if ($IncludeModules) {
        return $processes | Select-Object Name, Id, Modules
    } else {
        return $processes | Select-Object Name, Id, CPU | Sort-Object $SortBy
    }
}

# Function calls
$message = Get-Greeting -Name "Alice"
Write-Host $message

$area = Get-Area -Width 5  # Height uses default value
Write-Host "Area: $area"

$name, $age = Get-NameAge
Write-Host "Name: $name, Age: $age"

Object-Oriented and Classes

# Class definition (PowerShell 5.0+)
class Car {
    [string]$Make
    [string]$Model
    [int]$Year
    [int]$Mileage = 0
    
    # Constructor
    Car([string]$make, [string]$model, [int]$year) {
        $this.Make = $make
        $this.Model = $model
        $this.Year = $year
    }
    
    # Method
    [void]Drive([int]$distance) {
        $this.Mileage += $distance
        Write-Host "Drove $distance km. Total mileage: $($this.Mileage) km"
    }
    
    [string]GetInfo() {
        return "$($this.Year) $($this.Make) $($this.Model)"
    }
    
    # Static method
    static [string]GetCarCount() {
        return "Function to get total car count"
    }
}

# Object creation and usage
$myCar = [Car]::new("Toyota", "Prius", 2022)
Write-Host $myCar.GetInfo()
$myCar.Drive(50)
$myCar.Drive(30)

# Custom object creation (PSCustomObject)
$customPerson = [PSCustomObject]@{
    Name = "Jane Smith"
    Age = 28
    Department = "Development"
}

$customPerson | Add-Member -MemberType ScriptMethod -Name "GetDescription" -Value {
    return "Name: $($this.Name), Age: $($this.Age), Department: $($this.Department)"
}

Write-Host $customPerson.GetDescription()

File Operations and Text Processing

# File creation and writing
$content = @"
This is a test file.
Learning file operations in PowerShell.
Can write multiple lines of text.
"@

$content | Out-File -FilePath "sample.txt" -Encoding UTF8

# File reading
$fileContent = Get-Content -Path "sample.txt" -Encoding UTF8
foreach ($line in $fileContent) {
    Write-Host "Read: $line"
}

# CSV format data processing
$csvData = @"
Name,Age,Job
John Doe,30,Engineer
Jane Smith,25,Designer
Bob Johnson,35,Manager
"@

$csvData | Out-File -FilePath "employees.csv" -Encoding UTF8

# CSV file reading and object conversion
$employees = Import-Csv -Path "employees.csv" -Encoding UTF8

foreach ($employee in $employees) {
    Write-Host "Name: $($employee.Name), Age: $($employee.Age), Job: $($employee.Job)"
}

# File system operations
$files = Get-ChildItem -Path "." -Filter "*.txt"
foreach ($file in $files) {
    Write-Host "File: $($file.Name), Size: $($file.Length) bytes"
}

# JSON data processing
$jsonData = @{
    Name = "API Response"
    Data = @(
        @{Id = 1; Title = "Item 1"},
        @{Id = 2; Title = "Item 2"}
    )
    Status = "Success"
}

$jsonString = $jsonData | ConvertTo-Json -Depth 3
Write-Host "JSON format:"
Write-Host $jsonString

$parsedJson = $jsonString | ConvertFrom-Json
Write-Host "After parsing: $($parsedJson.Name)"

System Administration and Cmdlets

# Process management
$processes = Get-Process | Where-Object { $_.CPU -gt 10 } | 
             Sort-Object CPU -Descending | 
             Select-Object -First 5 Name, CPU, WorkingSet

Write-Host "Top 5 CPU-intensive processes:"
$processes | Format-Table -AutoSize

# Service management
$services = Get-Service | Where-Object { $_.Status -eq "Running" } |
            Sort-Object Name |
            Select-Object Name, Status, StartType

Write-Host "Running services count: $($services.Count)"

# Network information
$networkAdapters = Get-NetAdapter | Where-Object { $_.Status -eq "Up" }
foreach ($adapter in $networkAdapters) {
    Write-Host "Adapter: $($adapter.Name), Speed: $($adapter.LinkSpeed)"
}

# Event log checking
$recentErrors = Get-EventLog -LogName System -EntryType Error -Newest 5 -ErrorAction SilentlyContinue
if ($recentErrors) {
    Write-Host "Recent system errors:"
    $recentErrors | Select-Object TimeGenerated, Source, Message | Format-Table -Wrap
}

# Registry operations
$regValue = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name "ProductName" -ErrorAction SilentlyContinue
if ($regValue) {
    Write-Host "Windows version: $($regValue.ProductName)"
}

Special Features

Pipeline and Filtering

# Powerful pipeline processing
Get-Process | 
    Where-Object { $_.ProcessName -like "chrome*" } |
    Sort-Object WorkingSet -Descending |
    Select-Object ProcessName, Id, @{Name="Memory(MB)"; Expression={[math]::Round($_.WorkingSet/1MB, 2)}} |
    Format-Table -AutoSize

# Array filtering and transformation
$numbers = 1..20
$evenSquares = $numbers | 
    Where-Object { $_ % 2 -eq 0 } |
    ForEach-Object { $_ * $_ }

Write-Host "Even squares: $($evenSquares -join ', ')"

# Grouping and aggregation
$files = Get-ChildItem -Path "C:\Windows\System32" -File -ErrorAction SilentlyContinue
$filesByExtension = $files | 
    Group-Object Extension |
    Sort-Object Count -Descending |
    Select-Object Name, Count

Write-Host "File count by extension:"
$filesByExtension | Format-Table -AutoSize

Error Handling

# try-catch-finally
try {
    $result = 10 / 0
    Write-Host "Result: $result"
}
catch [System.DivideByZeroException] {
    Write-Error "Attempted to divide by zero: $($_.Exception.Message)"
}
catch {
    Write-Error "Unexpected error: $($_.Exception.Message)"
}
finally {
    Write-Host "Processing completed"
}

# Error action setting
Get-Process -Name "NonExistentProcess" -ErrorAction SilentlyContinue
if (-not $?) {
    Write-Host "Process not found"
}

# Custom error generation
function Test-Value {
    param([int]$Value)
    
    if ($Value -lt 0) {
        throw [System.ArgumentException]::new("Value must be greater than or equal to 0")
    }
    
    return $Value * 2
}

Parallel Processing and Jobs

# Background jobs
$job1 = Start-Job -ScriptBlock { Start-Sleep 5; Get-Date }
$job2 = Start-Job -ScriptBlock { Start-Sleep 3; Get-Process | Measure-Object }

Write-Host "Jobs running..."
Wait-Job $job1, $job2

$result1 = Receive-Job $job1
$result2 = Receive-Job $job2

Write-Host "Job 1 result: $result1"
Write-Host "Job 2 result: Process count $($result2.Count)"

Remove-Job $job1, $job2

# Parallel processing (PowerShell 7+)
$servers = @("server1", "server2", "server3")
$servers | ForEach-Object -Parallel {
    # Virtual server response check
    Start-Sleep (Get-Random -Minimum 1 -Maximum 3)
    Write-Output "$_ : Response OK"
} -ThrottleLimit 3

Versions

Version Status Key Features Release Year
PowerShell 7.4 Latest Improved performance 2023
PowerShell 7.3 Current $PSStyle, class improvements 2022
PowerShell 7.2 LTS Cross-platform stabilization 2021
PowerShell 7.1 Current Experimental features, PSReadLine improvements 2020
PowerShell 7.0 Major .NET Core migration, Linux/macOS support 2020
Windows PowerShell 5.1 Legacy Windows standard, class support 2016

Reference Pages

Official Documentation

Learning Resources

Development Tools