Windows-focused PowerShell module and bootstrap flow for quickly turning a fresh Windows Sandbox session into a usable development environment, especially from a .wsb startup entrypoint. It can provision managed Python, PowerShell 7, Node.js, OpenCode CLI, Gemini CLI, Qwen CLI, Codex CLI, GitHub CLI, MinGit, VS Code, and Microsoft Visual C++ runtime prerequisites when you want them.
The primary intent is fast, repeatable setup inside Windows Sandbox. The same bootstrap pattern can also run on a normal Windows machine, but that is a secondary use case rather than the main focus of this repo.
π Key Features:
- Fast Windows Sandbox bring-up from a
.wsbstartup command or a manual shell - Managed runtime provisioning for
python,pip,pwsh,git,gh,code,node,npm,opencode,gemini,qwen,codex, and VC++ prerequisites - Runtime discovery that can reuse compatible external installs or refresh to sandbox-owned managed copies
- Persisted command results plus live runtime snapshots through
Get-SandboxState - Managed npm ownership under the sandbox Node runtime, including proxy-aware npm configuration when Windows resolves the npm registry through a proxy
- Reusable
iwr | iexbootstrap flow for repo-specific or generic PowerShell handoff scenarios - PowerShell 5.1-first bootstrap path with normal Windows machine support as a secondary workflow
The module currently exports these public commands:
Get-SandboxVersionGet-SandboxStateInitialize-PythonRuntimeInitialize-Ps7RuntimeInitialize-GitRuntimeInitialize-VSCodeRuntimeInitialize-NodeRuntimeInitialize-OpenCodeRuntimeInitialize-GeminiRuntimeInitialize-QwenRuntimeInitialize-CodexRuntimeInitialize-GHCliRuntimeInitialize-VCRuntime
There is not yet a single combined Initialize-Sandbox command. The current model is a set of small init commands that each read real state, plan from that state, perform bounded repair or install work, and persist the observed result.
Windows Sandbox is ideal for disposable setup checks: bootstrap a repo, validate installer behavior, and test fresh-machine assumptions without touching your main workstation.
The problem is that a blank .wsb session still takes manual work to become useful. This project turns that repeated setup into a small versioned PowerShell entrypoint so the environment is quick to reuse instead of tedious to rebuild.
Windows Sandbox on the host requires Windows 10/11 1903+, Pro/Enterprise/Education/Pro Education/SE, virtualization enabled, 4 GB RAM, 1 GB free disk, 2 CPU cores, and the Windows Sandbox feature enabled.
Example Windows Sandbox session after the bootstrapper opens PowerShell and the follow-up runtime commands are available.
The bootstrapper is optimized for getting a Windows Sandbox session ready quickly. It installs the required PowerShell package tooling plus Eigenverft.Manifested.Sandbox from the PowerShell Gallery, then opens a new Windows PowerShell console and runs the default follow-up command.
π‘ Even if you do not end up using this module's managed runtime installers, the bootstrapper is still useful as a reusable startup pattern. It gives you a simple way to install a chosen set of PowerShell Gallery modules, open a fresh console, and immediately run a preset command chain.
PowerShell Gallery package: Eigenverft.Manifested.Sandbox
The published bootstrap one-liner first downloads iwr/bootstrapper.ps1 from raw.githubusercontent.com and then, in Windows PowerShell 5.1:
- Enables TLS 1.2 if possible
- Tries to set the current user's execution policy to
Unrestricted - Bootstraps the
NuGetpackage provider inCurrentUserscope - Trusts or registers
PSGallery - Installs
PackageManagement,PowerShellGet, andEigenverft.Manifested.SandboxinCurrentUserscope - Opens a new Windows PowerShell session and runs
Get-SandboxVersion
Admin rights are not required for the bootstrap or module install path. Later runtime actions can have different requirements; for example, Initialize-VCRuntime may still require elevation when the VC++ runtime needs to be installed or repaired.
π‘ Why is this command so long? It includes a built-in proxy handshake. In heavily managed corporate environments, basic downloads often fail. This one-liner explicitly checks for and dynamically authenticates through your system's proxy with default network credentials before downloading the bootstrap script.
From Windows PowerShell 5.1:
$u='https://raw.githubusercontent.com/eigenverft/Eigenverft.Manifested.Sandbox/refs/heads/main/iwr/bootstrapper.ps1';try{[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12}catch{};$p=[System.Net.WebRequest]::GetSystemWebProxy();if(-not $p.IsBypassed($u)){iwr $u -Proxy ($p.GetProxy($u).AbsoluteUri) -ProxyUseDefaultCredentials -UseBasicParsing|iex}else{iwr $u -UseBasicParsing|iex}From cmd.exe:
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$u='https://raw.githubusercontent.com/eigenverft/Eigenverft.Manifested.Sandbox/refs/heads/main/iwr/bootstrapper.ps1';try{[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12}catch{};$p=[System.Net.WebRequest]::GetSystemWebProxy();if(-not $p.IsBypassed($u)){iwr $u -Proxy ($p.GetProxy($u).AbsoluteUri) -ProxyUseDefaultCredentials -UseBasicParsing|iex}else{iwr $u -UseBasicParsing|iex}" && exitA generic version of the bootstrapper lets you specify which PowerShell Gallery modules to install and which command to invoke automatically, so it can be reused for projects beyond Eigenverft.Manifested.Sandbox and for repo-specific bootstrap flows that just need a clean handoff into PowerShell.
$c='Initialize-VCRuntime;Initialize-PythonRuntime;Initialize-Ps7Runtime;Initialize-GitRuntime;Initialize-GHCliRuntime;Initialize-VSCodeRuntime;Initialize-NodeRuntime;Initialize-OpenCodeRuntime;Initialize-CodexRuntime;Get-SandboxState';$i='PackageManagement','PowerShellGet','Eigenverft.Manifested.Sandbox';$u='https://raw.githubusercontent.com/eigenverft/Eigenverft.Manifested.Sandbox/refs/heads/main/iwr/bootstrapper.sandbox.generic.ps1';try{[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12}catch{};$p=[System.Net.WebRequest]::GetSystemWebProxy();if(-not $p.IsBypassed($u)){iwr $u -Proxy ($p.GetProxy($u).AbsoluteUri) -ProxyUseDefaultCredentials -UseBasicParsing|iex}else{iwr $u -UseBasicParsing|iex}π‘ To test another branch, replace
mainwith the branch name in the URL.
The published default bootstrapper currently uses:
$i='PackageManagement','PowerShellGet','Eigenverft.Manifested.Sandbox'
$c='Get-SandboxVersion'The configurable variant keeps the same overall bootstrap pattern, but lets you preset $i and $c before invocation. That same pattern also maps well to Windows Sandbox .wsb startup definitions, where you often want the XML to stay small while the real startup behavior lives in versioned PowerShell.
If you want a ready-to-use Windows Sandbox entry file, save something like this as sandbox.wsb and launch it:
<Configuration>
<!-- Hardware / integration toggles -->
<VGpu>Enable</VGpu>
<Networking>Enable</Networking>
<AudioInput>Enable</AudioInput>
<VideoInput>Enable</VideoInput>
<PrinterRedirection>Enable</PrinterRedirection>
<ClipboardRedirection>Enable</ClipboardRedirection>
<MemoryInMB>4096</MemoryInMB>
<!-- Map host folder into the sandbox -->
<MappedFolders>
<MappedFolder>
<HostFolder>C:\temp</HostFolder>
<SandboxFolder>C:\temp</SandboxFolder>
<ReadOnly>false</ReadOnly>
</MappedFolder>
</MappedFolders>
<!-- Auto-start: PowerShell startup -->
<LogonCommand>
<!-- Dev-friendly generic variant:
<Command>cmd /c start "" powershell.exe -NoExit -Command "$c='Get-SandboxVersion;Initialize-PythonRuntime;Initialize-Ps7Runtime;Initialize-GitRuntime;Initialize-GHCliRuntime;Initialize-VSCodeRuntime;Initialize-NodeRuntime;Initialize-OpenCodeRuntime;Initialize-CodexRuntime;Get-SandboxState';$i='PackageManagement','PowerShellGet','Eigenverft.Manifested.Sandbox';$u='https://raw.githubusercontent.com/eigenverft/Eigenverft.Manifested.Sandbox/refs/heads/main/iwr/bootstrapper.sandbox.generic.ps1';try{[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12}catch{};$p=[System.Net.WebRequest]::GetSystemWebProxy();if(-not $p.IsBypassed($u)){iwr $u -Proxy ($p.GetProxy($u).AbsoluteUri) -ProxyUseDefaultCredentials -UseBasicParsing|iex}else{iwr $u -UseBasicParsing|iex}"</Command>
-->
<Command>cmd /c start "" powershell.exe -NoExit -Command "$u='https://raw.githubusercontent.com/eigenverft/Eigenverft.Manifested.Sandbox/refs/heads/main/iwr/bootstrapper.ps1';try{[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12}catch{};$p=[System.Net.WebRequest]::GetSystemWebProxy();if(-not $p.IsBypassed($u)){iwr $u -Proxy ($p.GetProxy($u).AbsoluteUri) -ProxyUseDefaultCredentials -UseBasicParsing|iex}else{iwr $u -UseBasicParsing|iex}"</Command>
</LogonCommand>
</Configuration>This is a practical starting point for a disposable Windows Sandbox session that immediately pulls the bootstrapper from GitHub and opens PowerShell for the follow-up init commands.
The .wsb scenario is one of the clearest reasons to keep the bootstrapper flexible. The XML only needs to launch PowerShell and point at the bootstrap script, while the module list and startup command can stay in versioned PowerShell instead of being baked directly into the sandbox definition. If you want a different startup flow, switch the LogonCommand to the generic bootstrapper variant and preset $i and $c there.
After the bootstrapper opens the new console, run:
Get-SandboxVersion
Initialize-PythonRuntime
Initialize-Ps7Runtime
Initialize-GitRuntime
Initialize-GHCliRuntime
Initialize-VSCodeRuntime
Initialize-NodeRuntime
Initialize-OpenCodeRuntime
Initialize-GeminiRuntime
Initialize-QwenRuntime
Initialize-CodexRuntime
Initialize-VCRuntime
Get-SandboxStateGet-SandboxVersionis the quick way to show the highest installed or loaded module version the current PowerShell session can resolve.Get-SandboxStateexposes both the persisted command document and live runtime snapshots, so it is the easiest way to see what the module believes is managed, external, missing, partial, or blocked right now.Initialize-PythonRuntime,Initialize-Ps7Runtime,Initialize-GitRuntime,Initialize-GHCliRuntime,Initialize-VSCodeRuntime,Initialize-NodeRuntime,Initialize-OpenCodeRuntime,Initialize-GeminiRuntime,Initialize-QwenRuntime, andInitialize-CodexRuntimeare intended to run in a normal user session. They prefer sandbox-managed portable runtimes underLocalAppData, using python.org for the CPython embeddable ZIP, GitHub as the download source for PowerShell 7, MinGit, and GitHub CLI, the official VS Code Windows ZIP archive with portabledatamode for VS Code, and npm-based managed installs for OpenCode, Gemini, Qwen, and Codex.- Those commands also check for an already-usable
python,pwsh,git,gh,code,node,opencode,gemini,qwen, orcodexthat exists outside prior sandbox state. If a compatible runtime is already available onPATHor in a common install location, the command can treat it as ready and persist it as an external runtime instead of downloading or installing a new copy. If you explicitly use a refresh switch such as-RefreshPython,-RefreshGit,-RefreshGHCli,-RefreshPs7,-RefreshVSCode,-RefreshNode,-RefreshOpenCode,-RefreshGemini,-RefreshQwen, or-RefreshCodex, the command will still acquire and install the sandbox-managed copy. Initialize-PythonRuntimeinstalls the official CPython Windows embeddable package into a sandbox-managed tools root, enablesimport site, bootstrapspip, and exposespython,python.exe,pip.cmd, andpip3.cmdfrom the managed runtime directory. When Windows resolves the package index through a proxy, it keeps proxy settings in a runtime-localpip.iniinstead of writing to a machine-wide or user-wide pip config.Initialize-GHCliRuntimeinstalls a managedgh.exefrom the official GitHub CLI Windows ZIP release and validates the package against GitHub's published checksum asset before making that runtime active onPATH.Initialize-NodeRuntimeinstalls the managed Node.js runtime and owns the sandbox-managed npm configuration. When Windows resolves the active npm registry through a proxy, it writesproxyandhttps-proxyinto the managed runtime's globalnpmrc; when the route is direct, it leaves npm config unchanged.Initialize-OpenCodeRuntime,Initialize-GeminiRuntime,Initialize-QwenRuntime, andInitialize-CodexRuntimeinstallopencode-ai,@google/gemini-cli,@qwen-code/qwen-code, and@openai/codexinto sandbox-managed tool roots and inherit the managed npm global config when they are using the sandbox-owned Node/npm runtime.Initialize-OpenCodeRuntimeinstallsopencode-aiand exposesopencode/opencode.cmdfrom the managed tool root when refreshed or newly installed.Initialize-GeminiRuntimeinstalls@google/gemini-cliinto the sandbox-managed tool root and prefers that managed copy when refreshed. Gemini CLI's official docs currently recommend Node.js20.0.0+and Windows 1124H2+; this module follows a best-effort Windows policy and ensures a compatible Node runtime before managed install when needed.Initialize-QwenRuntimeinstalls@qwen-code/qwen-codeinto the sandbox-managed tool root and prefers that managed copy when refreshed. Qwen Code's official quickstart currently requires Node.js20+; this module follows that requirement and ensures a compatible Node runtime before managed install when needed.Initialize-CodexRuntimeinstalls@openai/codexinto the sandbox-managed tool root and prefers that managed copy when refreshed. It always ensures the VC runtime prerequisite before install, and if no usable Node/npm is available yet it also ensures the required Node runtime first.Initialize-VCRuntimeis different because the VC runtime is a machine/runtime prerequisite rather than a sandbox-managed portable tool.Initialize-VCRuntimeshould be run in an elevated PowerShell process when the Microsoft Visual C++ Redistributable needs to be installed or repaired.
If you prefer installing the module directly instead of using the bootstrapper:
Install-Module Eigenverft.Manifested.Sandbox -Scope CurrentUser -Repository PSGallery
Import-Module Eigenverft.Manifested.Sandbox- Use the refresh switches when you want the sandbox-managed runtime even if a compatible tool already exists elsewhere on the machine.
Initialize-PythonRuntimekeeps pip cache and proxy state under the sandbox root, so it is a good fit for disposable or corporate-proxy sandbox sessions where you do not want pip config leaking into the wider user profile.- OpenCode, Gemini, Qwen, and Codex are all opt-in in the example command chains; add the specific runtime init commands you want for a given sandbox profile.
- The npm-based CLIs share the managed Node runtime when needed. If
Initialize-NodeRuntimedetects that the npm registry routes through a system proxy, it persists that proxy into the sandbox-owned npm config; if the route is direct, it makes no npm proxy changes. - Replace
mainin the bootstrap URLs to test another branch without changing the overall bootstrap flow. - Keep
.wsbfiles small and let versioned PowerShell own the real startup logic whenever you want a more maintainable sandbox launch path. - Run
Get-SandboxStateafter a bootstrap chain when you want the quickest view of managed vs external runtimes and persisted command outcomes. - Run
Initialize-VCRuntimein an elevated PowerShell session if the Microsoft Visual C++ Redistributable needs installation or repair.
This project is licensed under the MIT License - see the LICENSE file for details.
For questions and support:
- π Open an issue in this repository
- π€ Submit a pull request with improvements
