PowerShell
Automation with objects, not text.
PowerShell is Microsoft's cross-platform shell and scripting language. Unlike traditional shells that pass text, PowerShell passes structured .NET objects through the pipeline. It is the standard tool for automating Windows, Microsoft 365 and Azure, and it runs on Linux and macOS too.
Why learn PowerShell?
If you work with Windows, Azure or Microsoft 365, PowerShell is the fastest way to automate it, including AI services on Azure.
- Objects in the pipeline: filter and sort by properties, no text parsing.
- Microsoft ecosystem: manage Windows, Azure, Entra ID and Microsoft 365.
- REST built in:
Invoke-RestMethodturns JSON APIs into objects.
Set up and run your first program
Windows includes Windows PowerShell 5.1; install PowerShell 7 (pwsh) for the modern cross-platform version.
winget install Microsoft.PowerShell # Windows
brew install powershell # macOS
pwsh ./hello.ps1$name = "Ada"
Write-Output "Hello, AI! Welcome to PowerShell, $name."Set-ExecutionPolicy -Scope CurrentUser RemoteSigned once.Variables and types
Variables start with $. Double-quoted strings expand variables; $( ) evaluates expressions inside strings.
$layers = 32
$model = "llama3.1"
[double]$params = 8.03e9
$gb = $params * 2 / 1e9
Write-Output "$model has $layers layers"
Write-Output "FP16 size: $([math]::Round($gb, 1)) GB"
$layers.GetType().Name # Int32Cmdlets and the object pipeline
Commands (cmdlets) use Verb-Noun names. Output is objects, so Where-Object, Sort-Object and Select-Object work on properties.
# Five largest files in a folder
Get-ChildItem -Recurse -File |
Sort-Object Length -Descending |
Select-Object -First 5 Name, @{n='MB'; e={[math]::Round($_.Length / 1MB, 1)}}
# Processes using the most memory
Get-Process | Sort-Object WorkingSet64 -Descending | Select-Object -First 3 Name, IdArrays, hashtables and objects
@( ) makes arrays and @{ } makes hashtables. [pscustomobject] creates objects you can pipe, sort and export.
$gpus = @(
[pscustomobject]@{ Name = "H100"; Vram = 80 }
[pscustomobject]@{ Name = "H200"; Vram = 141 }
[pscustomobject]@{ Name = "RTX 5090"; Vram = 32 }
)
$gpus | Where-Object Vram -ge 80 | ForEach-Object { "$($_.Name): $($_.Vram) GB" }
$prices = @{ H100 = 2.49; H200 = 3.29 }
$prices["H100"]
$gpus | Export-Csv gpus.csv -NoTypeInformationFunctions and parameters
Functions declare parameters with types, defaults and validation. Advanced functions behave like built-in cmdlets.
function Get-ModelParams {
param(
[Parameter(Mandatory)][int]$Layers,
[int]$Width = 4096
)
12 * $Layers * [long]$Width * $Width
}
function Test-Fits {
param([int]$ModelGB, [int]$VramGB)
if ($ModelGB -le $VramGB) { "fits" } else { "too big" }
}
Get-ModelParams -Layers 32
Test-Fits -ModelGB 16 -VramGB 24Errors and REST APIs
try/catch handles errors (use -ErrorAction Stop to make cmdlet errors catchable). Invoke-RestMethod calls web APIs and converts JSON to objects.
try {
$models = Invoke-RestMethod -Uri "http://localhost:11434/api/tags" -ErrorAction Stop
$models.models | Select-Object name, size
} catch {
Write-Warning "Ollama is not running: $($_.Exception.Message)"
}
$repo = Invoke-RestMethod "https://api.github.com/repos/pytorch/pytorch"
"PyTorch stars: $($repo.stargazers_count)"AI with PowerShell
PowerShell automates the infrastructure around AI: creating Azure OpenAI and Azure AI Foundry resources, managing GPU virtual machines, checking nvidia-smi on Windows servers and calling model APIs. Microsoft also offers AI helpers for the shell, and any OpenAI-compatible endpoint can be called with Invoke-RestMethod.
The essential libraries
Summarise files with a local LLM
Send each text file in a folder to a local model and save the summaries to CSV.
$url = "http://localhost:11434/v1/chat/completions"
$results = foreach ($file in Get-ChildItem *.txt) {
$text = Get-Content $file -Raw
$body = @{
model = "llama3.1"
messages = @(@{ role = "user"; content = "Summarise in one sentence:`n$text" })
} | ConvertTo-Json -Depth 5
$res = Invoke-RestMethod -Uri $url -Method Post -Body $body -ContentType "application/json"
[pscustomobject]@{ File = $file.Name; Summary = $res.choices[0].message.content }
}
$results | Export-Csv summaries.csv -NoTypeInformationBuild an AI agent in PowerShell
Because JSON becomes objects automatically, a tool-calling agent in PowerShell is short and readable.
$url = "http://localhost:11434/v1/chat/completions"
$tools = @(@{ type = "function"; function = @{ name = "get_disk_free"; description = "Free disk space in GB for a drive or mount"
parameters = @{ type = "object"; properties = @{ path = @{ type = "string" } }; required = @("path") } } })
function get_disk_free($path) {
$d = Get-PSDrive -PSProvider FileSystem | Where-Object { $path.StartsWith($_.Root) } | Select-Object -First 1
"{0:N1} GB free on {1}" -f ($d.Free / 1GB), $d.Root
}
$messages = [System.Collections.ArrayList]@(@{ role = "user"; content = "How much space is free on C:\ ?" })
for ($round = 0; $round -lt 5; $round++) {
$body = @{ model = "llama3.1"; messages = $messages; tools = $tools } | ConvertTo-Json -Depth 10
$msg = (Invoke-RestMethod -Uri $url -Method Post -Body $body -ContentType "application/json").choices[0].message
[void]$messages.Add($msg)
if (-not $msg.tool_calls) { $msg.content; break }
foreach ($call in $msg.tool_calls) {
$fnArgs = $call.function.arguments | ConvertFrom-Json
[void]$messages.Add(@{ role = "tool"; tool_call_id = $call.id; content = (get_disk_free $fnArgs.path) })
}
}Use -Depth 10 with ConvertTo-Json; the default depth truncates nested tool schemas.
ollama pull llama3.1, and keep it running. The code talks to its OpenAI-compatible API at http://localhost:11434/v1, so the same program also works with vLLM, llama.cpp server or a cloud API by changing the URL, model name and adding an API key.PowerShell learning roadmap
Tick items off as you go. Your progress is saved in this browser.
Beginner
Intermediate
Advanced
Projects to build
PowerShell cheat sheet
| Task | Syntax |
|---|---|
| Variable | $x = 5 |
| Help | Get-Help Get-Process -Examples |
| Filter | ... | Where-Object Size -gt 100 |
| Loop | foreach ($f in $files) { } |
| Object | [pscustomobject]@{ A = 1 } |
| REST | Invoke-RestMethod -Uri $u |
Common mistakes
- Comparison uses
-eq,-gt,-lt, not==or>(>redirects output). - ConvertTo-Json only goes 2 levels deep by default.
- Windows PowerShell 5.1 and PowerShell 7 differ; target pwsh 7 for new scripts.
Where to go next
- PowerShell docs — official
- PowerShell 101 — free book
- PowerShell Gallery — modules
On TensorCore.si: Bash volume, C# volume.
Keyboard: [ previous language · ] next language · / search the library