# Modern Windows Shell Architecture: PowerShell and WinGet<no value>

{{< hero-card title="From Legacy CLI to Object-Oriented Automation" variant="dark" >}}
The Windows shell environment has shifted fundamentally. The current standard is defined by three decoupled components: PowerShell 7+ as the shell, Windows Terminal as the host, and WinGet as the native package manager. For users re-entering the Windows ecosystem, understanding these boundaries is the prerequisite for everything else.
{{< /hero-card >}}

## The Core Paradigm: Objects Over Strings

The defining difference between PowerShell and Unix-like shells is the pipeline. Bash passes text streams that require `grep`, `sed`, or `awk` for parsing. PowerShell passes `.NET` objects. Every cmdlet receives structured objects and emits structured objects — no string parsing required.

Four operations cover the majority of pipeline work:

- **`Get-Member`** (alias `gm`) — inspect the properties and methods of any object in the pipeline
- **`Where-Object`** (alias `?`) — filter objects by logical checks on their properties
- **`Select-Object`** (alias `select`) — extract specific properties or limit output count
- **`Format-Table`** / **`Format-List`** — convert objects to display strings; use only as the final step in a pipeline, as they break further automation

The last point is a common source of pipeline failures. Formatting cmdlets are terminal — once an object becomes a display string, its properties are no longer accessible to downstream cmdlets.

## Environment and Productivity Enhancements

{{< accordion title="Windows Terminal" >}}

The legacy `conhost.exe` host is deprecated. Windows Terminal provides GPU-accelerated text rendering, multiple tabs, and split panes.

Key shortcuts:

- `Alt + Shift + D` — vertical split
- `Alt + Shift + -` — horizontal split
- `Ctrl + Shift + F` — search the buffer

{{< /accordion >}}

{{< accordion title="PSReadLine" >}}

Modern PowerShell includes PSReadLine, which provides readline functionality comparable to Zsh or Fish.

Enable ghost-text completions from command history:

```powershell
Set-PSReadLineOption -PredictionSource History
```

Key bindings:

- `Ctrl + Space` — full menu-based completion
- `Ctrl + R` — reverse history search (regex-compatible)
- `Alt + A` — select the current line for editing
- `F12` — clear the screen while preserving the buffer

{{< /accordion >}}

{{< accordion title="Profile Configuration" >}}

The environment is configured via `$PROFILE`. Open it directly with:

```powershell
code $PROFILE
```

Use the profile to set aliases and import modules automatically on startup. Changes take effect in new sessions; use `. $PROFILE` to reload without restarting the terminal.

{{< /accordion >}}

## WinGet: Native Package Management

WinGet replaces the manual download-and-execute workflow for software installation and system state management.

```powershell
# Install a package
winget install Git.Git

# Audit all installed software (including non-WinGet installs)
winget list

# Upgrade all outdated applications
winget upgrade --all

# Export current machine state to a declarative bundle
winget export -o bundles.json

# Replicate that state on a new node
winget import -i bundles.json
```

The export/import workflow is particularly useful for provisioning new workstations to a known software baseline without manual installation sequences.

## Execution Contexts and Privilege Elevation

Windows security architecture defines three primary execution contexts. Understanding their boundaries is a prerequisite for writing scripts that behave correctly across deployment environments.

{{< accordion title="Standard User (Least Privilege)" >}}

The default execution context. Scripts here have limited access to the `HKEY_LOCAL_MACHINE` (HKLM) registry hive and system-protected directories (`C:\Windows`, `C:\Program Files`).

Use `Resolve-Path` to ensure scripts handle relative paths correctly within user profiles. Avoid hardcoding paths that assume a specific user directory structure.

{{< /accordion >}}

{{< accordion title="Administrative User (Elevated)" >}}

Requires UAC consent. Provides write access to HKLM and system directories.

Spawn an elevated shell from a standard context:

```powershell
Start-Process pwsh -Verb RunAs
```

Detect elevation state within a script:

```powershell
([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
```

{{< /accordion >}}

{{< accordion title="SYSTEM (S-1-5-18)" >}}

The highest privilege level, reserved for Windows Services and the kernel. SYSTEM has broader access than a local Administrator — including certain protected registry keys and hardware drivers — but lacks a user profile (`HKCU`).

Consequences for script authors:

- Many environment variables available to users are absent in SYSTEM context
- Network paths and UNC shares that rely on user credentials are inaccessible
- Scripts deployed via Intune or SCCM run as SYSTEM and must use absolute paths and handle the absence of a desktop interaction layer

For debugging in SYSTEM context, use PsExec from the Sysinternals suite:

```powershell
PsExec -s -i powershell.exe
```

{{< /accordion >}}

## Scripting Standards

Three settings should be present in any production PowerShell script:

**Strict mode** catches uninitialized variables and references to non-existent properties before they produce silent failures:

```powershell
Set-StrictMode -Version Latest
```

**ErrorAction Stop** forces `try/catch` blocks to trigger on non-terminating errors, which PowerShell would otherwise silently continue past:

```powershell
Get-Item $path -ErrorAction Stop
```

**Modules over scripts** — modern Windows development favors `.psm1` module files over standalone scripts for better scoping, reusability, and dependency management. A script that grows beyond a single purpose should be refactored into a module.

{{< cta-button href="/resources/" >}}
Browse the ISS Resource Library
{{< /cta-button >}}
