Skip to content

RFC: Terminal Session Recording in Start-Transcript - #421

Draft
soroshsabz wants to merge 1 commit into
PowerShell:masterfrom
soroshsabz:rfc-terminal-recording
Draft

soroshsabz wants to merge 1 commit into
PowerShell:masterfrom
soroshsabz:rfc-terminal-recording

Conversation

@soroshsabz

@soroshsabz soroshsabz commented Nov 5, 2026 •

Copy link
Copy Markdown

Terminal Session Recording in Start-Transcript

Summary

Proposes extending Start-Transcript with a new -RecordTerminal capability that records the complete terminal session — including full-screen interactive TUI applications such as sconfig (Windows Server) and nmtui (RHEL) — as a time-stamped terminal stream saved in the open asciicast v3 format, optionally rendered to a video file (GIF built-in; WebM/MP4 via ffmpeg).

This is the PowerShell-level equivalent of RHEL's system-wide session recording (tlog + SSSD/PAM) and of community tools like asciinema/script(1), integrated into the familiar Start-Transcript / Stop-Transcript experience, with group policy support for audit scenarios.

Motivation

Start-Transcript today only captures what flows through the PowerShell host. TUI applications open the console directly (CONIN$/CONOUT$, /dev/tty), use raw mode and the alternate screen buffer, and are effectively invisible to the transcript — as discussed in PowerShell/PowerShell#28296.

Key scenarios:

  • Audit/compliance: defensible records of privileged interactive administration
  • Support/incident response: reproduce exactly what was on screen inside a TUI app
  • Training/docs/bug reports: shareable video (GIF/WebM) of a full session

Key design points

  • Strictly additive: new switches (-RecordTerminal, -RecordingFormat, -RecordInput, -RecordIdleTimeLimit); existing text transcript behavior unchanged
  • Capture happens in the host via ConPTY (Windows) / PTY (Unix), so TUI apps are captured transparently
  • .cast (asciicast v3) is always written as the source of truth → interop with asciinema play, agg
  • Video rendering: GIF via built-in managed renderer; WebM/MP4 via ffmpeg when available (graceful downgrade)
  • Group policy extension per RFC0041 (EnableTerminalRecording, RecordingFormat, RecordingOutputDirectory)
  • Ships as an experimental feature (PSTerminalRecording)
  • Security: -RecordInput off by default (secret capture risk); recordings noted in transcript header/footer

References

Note for Committee: RFC number assignment and experimental feature name TBD.


This change is Reviewable

@soroshsabz

Copy link
Copy Markdown
Author

Proposed addition: engine primitives that would let third-party modules implement this cleanly

While working on the community-module implementation of this request (Bsn.Host / Start-InteractiveTranscript – ConPTY engine on Windows, script(1) on Linux/macOS, asciicast v2 output), I catalogued what a PowerShell Gallery module can and cannot do here, and which engine-level APIs would collapse the remaining gap. Proposing these as either additions to this RFC or companion RFCs. They are ordered by impact.

Tier A — A console output tap (interceptor interface)

An IPSConsoleInterceptor-style hook (or ConsoleOutputWritten / ConsoleInputRead events on PSHostUserInterface) that the host invokes for every chunk it writes to the terminal, after VT rendering.

  • Gives: first-class enhanced transcripts (pipeline output, host writes, colors, timing) without the fragile Out-Default proxy functions modules abuse today.
  • Limitation: still misses native/TUI children, because they write to inherited console handles without going through the host. A tap alone can never see sconfig or vim — it improves pipeline-level recording only.

Tier B — A managed PTY primitive (highest practical impact for module authors)

A supported, cross-platform pseudo-terminal API in .NET/PowerShell: create PTY, spawn an attached process, read/write streams, receive resize notifications (ConPTY + openpty behind one abstraction). There is a long-standing dotnet/runtime request for this.

  • Gives: our 600-line P/Invoke ConPTY engine plus the script(1) workaround on Unix collapses to ~50 lines of correct cross-platform code. Same win for expect-style automation, embedded shells, and terminal test harnesses.
  • Limitation: still the "enter a recorded session" model — but that ceiling is architectural (a module cannot retroactively insert a PTY between an already-running shell and its terminal), not API-shaped.

Tier C — A host-sponsored "nested terminal passthrough" primitive

The host exposes what module authors currently hand-roll: raw console-mode save/restore, a VT passthrough loop, resize forwarding, clean teardown — e.g. PSHost.EnterNestedTerminal(...) or an Invoke-PSHostedCommand engine primitive.

  • Why it matters: the Alternate Proposals section correctly notes a module cannot do this "without the host's cooperation." This tier is that cooperation: the engine provides the plumbing, the ecosystem provides the UX (recording, casts, audit sinks, training tooling). Effectively RFC 421 scoped down to a primitive instead of a feature.

Tier D — Pluggable transcript sinks on Start-Transcript

Invert the layering: the engine keeps the hard part (transparent host-level ConPTY capture, as this RFC specifies), but Start-Transcript accepts a transcript provider/sink interface implemented by modules (asciicast v2, tlog-style JSON, SIEM/audit formats, video renderers, ...).

  • Gives: Microsoft ships one capture implementation instead of N half-working ones, and format innovation moves to the gallery. Start-Transcript -RecordTerminal -RecordingSink <module> composes naturally with the RFC's existing switches.
  • Why it fits this RFC: it is a small amendment to the "Recording file format" and "Video rendering" sections — capture in engine, formats pluggable.

Small but real quality-of-life APIs

Resize events on $Host.UI.RawUI, console-mode save/restore helpers, and a supported output tap for the pipeline would each remove fragile interop that every terminal module currently duplicates.

Suggestion

  • Tier B is the most transformative for module authors today.
  • Tier C is the pragmatic bridge that enables module UX without engine features.
  • Tier D is the most architecturally sound end-state and reads like a natural companion section to this RFC.
  • Tiers C + D together would let this RFC keep capture in the engine while the PowerShell Gallery ecosystem provides formats and tooling.

Happy to turn any of these tiers into concrete RFC language on request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant