# Code Reference — PowerShell

_29 pages_

---
# PowerShell (/docs/powershell)



# PowerShell [#powershell]

Windows shell & automation.

Browse the sidebar for every cheat sheet in this section.

## Sections [#sections]

* [Examples](./examples)


---

# Aliases Basics (/docs/powershell/aliases-basics)



# Aliases Basics [#aliases-basics]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

**Aliases** are short names for commands (`ls` → `Get-ChildItem`, `cd` → `Set-Location`). They help newcomers from Bash/cmd, but scripts should prefer full cmdlet names for clarity and portability.

## 🔧 Core concepts [#-core-concepts]

| Idea             | Detail                                     |
| ---------------- | ------------------------------------------ |
| Built-in aliases | Ship with PowerShell                       |
| Custom aliases   | `Set-Alias` / `New-Alias` for your session |
| Discovery        | `Get-Alias`, `Alias:` drive                |
| Good practice    | Use full names in `.ps1` files             |
| Gal              | Alias for `Get-Alias`                      |

Aliases do not support custom parameters the way functions do — use a function for anything non-trivial.

## 💡 Examples [#-examples]

**Common aliases:**

```powershell
ls          # Get-ChildItem
cd $HOME    # Set-Location
pwd         # Get-Location
cat file.txt  # Get-Content (if file exists)
echo "hi"   # Write-Output
```

**Resolve an alias:**

```powershell
Get-Alias ls
Get-Alias | Where-Object Definition -Match "ChildItem"
Get-Command ls
```

**Create a temporary alias:**

```powershell
Set-Alias -Name npp -Value notepad
# npp .\readme.md
Get-Alias npp
```

**Prefer full names in scripts:**

```powershell
# Good in scripts
Get-ChildItem -Path . -File

# Fine interactively
ls -File
```

## ⚠️ Pitfalls [#️-pitfalls]

* `curl` may alias to `Invoke-WebRequest` in Windows PowerShell — very different from real curl.
* Aliases you set in a session vanish unless added to your profile.
* Overloading familiar names can confuse teammates.
* Aliases are not expanded in all remoting / constrained sessions the same way.

## 🔗 Related [#-related]

* [getting\_started.md](/docs/powershell/getting-started)
* [get\_help.md](/docs/powershell/get-help)
* [providers\_basics.md](/docs/powershell/providers-basics)
* [cmdlets.md](/docs/powershell/cmdlets)


---

# Cmdlets (/docs/powershell/cmdlets)



# Cmdlets [#cmdlets]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Cmdlets are PowerShell’s native commands: Verb-Noun names, structured objects as output, and common parameters (`-ErrorAction`, `-WhatIf`, …). Discover them with `Get-Command`, learn them with `Get-Help`, and inspect objects with `Get-Member`.

## 🔧 Core concepts [#-core-concepts]

| Idea          | Detail                                                      |
| ------------- | ----------------------------------------------------------- |
| Naming        | Approved verbs: `Get`, `Set`, `New`, `Remove`, `Add`, …     |
| Discovery     | `Get-Command *item*`, `Get-Alias`                           |
| Help          | `Get-Help cmd -Full`, `Update-Help`                         |
| Members       | `Get-Member` / `gm`                                         |
| Common params | `-Verbose`, `-Debug`, `-ErrorAction`, `-WhatIf`, `-Confirm` |
| Parameters    | Positional or named; tab-completion helps                   |
| Modules       | Cmdlets ship in modules (`Get-Module -ListAvailable`)       |

Aliases (`gci` → `Get-ChildItem`) are fine interactively; prefer full names in scripts.

## 💡 Examples [#-examples]

**Discover and inspect:**

```powershell
Get-Command -Noun Process
Get-Help Get-Process -Examples
Get-Process | Get-Member
Get-Process pwsh | Select-Object Name, Id, CPU
```

**Common parameters:**

```powershell
Remove-Item .\tmp\* -Recurse -WhatIf
Copy-Item .\a.txt .\b.txt -ErrorAction Stop
Get-ChildItem -Verbose
```

**Approved verb pattern (advanced function):**

```powershell
function Get-Something {
  [CmdletBinding()]
  param([string]$Name)
  process { "Hello $Name" }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* External programs return strings/exit codes—not objects—unless you parse them.
* Aliases differ across platforms; scripts should use canonical cmdlet names.
* `-Confirm` / `-WhatIf` only work when the command supports `SupportsShouldProcess`.
* Parameter binding errors often mean pipeline input type mismatch—check `Get-Help -Parameter`.
* `curl` / `wget` may be aliases to `Invoke-WebRequest` on Windows PowerShell 5.1.
* Don’t assume Linux binaries exist in Windows PowerShell sessions.

## 🔗 Related [#-related]

* [pipeline.md](/docs/powershell/pipeline)
* [objects.md](/docs/powershell/objects)
* [modules.md](/docs/powershell/modules)
* [useful\_commands.md](/docs/powershell/useful-commands)
* [scripting.md](/docs/powershell/scripting)


---

# Conditionals (/docs/powershell/conditionals)



# Conditionals [#conditionals]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Branch with `if` / `elseif` / `else`, `switch`, and ternary (`? :` in PowerShell 7+). Comparison operators are letter-based (`-eq`, `-lt`, …) and case-insensitive by default for strings. Use `-match` for regex and `-in` / `-contains` for membership.

## 🔧 Core concepts [#-core-concepts]

| Operator                 | Meaning                     |
| ------------------------ | --------------------------- |
| `-eq -ne`                | Equal / not equal           |
| `-lt -le -gt -ge`        | Ordering                    |
| `-like -notlike`         | Wildcard                    |
| `-match -notmatch`       | Regex (`$matches`)          |
| `-in -notin`             | Item in collection          |
| `-contains -notcontains` | Collection contains item    |
| `-and -or -not` / `!`    | Logic                       |
| `switch`                 | Multi-branch / regex / file |

Null-conditional: `$x?.Prop`. Null-coalescing: `$x ?? 'default'` (PS 7+).

## 💡 Examples [#-examples]

**If / elseif:**

```powershell
if ($null -eq $path) {
  throw 'path required'
} elseif (Test-Path $path -PathType Leaf) {
  'file'
} else {
  'missing or directory'
}
```

**Switch:**

```powershell
switch -Regex ($name) {
  '^ERROR'   { 'err'; break }
  '^WARN'    { 'warn'; break }
  default    { 'info' }
}
```

**Ternary and null coalesce (PS 7+):**

```powershell
$mode = $IsWindows ? 'win' : 'unix'
$port = $env:PORT ?? '8080'
```

**Membership:**

```powershell
if ($ext -in @('.jpg', '.png')) { 'image' }
if (@(1,2,3) -contains 2) { 'yes' }
```

## ⚠️ Pitfalls [#️-pitfalls]

* Put `$null` on the left: `$null -eq $x` avoids array comparison surprises.
* `-contains` is for collections on the **left**; `-in` reads more naturally for scalars.
* String compares are case-insensitive unless you use `-ceq` / `-clike` / `-cmatch`.
* `if (@())` is false; `if @(0)` is true (non-empty array)—don’t confuse with truthiness of elements.
* Assignment inside conditions is uncommon; `=` is not comparison—use `-eq`.
* `switch` falls through without `break` in some modes—be explicit.

## 🔗 Related [#-related]

* [variables.md](/docs/powershell/variables)
* [loops.md](/docs/powershell/loops)
* [error\_handling.md](/docs/powershell/error-handling)
* [pipeline.md](/docs/powershell/pipeline)
* [vs\_bash.md](/docs/powershell/vs-bash)


---

# Error Handling (/docs/powershell/error-handling)



# Error Handling [#error-handling]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

PowerShell has terminating and non-terminating errors. Use `-ErrorAction`, `try/catch/finally`, and `$Error` to control behavior. Prefer terminating errors for scripts that must stop; use `-ErrorVariable` to capture without stopping.

## 🔧 Core concepts [#-core-concepts]

| Mechanism                | Role                                                        |
| ------------------------ | ----------------------------------------------------------- |
| Non-terminating          | Writes to error stream; continues                           |
| Terminating              | Stops statement / enters `catch`                            |
| `-ErrorAction`           | `Stop`, `Continue`, `SilentlyContinue`, `Inquire`, `Ignore` |
| `$ErrorActionPreference` | Default for non-terminating                                 |
| `try / catch / finally`  | Structured handling                                         |
| `throw` / `Write-Error`  | Raise errors                                                |
| `$Error`                 | Automatic error list                                        |
| `$LASTEXITCODE`          | Native command exit code                                    |

`catch [System.IO.IOException]` filters by type. `$PSItem` / `$_` in `catch` is the error record.

## 💡 Examples [#-examples]

**Try/catch:**

```powershell
try {
  Get-Content -LiteralPath .\missing.txt -ErrorAction Stop
} catch {
  Write-Error "Failed: $($_.Exception.Message)"
} finally {
  'cleanup'
}
```

**Capture without stop:**

```powershell
Get-ChildItem .\nope -ErrorAction SilentlyContinue -ErrorVariable e
if ($e) { $e | ForEach-Object Message }
```

**Native commands:**

```powershell
git rev-parse HEAD
if ($LASTEXITCODE -ne 0) { throw "git failed: $LASTEXITCODE" }
```

**Preference scope:**

```powershell
$ErrorActionPreference = 'Stop'
```

## ⚠️ Pitfalls [#️-pitfalls]

* Default `-ErrorAction Continue` means scripts keep going after many failures.
* `try/catch` only catches terminating errors—add `-ErrorAction Stop` to cmdlets.
* Swallowing errors with `SilentlyContinue` hides root causes.
* `$Error[0]` is the newest; clear carefully (`$Error.Clear()`).
* Mixing `throw` strings vs `ErrorRecord` changes catch behavior slightly.
* Pipeline errors may not abort the whole pipeline unless preference is `Stop`.

## 🔗 Related [#-related]

* [cmdlets.md](/docs/powershell/cmdlets)
* [scripting.md](/docs/powershell/scripting)
* [functions.md](/docs/powershell/functions)
* [jobs.md](/docs/powershell/jobs)
* [conditionals.md](/docs/powershell/conditionals)


---

# Examples (/docs/powershell/examples)



# Examples [#examples]

PowerShell notes in **Examples**.


---

# Export CSV Report (/docs/powershell/examples/export-csv-report)



# Export CSV Report [#export-csv-report]

*Powershell · Example / how-to*

***

## 📋 Overview [#-overview]

Query objects, project columns, and export a CSV report with `Export-Csv` and UTF-8 encoding.

## 🔧 Core concepts [#-core-concepts]

| Piece                | Role                            |
| -------------------- | ------------------------------- |
| `Select-Object`      | Choose / rename columns         |
| `Export-Csv`         | Write spreadsheet-friendly file |
| `-NoTypeInformation` | Cleaner CSV header              |
| Pipeline             | Compose filters                 |

## 💡 Examples [#-examples]

**export\_csv\_report.ps1:**

```powershell
param(
    [string]$OutFile = ".\report.csv",
    [int]$Top = 50
)

$ErrorActionPreference = "Stop"

$rows = Get-ChildItem -Path $PSScriptRoot -File -Recurse -ErrorAction SilentlyContinue |
    Where-Object { $_.Extension -in ".md", ".ps1", ".ts", ".py" } |
    Sort-Object Length -Descending |
    Select-Object -First $Top @{
        Name = "RelativePath"
        Expression = { $_.FullName.Substring($PSScriptRoot.Length).TrimStart("\") }
    }, Length, LastWriteTime, Extension

$rows | Export-Csv -Path $OutFile -NoTypeInformation -Encoding utf8

Write-Host "Wrote $($rows.Count) rows to $OutFile"
```

**From process list:**

```powershell
Get-Process |
  Select-Object Name, Id, CPU, WorkingSet |
  Export-Csv .\processes.csv -NoTypeInformation -Encoding utf8
```

## ⚠️ Pitfalls [#️-pitfalls]

* Default encoding can confuse Excel — prefer `-Encoding utf8`.
* Nested objects become strings poorly — flatten with calculated properties.
* `Export-Csv` overwrites by default; confirm the path in scripts.

## 🔗 Related [#-related]

* [REST get JSON](/docs/powershell/examples/rest-get-json)
* [Watch folder](/docs/powershell/examples/watch-folder)


---

# REST Get JSON (/docs/powershell/examples/rest-get-json)



# REST Get JSON [#rest-get-json]

*Powershell · Example / how-to*

***

## 📋 Overview [#-overview]

Call a JSON REST API with `Invoke-RestMethod`, handle errors, and select fields from the response.

## 🔧 Core concepts [#-core-concepts]

| Piece               | Role                     |
| ------------------- | ------------------------ |
| `Invoke-RestMethod` | Parse JSON automatically |
| Headers             | Accept / auth            |
| try/catch           | Surface HTTP errors      |
| Pipeline select     | Shape output             |

## 💡 Examples [#-examples]

**rest\_get\_json.ps1:**

```powershell
param(
    [string]$UserId = "1"
)

$ErrorActionPreference = "Stop"
$url = "https://jsonplaceholder.typicode.com/users/$UserId"

try {
    $user = Invoke-RestMethod -Uri $url -Method Get -Headers @{
        Accept = "application/json"
    }
} catch {
    Write-Error "Request failed: $($_.Exception.Message)"
    exit 1
}

[pscustomobject]@{
    Id    = $user.id
    Name  = $user.name
    Email = $user.email
    City  = $user.address.city
} | Format-List
```

**With token:**

```powershell
$token = $env:API_TOKEN
Invoke-RestMethod -Uri "https://api.example.com/v1/items" -Headers @{
    Authorization = "Bearer $token"
    Accept        = "application/json"
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Secrets in scripts should come from env vars / secret stores, not literals.
* `Invoke-WebRequest` returns raw response; prefer `Invoke-RestMethod` for JSON.
* TLS / proxy issues often need `[Net.ServicePointManager]` only as a last resort.

## 🔗 Related [#-related]

* [Export CSV report](/docs/powershell/examples/export-csv-report)
* [Watch folder](/docs/powershell/examples/watch-folder)


---

# Watch Folder (/docs/powershell/examples/watch-folder)



# Watch Folder [#watch-folder]

*Powershell · Example / how-to*

***

## 📋 Overview [#-overview]

Watch a directory for created/changed files using `FileSystemWatcher` and run a handler for each event.

## 🔧 Core concepts [#-core-concepts]

| Piece                  | Role                         |
| ---------------------- | ---------------------------- |
| `FileSystemWatcher`    | OS file change events        |
| `Register-ObjectEvent` | Subscribe in PowerShell      |
| Filter                 | Limit to extensions          |
| Debounce mindset       | Editors may fire many events |

## 💡 Examples [#-examples]

**watch\_folder.ps1:**

```powershell
param(
    [string]$Path = ".\inbox",
    [string]$Filter = "*.*"
)

$ErrorActionPreference = "Stop"
New-Item -ItemType Directory -Force -Path $Path | Out-Null

$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = (Resolve-Path $Path)
$watcher.Filter = $Filter
$watcher.IncludeSubdirectories = $false
$watcher.EnableRaisingEvents = $true

$action = {
    $name = $Event.SourceEventArgs.Name
    $change = $Event.SourceEventArgs.ChangeType
    $time = Get-Date -Format o
    Write-Host "[$time] $change :: $name"
}

$handlers = @(
    Register-ObjectEvent $watcher Created -Action $action
    Register-ObjectEvent $watcher Changed -Action $action
    Register-ObjectEvent $watcher Renamed -Action $action
)

Write-Host "Watching $($watcher.Path) (Ctrl+C to stop)"
try {
    while ($true) { Start-Sleep -Seconds 1 }
} finally {
    $handlers | ForEach-Object { Unregister-Event -SourceIdentifier $_.Name -ErrorAction SilentlyContinue }
    $watcher.EnableRaisingEvents = $false
    $watcher.Dispose()
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Some apps write via temp+rename — listen for `Renamed`/`Created`, not only `Changed`.
* Event storms: debounce in the action if you kick off heavy work.
* Always unregister events / dispose the watcher on exit.

## 🔗 Related [#-related]

* [Export CSV report](/docs/powershell/examples/export-csv-report)
* [REST get JSON](/docs/powershell/examples/rest-get-json)


---

# Execution Policy (/docs/powershell/execution-policy)



# Execution Policy [#execution-policy]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Execution policy is a safety gate controlling which scripts can run—not a security boundary. Policies differ by scope (Process, CurrentUser, LocalMachine). Prefer `RemoteSigned` for interactive machines; use process-scoped bypasses for CI without changing machine policy.

## 🔧 Core concepts [#-core-concepts]

| Policy         | Effect                              |
| -------------- | ----------------------------------- |
| `Restricted`   | No scripts                          |
| `AllSigned`    | Only signed scripts                 |
| `RemoteSigned` | Local OK; downloaded need signature |
| `Unrestricted` | Warn on remote; run                 |
| `Bypass`       | Nothing blocked                     |
| `Undefined`    | Defer to other scopes               |

| Scope          | Typical use          |
| -------------- | -------------------- |
| `Process`      | Current session only |
| `CurrentUser`  | Per-user registry    |
| `LocalMachine` | Machine-wide (admin) |

Zone Identifier alternate data streams mark “downloaded” files on Windows.

## 💡 Examples [#-examples]

**Inspect and set:**

```powershell
Get-ExecutionPolicy -List
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
```

**One-off bypass (CI / troubleshooting):**

```powershell
pwsh -ExecutionPolicy Bypass -File .\deploy.ps1
Set-ExecutionPolicy Bypass -Scope Process
```

**Unblock downloaded file:**

```powershell
Unblock-File -Path .\Install-Thing.ps1
Get-Item .\Install-Thing.ps1 -Stream *
```

## ⚠️ Pitfalls [#️-pitfalls]

* Execution policy does not stop a determined user (`powershell -Command`, bypass, copying contents).
* Group Policy may override your `Set-ExecutionPolicy`—check `-List`.
* USB/network files may still be treated as remote.
* Signing requires certificates and maintenance—don’t adopt `AllSigned` casually.
* On non-Windows, policies are largely `Unrestricted` / less relevant—still use `-File` carefully.
* Don’t set `LocalMachine` Bypass on shared workstations without need.

## 🔗 Related [#-related]

* [scripting.md](/docs/powershell/scripting)
* [profiles.md](/docs/powershell/profiles)
* [modules.md](/docs/powershell/modules)
* [error\_handling.md](/docs/powershell/error-handling)
* [useful\_commands.md](/docs/powershell/useful-commands)


---

# Functions (/docs/powershell/functions)



# Functions [#functions]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Functions encapsulate reusable logic. Advanced functions use `[CmdletBinding()]` to gain common parameters, pipeline binding, and `-WhatIf` support. Prefer Verb-Noun names and explicit `param()` blocks.

## 🔧 Core concepts [#-core-concepts]

| Feature            | Detail                                     |
| ------------------ | ------------------------------------------ |
| Simple             | `function Name \{ param(...) … \}`         |
| Advanced           | `[CmdletBinding()]` + `param` attributes   |
| Pipeline           | `ValueFromPipeline`, `process \{\}`        |
| Output             | Write objects; avoid `Write-Host` for data |
| Scope              | Functions see parent scope unless `local`  |
| Dynamic params     | Advanced scenarios                         |
| Comment-based help | `.SYNOPSIS` in comments                    |

Blocks: `begin`, `process`, `end`, `clean` (PS 7.3+). Use `process` for pipeline streaming.

## 💡 Examples [#-examples]

**Advanced function:**

```powershell
function Get-FileSizeMb {
  [CmdletBinding()]
  param(
    [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
    [Alias('FullName')]
    [string]$Path
  )
  process {
    $item = Get-Item -LiteralPath $Path
    [pscustomobject]@{
      Path = $item.FullName
      SizeMB = [math]::Round($item.Length / 1MB, 2)
    }
  }
}

Get-ChildItem *.log | Get-FileSizeMb
```

**ShouldProcess:**

```powershell
function Remove-OldLog {
  [CmdletBinding(SupportsShouldProcess)]
  param([string]$Path)
  if ($PSCmdlet.ShouldProcess($Path, 'Remove')) {
    Remove-Item -LiteralPath $Path
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `Write-Host` bypasses the pipeline—use `Write-Output` / implicit output for data.
* Forgetting `process \{\}` breaks per-object pipeline behavior (only runs once).
* `$args` is unstructured—prefer `param()`.
* Name collisions with cmdlets: use a module prefix or approved verbs.
* Returning arrays may get flattened—use `Write-Output -NoEnumerate` or unary comma when needed.
* Don’t use `exit` inside library functions; throw or return instead.

## 🔗 Related [#-related]

* [cmdlets.md](/docs/powershell/cmdlets)
* [pipeline.md](/docs/powershell/pipeline)
* [modules.md](/docs/powershell/modules)
* [error\_handling.md](/docs/powershell/error-handling)
* [scripting.md](/docs/powershell/scripting)


---

# Get-Help (/docs/powershell/get-help)



# Get-Help [#get-help]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`Get-Help` is the built-in manual for cmdlets, functions, and about topics. Learning to read help is faster than memorizing every parameter. Update help once so examples are available offline.

## 🔧 Core concepts [#-core-concepts]

| Command                   | Purpose                       |
| ------------------------- | ----------------------------- |
| `Get-Help Name`           | Show help for a command       |
| `Get-Help Name -Examples` | Example-focused view          |
| `Get-Help Name -Full`     | Complete help                 |
| `Get-Help Name -Online`   | Open web docs                 |
| `Update-Help`             | Download latest help files    |
| `Get-Command`             | Find commands by name/pattern |

Tab completion and `Get-Command *Item*` pair well with help.

## 💡 Examples [#-examples]

**Basic help:**

```powershell
Get-Help Get-ChildItem
Get-Help Get-ChildItem -Examples
Get-Help Get-ChildItem -Parameter Filter
```

**Discover commands then read help:**

```powershell
Get-Command *process*
Get-Help Get-Process -Full
```

**About topics (concepts):**

```powershell
Get-Help about_Pipelines
Get-Help about_Variables
Get-Help about_* | Select-Object -First 10
```

**Update help (may need admin for some scopes):**

```powershell
Update-Help -ErrorAction SilentlyContinue
```

## ⚠️ Pitfalls [#️-pitfalls]

* Fresh installs often have *minimal* help until `Update-Help` runs.
* Help for third-party modules only appears after the module is installed/imported.
* `-Online` needs a browser and network.
* Alias help: `Get-Help ls` works, but learning `Get-ChildItem` is clearer long-term.

## 🔗 Related [#-related]

* [getting\_started.md](/docs/powershell/getting-started)
* [hello\_world.md](/docs/powershell/hello-world)
* [aliases\_basics.md](/docs/powershell/aliases-basics)
* [cmdlets.md](/docs/powershell/cmdlets)


---

# Getting Started with PowerShell (/docs/powershell/getting-started)



# Getting Started with PowerShell [#getting-started-with-powershell]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

PowerShell is a cross-platform shell and scripting language from Microsoft. Commands are usually **cmdlets** named `Verb-Noun` (like `Get-ChildItem`). It works with .NET objects, not only text.

## 🔧 Core concepts [#-core-concepts]

| Idea             | Meaning                                  |
| ---------------- | ---------------------------------------- |
| Cmdlet           | Built-in command: `Get-Process`          |
| Pipeline         | Pass objects between commands with `\|`  |
| Object           | Structured data with properties/methods  |
| Profile          | Startup script for customizations        |
| Execution policy | Controls which scripts may run (Windows) |

Open **Windows PowerShell**, &#x2A;*PowerShell 7+** (`pwsh`), or the integrated terminal in VS Code / Cursor.

## 💡 Examples [#-examples]

**Version and help discovery:**

```powershell
$PSVersionTable.PSVersion
Get-Command Get-ChildItem
Get-Help Get-ChildItem -Examples
```

**List files (like `ls`):**

```powershell
Get-ChildItem
Get-ChildItem -Force
pwd
```

**Hello in the shell:**

```powershell
Write-Output "Hello from PowerShell"
"Hello" | Write-Host
```

**Simple script (`hello.ps1`):**

```powershell
Write-Output "Hello, World!"
```

```powershell
pwsh ./hello.ps1
```

## ⚠️ Pitfalls [#️-pitfalls]

* Execution policy may block scripts — see `Get-ExecutionPolicy`; fix carefully, not by disabling security blindly.
* Aliases like `ls` / `curl` may not match Linux behavior exactly.
* Windows PowerShell 5.1 ≠ PowerShell 7 — prefer `pwsh` when possible.
* Paths with spaces need quotes: `cd "C:\My Projects"`.

## 🔗 Related [#-related]

* [hello\_world.md](/docs/powershell/hello-world)
* [get\_help.md](/docs/powershell/get-help)
* [providers\_basics.md](/docs/powershell/providers-basics)
* [aliases\_basics.md](/docs/powershell/aliases-basics)


---

# Glossary (/docs/powershell/glossary)



# Glossary [#glossary]

*Powershell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Alphabetical glossary of core PowerShell terms for cmdlets, objects, pipelines, remoting, and scripting.

## 🔧 Core concepts [#-core-concepts]

| Term              | Definition                                                                           |                                                            |
| ----------------- | ------------------------------------------------------------------------------------ | ---------------------------------------------------------- |
| Alias             | An alternate short name for a cmdlet or function, such as `gci` for `Get-ChildItem`. |                                                            |
| Array             | An ordered collection of objects, often created with `@()` or comma lists.           |                                                            |
| Cmdlet            | A compiled .NET command following Verb-Noun naming, like `Get-Process`.              |                                                            |
| Common parameter  | Shared parameters such as `-ErrorAction` and `-Verbose` available on many commands.  |                                                            |
| Execution policy  | A setting that restricts which scripts may run on a machine.                         |                                                            |
| Filter            | A scriptblock used in the pipeline to include/exclude objects.                       |                                                            |
| Function          | A reusable named scriptblock defined with `function Name \{ \}`.                     |                                                            |
| Hash table        | A key/value map written as `@\{ Key = Value \}`.                                     |                                                            |
| Job               | A background task started with `Start-Job` or `-AsJob`.                              |                                                            |
| Member            | A property or method on a PowerShell object.                                         |                                                            |
| Module            | A package of commands loaded with `Import-Module`.                                   |                                                            |
| Object            | The structured .NET data item flowing through the PowerShell pipeline.               |                                                            |
| Parameter         | A named input to a command, often bound by name or position.                         |                                                            |
| Parameter binding | The process that maps pipeline input and arguments to parameters.                    |                                                            |
| Pipeline          | The \`                                                                               | \` chain that passes objects from one command to the next. |
| Profile           | A script that runs when a PowerShell host starts.                                    |                                                            |
| Provider          | A drive-like data store interface such as `FileSystem` or `Registry`.                |                                                            |
| PSCredential      | An object holding a username and secure password for auth.                           |                                                            |
| Remoting          | Running commands on remote machines via WinRM/`Invoke-Command`.                      |                                                            |
| Scope             | The visibility boundary for variables and functions (`Global`, `Script`, `Local`).   |                                                            |
| Scriptblock       | An anonymous block of code written as `\{ ... \}`.                                   |                                                            |
| Splatting         | Passing a hashtable of parameters with `@params`.                                    |                                                            |
| Switch            | A boolean parameter present when named, or a `switch` statement for branching.       |                                                            |
| Variable          | A named storage slot referenced as `$name`.                                          |                                                            |
| Verb-Noun         | The conventional cmdlet naming pattern (`Get-`, `Set-`, `New-`, …).                  |                                                            |
| WhatIf            | A common risk-mitigation switch that previews changes without applying them.         |                                                            |

## 💡 Examples [#-examples]

**Cmdlets and pipeline:**

```powershell
Get-ChildItem -Path . -Filter *.md |
  Where-Object { $_.Length -gt 1KB } |
  Select-Object Name, Length
```

**Splatting and functions:**

```powershell
function Get-Greeting {
  param([string]$Name)
  "Hello, $Name"
}
$params = @{ Name = "Ada" }
Get-Greeting @params
```

**Remoting:**

```powershell
Invoke-Command -ComputerName web01 -ScriptBlock {
  Get-Service nginx
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Confusing **text pipelines** (Bash) with **object pipelines** (PowerShell).
* Mixing **aliases** in scripts with full **cmdlet** names — aliases hurt readability.
* Treating **execution policy** as security boundary — it is a safety rail, not a sandbox.
* Equating &#x2A;*`$null`**, empty string, and empty array in conditionals — truthiness differs.
* Assuming **Where-Object** filters like SQL — it runs script logic per object.

## 🔗 Related [#-related]

* [cmdlets](/docs/powershell/cmdlets)
* [pipeline](/docs/powershell/pipeline)
* [functions](/docs/powershell/functions)
* [variables](/docs/powershell/variables)
* [modules](/docs/powershell/modules)
* [remoting](/docs/powershell/remoting)


---

# Hello World (/docs/powershell/hello-world)



# Hello World [#hello-world]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

PowerShell Hello World prints a string to the host. Use `Write-Output` (pipeline-friendly) or `Write-Host` (host UI). A `.ps1` script stores commands for reuse.

## 🔧 Core concepts [#-core-concepts]

| Piece          | Role                                                |
| -------------- | --------------------------------------------------- |
| `Write-Output` | Sends objects down the pipeline / to success stream |
| `Write-Host`   | Writes directly to the host UI                      |
| `.ps1`         | PowerShell script file                              |
| String         | `"Hello"` or `'Hello'`                              |
| Comment        | `#` starts a line comment                           |

For scripts that return data, prefer `Write-Output` (or just emit the value).

## 💡 Examples [#-examples]

**Interactive:**

```powershell
Write-Output "Hello, World!"
"Hello, World!"
```

**Script file (`hello.ps1`):**

```powershell
# hello.ps1
$name = "Ada"
Write-Output "Hello, $name!"
```

```powershell
pwsh ./hello.ps1
```

**Formatted string:**

```powershell
$version = $PSVersionTable.PSVersion
Write-Output "Hello from PowerShell $version"
```

**Write-Host vs Output:**

```powershell
Write-Host "visible on screen" -ForegroundColor Green
Write-Output "can be piped" | ForEach-Object { $_.ToUpper() }
```

## ⚠️ Pitfalls [#️-pitfalls]

* Double quotes expand `$variables`; single quotes do not.
* Running scripts may require a less restrictive execution policy in your user scope.
* `echo` is an alias for `Write-Output` — fine, but learn the real name.
* Saving with a wrong encoding can break non-ASCII characters.

## 🔗 Related [#-related]

* [getting\_started.md](/docs/powershell/getting-started)
* [get\_help.md](/docs/powershell/get-help)
* [variables.md](/docs/powershell/variables)
* [aliases\_basics.md](/docs/powershell/aliases-basics)


---

# Jobs (/docs/powershell/jobs)



# Jobs [#jobs]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Jobs run work in the background. Classic jobs (`Start-Job`) use separate processes; thread jobs (`Start-ThreadJob`) are lighter. PowerShell 7 also offers `ForEach-Object -Parallel`. Use jobs for fan-out, long tasks, and remoting aggregation.

## 🔧 Core concepts [#-core-concepts]

| Cmdlet                  | Role                         |
| ----------------------- | ---------------------------- |
| `Start-Job`             | Background process job       |
| `Start-ThreadJob`       | Same-process thread (module) |
| `Get-Job`               | List                         |
| `Wait-Job`              | Block until done             |
| `Receive-Job`           | Collect output               |
| `Remove-Job`            | Cleanup                      |
| `Stop-Job`              | Cancel                       |
| `Invoke-Command -AsJob` | Remote as job                |

Child jobs appear under parent job objects for remoting fan-out. Always `Receive-Job` + `Remove-Job` to avoid leaks.

## 💡 Examples [#-examples]

**Local jobs:**

```powershell
$j = Start-Job -ScriptBlock {
  Start-Sleep -Seconds 2
  Get-Date
}
Wait-Job $j | Out-Null
Receive-Job $j
Remove-Job $j
```

**ThreadJob:**

```powershell
Install-Module ThreadJob -Scope CurrentUser
$jobs = 1..5 | ForEach-Object {
  Start-ThreadJob { param($n) Start-Sleep 1; $n * 2 } -ArgumentList $_
}
$jobs | Wait-Job | Receive-Job
$jobs | Remove-Job
```

**Parallel foreach (PS 7+):**

```powershell
1..10 | ForEach-Object -Parallel {
  Invoke-RestMethod "https://httpbin.org/get?n=$_"
} -ThrottleLimit 4
```

## ⚠️ Pitfalls [#️-pitfalls]

* Jobs don’t share live variables with the parent—pass `-ArgumentList` or `$using:` (remote/parallel).
* Forgetting `Receive-Job` leaves output buffered and jobs in Completed state forever.
* `Start-Job` is heavy (new runspace/process)—prefer ThreadJob/parallel for many small tasks.
* Errors surface when receiving—check job `State` and `ChildJobs`.
* UI/host-interactive cmdlets fail inside jobs.
* Remoting jobs need sessions cleaned up (`Remove-PSSession`).

## 🔗 Related [#-related]

* [remoting.md](/docs/powershell/remoting)
* [loops.md](/docs/powershell/loops)
* [error\_handling.md](/docs/powershell/error-handling)
* [scripting.md](/docs/powershell/scripting)
* [pipeline.md](/docs/powershell/pipeline)


---

# JSON & CSV (/docs/powershell/json-csv)



# JSON & CSV [#json--csv]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

PowerShell converts between objects and text formats with `ConvertTo-Json` / `ConvertFrom-Json` and `Export-Csv` / `Import-Csv`. Prefer object pipelines over hand-rolled string parsing. Watch depth limits and type fidelity when round-tripping JSON.

## 🔧 Core concepts [#-core-concepts]

| Cmdlet             | Role                        |
| ------------------ | --------------------------- |
| `ConvertTo-Json`   | Objects → JSON string       |
| `ConvertFrom-Json` | JSON → objects              |
| `Get-Content -Raw` | Read whole file             |
| `Export-Csv`       | Objects → CSV file          |
| `Import-Csv`       | CSV → objects (all strings) |
| `ConvertTo-Csv`    | CSV as strings in pipeline  |

PowerShell 7+ improved JSON depth defaults and added `-AsHashtable`. CSV exports include type metadata comments unless `-NoTypeInformation` (default in PS 6+).

## 💡 Examples [#-examples]

**JSON:**

```powershell
$data = Get-Content -Raw .\config.json | ConvertFrom-Json
$data.Port = 8080
$data | ConvertTo-Json -Depth 6 | Set-Content -Path .\config.json -Encoding utf8

# PS 7+
$h = Get-Content -Raw .\config.json | ConvertFrom-Json -AsHashtable
```

**CSV:**

```powershell
Get-Process |
  Select-Object Name, Id, CPU |
  Export-Csv .\procs.csv -NoTypeInformation

Import-Csv .\procs.csv |
  Where-Object { [int]$_.Id -gt 1000 }
```

**REST body:**

```powershell
$body = @{ name = 'Ada'; roles = @('dev') } | ConvertTo-Json
```

## ⚠️ Pitfalls [#️-pitfalls]

* `ConvertTo-Json` truncates nested objects when `-Depth` is too low (default historically 2).
* `Import-Csv` properties are strings—cast numbers/dates explicitly.
* `Export-Csv` of `Format-Table` output is wrong—select objects first.
* Hashtable key order / `PSCustomObject` differences affect JSON shape.
* Large JSON: streaming parsers may be better than loading entirely.
* Encoding: prefer UTF-8 without unexpected BOM issues across tools.

## 🔗 Related [#-related]

* [objects.md](/docs/powershell/objects)
* [rest\_api.md](/docs/powershell/rest-api)
* [pipeline.md](/docs/powershell/pipeline)
* [useful\_commands.md](/docs/powershell/useful-commands)
* [scripting.md](/docs/powershell/scripting)


---

# Loops (/docs/powershell/loops)



# Loops [#loops]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

PowerShell provides `foreach`, `for`, `while`, `do/while`, `do/until`, and pipeline-oriented `ForEach-Object`. Prefer streaming pipelines for large collections; use `foreach` statements when you need `break`/`continue` with clearer scopes.

## 🔧 Core concepts [#-core-concepts]

| Loop                       | Use                           |
| -------------------------- | ----------------------------- |
| `foreach ($x in $coll)`    | Iterate collection            |
| `ForEach-Object`           | Pipeline iteration            |
| `for (;;) / for ($i=0; …)` | Index loops                   |
| `while` / `do`             | Condition-driven              |
| `break` / `continue`       | Control flow                  |
| `return`                   | Exit function (not just loop) |

`%` is an alias for `ForEach-Object`; `?` for `Where-Object`. In scripts, prefer full names.

## 💡 Examples [#-examples]

**foreach vs pipeline:**

```powershell
foreach ($f in Get-ChildItem .\logs -File) {
  if ($f.Length -eq 0) { continue }
  $f.FullName
}

Get-ChildItem .\logs -File | ForEach-Object {
  $_.Name.ToUpper()
}
```

**for / while:**

```powershell
for ($i = 0; $i -lt 3; $i++) { $i }

$n = 0
while ($n -lt 3) { $n++; $n }
```

**do/until:**

```powershell
do {
  $r = Get-Random -Maximum 5
} until ($r -eq 0)
```

**Parallel (PS 7+):**

```powershell
1..5 | ForEach-Object -Parallel {
  Start-Sleep -Seconds 1
  $_
} -ThrottleLimit 3
```

## ⚠️ Pitfalls [#️-pitfalls]

* `return` inside `ForEach-Object` acts like `continue` for the scriptblock in some mental models—actually it exits the scriptblock only; use carefully inside functions.
* Modifying a collection while enumerating it throws—copy first or collect changes.
* `foreach ($x in Get-ChildItem -Recurse)` can be huge; filter early.
* Pipeline `ForEach-Object -Parallel` has session/state limits—avoid shared mutable state.
* `$foreach` automatic variable exists inside `foreach` statements—don’t overwrite casually.
* Prefer `Where-Object` before heavy `ForEach-Object` work.

## 🔗 Related [#-related]

* [pipeline.md](/docs/powershell/pipeline)
* [conditionals.md](/docs/powershell/conditionals)
* [functions.md](/docs/powershell/functions)
* [jobs.md](/docs/powershell/jobs)
* [objects.md](/docs/powershell/objects)


---

# Modules (/docs/powershell/modules)



# Modules [#modules]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Modules package functions, cmdlets, and resources for reuse. Import with `Import-Module`; discover with `Get-Module -ListAvailable`. Prefer versioned modules from the PowerShell Gallery and explicit manifests (`.psd1`) for production.

## 🔧 Core concepts [#-core-concepts]

| Piece               | Role                              |
| ------------------- | --------------------------------- |
| `.psm1`             | Script module                     |
| `.psd1`             | Manifest (exports, deps, version) |
| `Import-Module`     | Load                              |
| `Remove-Module`     | Unload                            |
| `Get-Module`        | Loaded / available                |
| `Install-Module`    | From Gallery (PSGet)              |
| `$env:PSModulePath` | Search paths                      |
| Autoloading         | Commands trigger import           |

Export explicitly via `Export-ModuleMember` or manifest `FunctionsToExport`—avoid accidental exports.

## 💡 Examples [#-examples]

**Import and find:**

```powershell
Get-Module -ListAvailable | Select-Object Name, Version
Import-Module ThreadJob -Force
Get-Command -Module ThreadJob
```

**Install from Gallery:**

```powershell
Set-PSRepository PSGallery -InstallationPolicy Trusted
Install-Module -Name PSScriptAnalyzer -Scope CurrentUser
```

**Minimal module:**

```powershell
# MyUtils.psm1
function Get-Hello { 'hello' }
Export-ModuleMember -Function Get-Hello
```

```powershell
# MyUtils.psd1 (sketch)
@{
  RootModule = 'MyUtils.psm1'
  ModuleVersion = '1.0.0'
  FunctionsToExport = @('Get-Hello')
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Multiple versions on `PSModulePath`—pin with `-RequiredVersion` when needed.
* CurrentUser vs AllUsers install scopes (admin rights).
* Binary modules differ by edition (Windows PowerShell 5.1 vs PowerShell 7+).
* Dot-sourcing `.ps1` is not a module—state and exports behave differently.
* Gallery modules: review publishers; use `Install-Module -WhatIf` / checksums where required.
* Circular imports and side effects at import time make debugging hard—keep imports thin.

## 🔗 Related [#-related]

* [functions.md](/docs/powershell/functions)
* [cmdlets.md](/docs/powershell/cmdlets)
* [profiles.md](/docs/powershell/profiles)
* [scripting.md](/docs/powershell/scripting)
* [execution\_policy.md](/docs/powershell/execution-policy)


---

# Objects (/docs/powershell/objects)



# Objects [#objects]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Almost everything in PowerShell is a .NET object with properties and methods. Pipelines pass objects; formatting is a display concern. Use `Select-Object`, `Add-Member`, and custom `PSCustomObject` for shaping data.

## 🔧 Core concepts [#-core-concepts]

| Tool                     | Use                             |
| ------------------------ | ------------------------------- |
| `Get-Member`             | Discover properties/methods     |
| `.Property`              | Access property                 |
| `.Method()`              | Call method                     |
| `Select-Object`          | Calculated properties           |
| `[pscustomobject]@\{…\}` | Ad-hoc objects                  |
| `ConvertTo-Json`         | Serialize                       |
| ETS                      | Extended type system / adapters |

Common types: `String`, `Int32`, `DateTime`, `Hashtable`, `Array`, `PSCustomObject`, file/process/service objects from cmdlets.

## 💡 Examples [#-examples]

**Inspect and select:**

```powershell
Get-ChildItem | Get-Member -MemberType Property
Get-Process |
  Select-Object Name, Id, @{N='MemMB';E={[math]::Round($_.WS/1MB,1)}}
```

**Create objects:**

```powershell
$user = [pscustomobject]@{
  Name = 'Ada'
  Roles = @('admin', 'dev')
}
$user | Add-Member -NotePropertyName Active -NotePropertyValue $true
```

**Hashtable vs object:**

```powershell
$map = @{ a = 1; b = 2 }          # unordered dictionary
$obj = [pscustomobject]$map       # note: key order may vary pre-PS6
```

**Methods:**

```powershell
'hello'.ToUpper()
(Get-Date).AddDays(7)
```

## ⚠️ Pitfalls [#️-pitfalls]

* Hashtables are not `PSCustomObject`—property access and JSON shape differ.
* `Format-Table` output is not the original object—don’t pipe formats to `Export-Csv`.
* Value types vs references: arrays/hashtables are reference-like when passed around.
* `Select-Object -ExpandProperty` unwraps; without it you get objects with one property.
* Comparing objects with `-eq` often compares references or limited members—compare properties explicitly.
* Remote/serialized objects may be “deserialized” (methods stripped)—check `Get-Member`.

## 🔗 Related [#-related]

* [pipeline.md](/docs/powershell/pipeline)
* [json\_csv.md](/docs/powershell/json-csv)
* [cmdlets.md](/docs/powershell/cmdlets)
* [variables.md](/docs/powershell/variables)
* [remoting.md](/docs/powershell/remoting)


---

# Pipeline (/docs/powershell/pipeline)



# Pipeline [#pipeline]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The PowerShell pipeline passes **objects** (not text) between commands. ByValue and ByPropertyName binding decide how properties map to the next cmdlet’s parameters. Use `ForEach-Object`, `Where-Object`, and `Select-Object` as the core filters.

## 🔧 Core concepts [#-core-concepts]

| Piece                  | Role                                 |
| ---------------------- | ------------------------------------ |
| `\|`                   | Send objects downstream              |
| ByValue                | Entire object matches parameter type |
| ByPropertyName         | Property name matches parameter name |
| `$_` / `$PSItem`       | Current pipeline object              |
| `ForEach-Object` (`%`) | Per-object script                    |
| `Where-Object` (`?`)   | Filter                               |
| `Select-Object`        | Project / expand properties          |
| `Tee-Object`           | Copy to variable/file and continue   |

Begin/Process/End blocks in advanced functions enable true streaming.

## 💡 Examples [#-examples]

**Filter and project:**

```powershell
Get-ChildItem .\logs -File |
  Where-Object { $_.Length -gt 1MB } |
  Select-Object Name, Length, LastWriteTime |
  Sort-Object Length -Descending
```

**ForEach and Tee:**

```powershell
Get-Service |
  Where-Object Status -eq 'Running' |
  ForEach-Object { $_.Name } |
  Tee-Object -Variable names
```

**Property binding:**

```powershell
# Stop-Process binds -Id ByPropertyName
Get-Process notepad -ErrorAction SilentlyContinue |
  Stop-Process -WhatIf
```

**Collect vs stream:**

```powershell
# Parentheses collect all output first
(Get-ChildItem -Recurse).Count
```

## ⚠️ Pitfalls [#️-pitfalls]

* Wrapping a pipeline in `(…)` buffers everything—can exhaust memory on large sets.
* Native executables receive text; format may break object pipelines.
* `Format-*` cmdlets emit formatting objects—don’t pipe them to exporters; use `Select-Object` first.
* `ForEach-Object` vs `foreach` statement: the statement doesn’t stream in the same way.
* Nulls in the pipeline can surprise `-eq` filters; be explicit.
* Pipeline-bound parameters need correct attributes in custom functions.

## 🔗 Related [#-related]

* [cmdlets.md](/docs/powershell/cmdlets)
* [objects.md](/docs/powershell/objects)
* [loops.md](/docs/powershell/loops)
* [functions.md](/docs/powershell/functions)
* [vs\_bash.md](/docs/powershell/vs-bash)


---

# Profiles (/docs/powershell/profiles)



# Profiles [#profiles]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

A profile is a script that runs when a host starts. Use it for aliases, prompt customization, and module imports—keep it fast and idempotent. Different hosts (Console, VS Code, ISE) have separate profile paths.

## 🔧 Core concepts [#-core-concepts]

| Variable / cmdlet                    | Role                           |
| ------------------------------------ | ------------------------------ |
| `$PROFILE`                           | Current host current user path |
| `$PROFILE.AllUsersAllHosts`          | All users, all hosts           |
| `$PROFILE.CurrentUserAllHosts`       | Your user, all hosts           |
| `Test-Path $PROFILE`                 | Exists?                        |
| `New-Item $PROFILE -Force`           | Create                         |
| `notepad $PROFILE` / `code $PROFILE` | Edit                           |

Hosts: Windows PowerShell vs PowerShell 7 have different profile locations. Prefer `CurrentUserAllHosts` for shared settings across VS Code and terminal.

## 💡 Examples [#-examples]

**Create and open:**

```powershell
if (-not (Test-Path -Path $PROFILE)) {
  New-Item -Path $PROFILE -ItemType File -Force
}
ise $PROFILE   # or: code $PROFILE
```

**Lean profile sketch:**

```powershell
# $PROFILE.CurrentUserAllHosts
$ErrorActionPreference = 'Continue'
Set-PSReadLineOption -EditMode Windows
function prompt {
  "PS $($executionContext.SessionState.Path.CurrentLocation)> "
}
Import-Module posh-git -ErrorAction SilentlyContinue
```

**Measure startup cost:**

```powershell
Measure-Command { pwsh -NoLogo -Command exit }
Measure-Command { . $PROFILE }
```

## ⚠️ Pitfalls [#️-pitfalls]

* Heavy imports in the profile slow every shell—lazy-load or use modules on demand.
* Don’t put secrets in profiles; use SecretManagement / env vars.
* Editing the wrong `$PROFILE` host path leads to “changes not applying”.
* `-NoProfile` in automation skips profiles—scripts should not rely on them.
* Syntax errors in a profile can break interactive sessions—keep a backup.
* Avoid changing global machine state from a user profile.

## 🔗 Related [#-related]

* [modules.md](/docs/powershell/modules)
* [execution\_policy.md](/docs/powershell/execution-policy)
* [scripting.md](/docs/powershell/scripting)
* [useful\_commands.md](/docs/powershell/useful-commands)
* [variables.md](/docs/powershell/variables)


---

# Providers Basics (/docs/powershell/providers-basics)



# Providers Basics [#providers-basics]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

**Providers** expose hierarchical data stores as if they were drives: the filesystem, registry, environment variables, certificates, and more. You navigate them with familiar cmdlets like `Set-Location` and `Get-ChildItem`.

## 🔧 Core concepts [#-core-concepts]

| Provider / Drive  | What it surfaces       |
| ----------------- | ---------------------- |
| `FileSystem`      | Disks (`C:`, `/`)      |
| `Env:`            | Environment variables  |
| `HKLM:` / `HKCU:` | Registry (Windows)     |
| `Variable:`       | PowerShell variables   |
| `Alias:`          | Command aliases        |
| `Function:`       | Functions              |
| `Cert:`           | Certificates (Windows) |

`Get-PSProvider` and `Get-PSDrive` list what is available.

## 💡 Examples [#-examples]

**List providers and drives:**

```powershell
Get-PSProvider
Get-PSDrive
```

**Environment drive:**

```powershell
Set-Location Env:
Get-ChildItem | Select-Object -First 10
Get-Content PATH
Set-Location $HOME
```

**Filesystem navigation (same cmdlets):**

```powershell
Set-Location $HOME
Get-ChildItem
New-Item -ItemType Directory -Path .\ps-practice -Force
```

**Aliases drive:**

```powershell
Get-ChildItem Alias: | Where-Object Name -EQ "ls"
```

## ⚠️ Pitfalls [#️-pitfalls]

* Registry edits can break Windows — practice read-only first (`Get-ChildItem HKCU:\...`).
* Not every provider supports every cmdlet the same way.
* Paths like `Env:\PATH` differ from Bash `$PATH` syntax.
* Leaving yourself in `Env:` or `HKCU:` confuses later relative paths — `cd $HOME` when done.

## 🔗 Related [#-related]

* [getting\_started.md](/docs/powershell/getting-started)
* [aliases\_basics.md](/docs/powershell/aliases-basics)
* [get\_help.md](/docs/powershell/get-help)
* [variables.md](/docs/powershell/variables)


---

# Remoting (/docs/powershell/remoting)



# Remoting [#remoting]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

PowerShell Remoting runs commands on remote machines over WinRM (classic) or SSH (PowerShell 7+). Use `Enter-PSSession` for interactive work and `Invoke-Command` for one-shot or fan-out automation. Always consider authentication, double-hop limits, and serialization.

## 🔧 Core concepts [#-core-concepts]

| Cmdlet                 | Role                              |
| ---------------------- | --------------------------------- |
| `Enable-PSRemoting`    | Configure WinRM (Windows, admin)  |
| `Enter-PSSession`      | Interactive remote shell          |
| `Exit-PSSession`       | Leave                             |
| `Invoke-Command`       | Run scriptblock remotely          |
| `New-PSSession`        | Persistent session                |
| `Copy-Item -ToSession` | File transfer via session         |
| SSH remoting           | `New-PSSession -HostName` (PS 7+) |

CredSSP / JEA / Just Enough Admin address delegation and least privilege. Objects returned are often deserialized (methods removed).

## 💡 Examples [#-examples]

**Invoke on many hosts:**

```powershell
$servers = 'web1', 'web2'
Invoke-Command -ComputerName $servers -ScriptBlock {
  Get-Service sshd -ErrorAction SilentlyContinue |
    Select-Object Name, Status
}
```

**Persistent session:**

```powershell
$s = New-PSSession -ComputerName web1 -Credential (Get-Credential)
Invoke-Command -Session $s -ScriptBlock { $env:COMPUTERNAME }
Copy-Item -Path .\app.zip -Destination C:\Temp\ -ToSession $s
Remove-PSSession $s
```

**SSH (PS 7+):**

```powershell
Enter-PSSession -HostName ada@linux1 -SSHTransport
```

## ⚠️ Pitfalls [#️-pitfalls]

* Second hop: remote session can’t use your creds for a third machine without CredSSP/Kerberos delegation.
* Deserialized objects lack methods—rehydrate or rematerialize on the remote side.
* Firewall / WinRM service must allow connections; HTTPS listeners for untrusted networks.
* Large fan-out: throttle with sessions and error aggregation (`-ThrottleLimit`).
* Don’t embed plain passwords; use `Get-Credential`, SecretManagement, or managed identities.
* Linux remoting needs SSH configured; WinRM is Windows-centric.

## 🔗 Related [#-related]

* [jobs.md](/docs/powershell/jobs)
* [objects.md](/docs/powershell/objects)
* [error\_handling.md](/docs/powershell/error-handling)
* [scripting.md](/docs/powershell/scripting)
* [useful\_commands.md](/docs/powershell/useful-commands)


---

# REST API (/docs/powershell/rest-api)



# REST API [#rest-api]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Call HTTP APIs with `Invoke-RestMethod` (JSON → objects) or `Invoke-WebRequest` (full response). PowerShell 7 aligns more closely with modern TLS and HTTP defaults. Pass headers, bodies, and auth securely—never hard-code secrets.

## 🔧 Core concepts [#-core-concepts]

| Cmdlet                       | Best for                      |
| ---------------------------- | ----------------------------- |
| `Invoke-RestMethod`          | JSON/XML APIs → objects       |
| `Invoke-WebRequest`          | Status, headers, raw content  |
| `-Method`                    | GET, POST, PUT, PATCH, DELETE |
| `-Headers`                   | Auth and content negotiation  |
| `-Body`                      | String or byte body           |
| `-ContentType`               | e.g. `application/json`       |
| `-Authentication` / `-Token` | PS 7+ auth helpers            |
| `-SkipCertificateCheck`      | Dev only (PS 7+)              |

Use `ConvertTo-Json` for bodies and splatting for readable calls.

## 💡 Examples [#-examples]

**GET / POST JSON:**

```powershell
$base = 'https://api.example.com'
$headers = @{ Authorization = "Bearer $env:API_TOKEN" }

Invoke-RestMethod -Uri "$base/v1/users/me" -Headers $headers

$body = @{ name = 'Ada'; active = $true } | ConvertTo-Json
Invoke-RestMethod -Uri "$base/v1/users" -Method Post `
  -Headers $headers -ContentType 'application/json' -Body $body
```

**Splatting + status check:**

```powershell
$params = @{
  Uri = "$base/health"
  Method = 'Get'
  TimeoutSec = 30
}
$r = Invoke-WebRequest @params
$r.StatusCode
```

**PS 7 token auth:**

```powershell
$token = ConvertTo-SecureString $env:API_TOKEN -AsPlainText -Force
Invoke-RestMethod -Uri $uri -Authentication Bearer -Token $token
```

## ⚠️ Pitfalls [#️-pitfalls]

* Windows PowerShell 5.1 defaults to older TLS—enable TLS 1.2 if needed.
* `Invoke-RestMethod` throws on many error statuses; catch and read response bodies carefully.
* Secrets in history/transcripts—prefer env vars or SecretManagement.
* Proxy and corporate MITM certs break calls—configure correctly, don’t disable validation in prod.
* Rate limits: respect `Retry-After`; add backoff.
* Large downloads: prefer `Invoke-WebRequest -OutFile` or `curl`.

## 🔗 Related [#-related]

* [json\_csv.md](/docs/powershell/json-csv)
* [error\_handling.md](/docs/powershell/error-handling)
* [variables.md](/docs/powershell/variables)
* [scripting.md](/docs/powershell/scripting)
* [useful\_commands.md](/docs/powershell/useful-commands)


---

# Scripting (/docs/powershell/scripting)



# Scripting [#scripting]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Scripts are `.ps1` files with parameters, comment-based help, and controlled exit codes. Write them like advanced functions: explicit params, `$ErrorActionPreference = 'Stop'` when appropriate, and no dependency on an interactive profile.

## 🔧 Core concepts [#-core-concepts]

| Topic            | Practice                                 |
| ---------------- | ---------------------------------------- |
| Shebang (Unix)   | `#!/usr/bin/env pwsh`                    |
| Params           | `param(...)` at top                      |
| `$PSScriptRoot`  | Script directory                         |
| `$PSCommandPath` | Full script path                         |
| Exit             | `exit $code` for process status          |
| Requires         | `#Requires -Version 7` / `-Modules`      |
| Dot-source       | `. .\lib.ps1` imports into current scope |
| Call operator    | `& .\script.ps1`                         |

Use approved verbs for exported functions; keep scripts focused and testable.

## 💡 Examples [#-examples]

**Parameterized script:**

```powershell
<#
.SYNOPSIS
  Compress a folder.
#>
#Requires -Version 7
param(
  [Parameter(Mandatory)]
  [string]$Path,
  [string]$OutFile = "$PSScriptRoot\out.zip"
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

if (-not (Test-Path -LiteralPath $Path)) {
  throw "Path not found: $Path"
}
Compress-Archive -Path $Path -DestinationPath $OutFile -Force
Write-Output $OutFile
```

**Run:**

```powershell
pwsh -File .\backup.ps1 -Path .\data
pwsh -NoProfile -File .\backup.ps1 -Path .\data
```

**Shared library:**

```powershell
. "$PSScriptRoot\lib\helpers.ps1"
```

## ⚠️ Pitfalls [#️-pitfalls]

* Execution policy may block scripts—see [execution\_policy.md](/docs/powershell/execution-policy).
* Dot-sourcing mutates caller scope; prefer modules for libraries.
* Relative paths depend on the **caller's** location unless you use `$PSScriptRoot`.
* Mixing Windows PowerShell 5.1 and PS 7 syntax breaks portability—declare `#Requires`.
* Interactive prompts (`Read-Host`) fail in CI—require parameters instead.
* Don’t assume aliases from your profile exist in automation.

## 🔗 Related [#-related]

* [functions.md](/docs/powershell/functions)
* [error\_handling.md](/docs/powershell/error-handling)
* [execution\_policy.md](/docs/powershell/execution-policy)
* [modules.md](/docs/powershell/modules)
* [profiles.md](/docs/powershell/profiles)


---

# Useful Commands (/docs/powershell/useful-commands)



# Useful Commands [#useful-commands]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

A compact toolkit of high-frequency PowerShell commands for files, processes, networking, and discovery. Prefer cmdlets in scripts; aliases are fine interactively. PowerShell 7+ (`pwsh`) is recommended for cross-platform work.

## 🔧 Core concepts [#-core-concepts]

| Area    | Go-to cmdlets                                                                          |
| ------- | -------------------------------------------------------------------------------------- |
| Files   | `Get-ChildItem`, `Copy-Item`, `Move-Item`, `Remove-Item`, `Get-Content`, `Set-Content` |
| Search  | `Select-String`, `Where-Object`                                                        |
| Process | `Get-Process`, `Stop-Process`, `Start-Process`                                         |
| Net     | `Test-Connection`, `Test-NetConnection`, `Invoke-WebRequest`                           |
| System  | `Get-Service`, `Get-ComputerInfo` (Win)                                                |
| Help    | `Get-Help`, `Get-Command`, `Get-Member`                                                |
| Path    | `Join-Path`, `Resolve-Path`, `Split-Path`, `Test-Path`                                 |

Operators: `-replace`, `-split`, `-join`, redirection `>`, `>>`, `2>`, `*>`.

## 💡 Examples [#-examples]

**Files and search:**

```powershell
Get-ChildItem -Recurse -Filter *.md |
  Select-String -Pattern 'TODO' |
  Select-Object Path, LineNumber, Line

Get-Content .\app.log -Tail 50 -Wait
```

**Processes and ports (Win):**

```powershell
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10
Test-NetConnection example.com -Port 443
Get-NetTCPConnection -State Listen | Select-Object LocalPort, OwningProcess
```

**Quick JSON / clipboard (Win):**

```powershell
Invoke-RestMethod https://api.github.com/zen
Set-Clipboard (Get-Location).Path
```

**Discovery:**

```powershell
Get-Command *Item*
Get-Help about_Operators
```

## ⚠️ Pitfalls [#️-pitfalls]

* `rm`, `ls`, `cat` are aliases—behavior differs from GNU tools.
* `Remove-Item -Recurse` without `-Force` may prompt; in PS 5.1 `-Recurse` quirks exist—test first.
* `curl` alias confusion on Windows PowerShell 5.1.
* Prefer `-LiteralPath` when names contain `[` wildcards.
* Admin-required cmdlets fail silently or access-denied—check elevation.
* Don’t use `Write-Host` when you need pipeline data.

## 🔗 Related [#-related]

* [cmdlets.md](/docs/powershell/cmdlets)
* [pipeline.md](/docs/powershell/pipeline)
* [json\_csv.md](/docs/powershell/json-csv)
* [rest\_api.md](/docs/powershell/rest-api)
* [vs\_bash.md](/docs/powershell/vs-bash)


---

# Variables (/docs/powershell/variables)



# Variables [#variables]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Variables start with `$` and hold typed .NET objects. Scopes include `local`, `script`, `global`, and `private`. Prefer meaningful names; use `$script:` for module/script-level state and avoid polluting `$global:`.

## 🔧 Core concepts [#-core-concepts]

| Syntax                          | Meaning                                     |
| ------------------------------- | ------------------------------------------- |
| `$name = value`                 | Assign                                      |
| `$\{name-with-dashes\}`         | Unusual names                               |
| `$env:PATH`                     | Environment variable                        |
| `$null`                         | Null                                        |
| `Remove-Variable` / `rv`        | Delete                                      |
| `Get-Variable`                  | Inspect                                     |
| `Set-Variable -Option ReadOnly` | Protect                                     |
| `$true` / `$false`              | Booleans                                    |
| `[int]$n = 5`                   | Constrained type                            |
| `$$` / `$^`                     | Last/first token of last line (interactive) |

Automatic variables: `$_`, `$PSItem`, `$args`, `$PSScriptRoot`, `$PSCommandPath`, `$LASTEXITCODE`, `$?`, `$Error`.

## 💡 Examples [#-examples]

**Types and env:**

```powershell
[int]$port = 8080
$name = 'Ada'
$env:NODE_ENV = 'development'
"$name runs on $port"
```

**Scopes:**

```powershell
$script:counter = 0
function Tick {
  $script:counter++
  $local = 'only here'
}
```

**Null-conditional / coalescing (PS 7+):**

```powershell
$value = $config?.Timeout ?? 30
```

**Splatting:**

```powershell
$params = @{ Path = '.\a.txt'; Destination = '.\b.txt'; Force = $true }
Copy-Item @params
```

## ⚠️ Pitfalls [#️-pitfalls]

* `$false`, `0`, empty string, and empty arrays are all “falsy” in conditionals—know the rules.
* Assigning to `$env:VAR` affects the process environment only (not permanently unless you set user/machine env).
* `$?` is boolean success of last **PowerShell** statement; native commands also set `$LASTEXITCODE`.
* Variable names are not case-sensitive.
* Expanding in double quotes calls `.ToString()`—objects may stringify poorly; use subexpressions `"$($obj.Prop)"`.
* Don’t use `$input` casually—it’s reserved for pipeline enumerators in functions.

## 🔗 Related [#-related]

* [objects.md](/docs/powershell/objects)
* [conditionals.md](/docs/powershell/conditionals)
* [functions.md](/docs/powershell/functions)
* [scripting.md](/docs/powershell/scripting)
* [vs\_bash.md](/docs/powershell/vs-bash)


---

# PowerShell vs Bash (/docs/powershell/vs-bash)



# PowerShell vs Bash [#powershell-vs-bash]

*PowerShell · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Bash pipelines text; PowerShell pipelines objects. Bash is ubiquitous on Unix; PowerShell is cross-platform (pwsh) with deep .NET integration. Choose based on environment and data shape—many teams use both.

## 🔧 Core concepts [#-core-concepts]

| Topic         | Bash          | PowerShell                       |
| ------------- | ------------- | -------------------------------- |
| Pipeline      | Text streams  | Objects                          |
| Variables     | `$x`, strings | `$x`, typed objects              |
| Compare       | `[[ ]]`, `=`  | `-eq`, `-lt`, …                  |
| Errors        | Exit codes    | Error records + exit codes       |
| Lists         | Arrays / IFS  | Object collections               |
| JSON          | `jq`          | `ConvertFrom-Json`               |
| Common filter | `grep`/`awk`  | `Where-Object` / `Select-String` |
| Script ext    | `.sh`         | `.ps1`                           |

Interop: call bash from pwsh and vice versa when tools are installed.

## 💡 Examples [#-examples]

**Same task:**

```shellscript
# bash
ls -1 *.log | wc -l
cat file.json | jq '.name'
```

```powershell
# PowerShell
@(Get-ChildItem *.log).Count
(Get-Content -Raw file.json | ConvertFrom-Json).name
```

**Call the other shell:**

```powershell
bash -lc 'grep -R TODO .'
```

```shellscript
pwsh -NoProfile -Command 'Get-ChildItem | Select-Object Name'
```

**Environment vars:**

```shellscript
export PORT=8080
```

```powershell
$env:PORT = '8080'
```

## ⚠️ Pitfalls [#️-pitfalls]

* Assuming `curl` means the same thing (alias vs binary) across shells.
* Quoting rules differ—don’t paste bash snippets into PowerShell unchanged.
* Exit codes: bash `set -e` vs PowerShell `$ErrorActionPreference`.
* Line endings and shebangs matter when sharing scripts across OSes.
* Performance: spawning many external processes from either shell is costly—batch work.
* Object formatting in PowerShell can look like “broken text” when piped to bash tools—convert explicitly.

## 🔗 Related [#-related]

* [pipeline.md](/docs/powershell/pipeline)
* [variables.md](/docs/powershell/variables)
* [useful\_commands.md](/docs/powershell/useful-commands)
* [scripting.md](/docs/powershell/scripting)
* [cmdlets.md](/docs/powershell/cmdlets)

