From 545cde71d6f01ba73a4e4efc231ae3ae33ea5829 Mon Sep 17 00:00:00 2001 From: 26zl <143036376+26zl@users.noreply.github.com> Date: Sat, 19 Sep 2026 23:25:34 +0200 Subject: [PATCH 1/2] serve: bind to loopback by default The banner said http://127.0.0.1 but neither backend was told to bind there: python -m http.server and npx http-server both listen on every interface by default, so the directory was reachable from the whole LAN. Pass --bind / -a explicitly, default to 127.0.0.1, and add -Bind for the case where sharing on the network is intended. The banner now prints the real address. --- Microsoft.PowerShell_profile.ps1 | 16 +++++++++------- README.md | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Microsoft.PowerShell_profile.ps1 b/Microsoft.PowerShell_profile.ps1 index 5caa34f..97ea077 100644 --- a/Microsoft.PowerShell_profile.ps1 +++ b/Microsoft.PowerShell_profile.ps1 @@ -4985,27 +4985,29 @@ function entropy { # Developer -# Serve a directory through Python or npx. +# Serve a directory through Python or npx. Loopback only by default: both servers +# listen on every interface unless told otherwise. Use -Bind 0.0.0.0 to share on the LAN. function serve { param( [int]$Port = 8000, - [string]$Path = '.' + [string]$Path = '.', + [string]$Bind = '127.0.0.1' ) $resolved = Resolve-Path -LiteralPath $Path -ErrorAction SilentlyContinue if (-not $resolved) { Write-Error "Path not found: $Path"; return } $oldTitle = Push-TabTitle "serve :$Port" try { if (Get-Command python -ErrorAction SilentlyContinue) { - Write-Host ("Serving {0} on http://127.0.0.1:{1} (Ctrl+C to stop)" -f $resolved.Path, $Port) -ForegroundColor Cyan + Write-Host ("Serving {0} on http://{1}:{2} (Ctrl+C to stop)" -f $resolved.Path, $Bind, $Port) -ForegroundColor Cyan Push-Location $resolved.Path - try { & python -m http.server $Port } + try { & python -m http.server $Port --bind $Bind } finally { Pop-Location } return } if (Get-Command npx -ErrorAction SilentlyContinue) { - Write-Host ("Serving {0} via npx http-server on http://127.0.0.1:{1}" -f $resolved.Path, $Port) -ForegroundColor Cyan + Write-Host ("Serving {0} via npx http-server on http://{1}:{2}" -f $resolved.Path, $Bind, $Port) -ForegroundColor Cyan Push-Location $resolved.Path - try { & npx --yes http-server -p $Port } + try { & npx --yes http-server -p $Port -a $Bind } finally { Pop-Location } return } @@ -6353,7 +6355,7 @@ ${g}certcheck${r} [port] - Full TLS probe: chain, SAN, SHA256 pin, cipher ${g}entropy${r} - Shannon entropy (detect packed/encrypted payloads). ${c}Developer+${r} -${g}serve${r} [port] [path] - One-line HTTP server (python or npx). +${g}serve${r} [port] [path] [-Bind addr] - One-line HTTP server (python or npx; loopback only by default). ${g}gitignore${r} - Generate .gitignore from gitignore.io. ${g}gcof${r} - Fuzzy git branch checkout (fzf). ${g}envload${r} [path] - Load .env file into current session. diff --git a/README.md b/README.md index 7545cc1..a66e83c 100644 --- a/README.md +++ b/README.md @@ -338,7 +338,7 @@ Run `Show-Help` in your terminal for a colored version of this list. | `timer { command }` | Measure execution time | | `watch { command } [-Interval n]` | Repeat command every n seconds (default 2; like Linux watch) | | `bak ` | Quick timestamped backup | -| `serve [port] [path]` | One-line HTTP server (python or npx) | +| `serve [port] [path] [-Bind addr]` | One-line HTTP server (python or npx). Loopback only by default; `-Bind 0.0.0.0` shares it on the LAN | | `gitignore ` | Generate .gitignore from gitignore.io | | `gcof` | Fuzzy git branch checkout (fzf) | | `envload [path]` | Load .env file into current session | From 746fce8df668cc77823445f64725b703cf6b6052 Mon Sep 17 00:00:00 2001 From: 26zl <143036376+26zl@users.noreply.github.com> Date: Sun, 20 Sep 2026 00:29:08 +0200 Subject: [PATCH 2/2] README: make the Controlled Folder Access exception temporary The install notes told people to add powershell.exe and pwsh.exe to the CFA allow-list for good. That hands every PowerShell script, ransomware included, write access to the protected folders, which is the one thing CFA is there to stop. The hard-coded pwsh path is also wrong for the Store build, whose path changes with every update. Allow the running host for the install only and remove it afterwards. Describe the actual symptom (a misleading "Could not find file" plus Defender event 1123), and drop the advice to move the clone: it is the write to Documents that is blocked, not the read from the clone. --- README.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a66e83c..4d263ab 100644 --- a/README.md +++ b/README.md @@ -122,12 +122,20 @@ When running locally you can override terminal defaults: .\setup.ps1 -SkipWizard -Opacity 85 -ColorScheme "One Half Dark" -FontSize 12 ``` -> **Controlled Folder Access:** If Windows Defender blocks the setup, allow PowerShell through: +> **Controlled Folder Access:** setup writes the profile to `Documents`, which CFA protects. The +> symptom is a misleading `Could not find file` and a Defender event 1123. Allow the PowerShell +> you are running **for the install only**, then take it out again. A permanent entry lets every +> PowerShell script, ransomware included, write to your protected folders. > > ```powershell -> Add-MpPreference -ControlledFolderAccessAllowedApplications "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -> Add-MpPreference -ControlledFolderAccessAllowedApplications "C:\Program Files\PowerShell\7\pwsh.exe" +> $ps = (Get-Process -Id $PID).Path # also right for the Store build, whose path changes per version +> Add-MpPreference -ControlledFolderAccessAllowedApplications $ps +> .\setup.ps1 +> Remove-MpPreference -ControlledFolderAccessAllowedApplications $ps +> (Get-MpPreference).ControlledFolderAccessAllowedApplications # check it is gone > ``` +> +> Later profile and module updates write to the same folder and need the same two lines around them. ## Updates @@ -450,7 +458,7 @@ PowerShellPerfect bundles a **prompt** (via Oh My Posh), a **command suite**, an | Symptom | Fix | | --- | --- | -| Setup blocked by Windows Defender (Controlled Folder Access) | Allow PowerShell through (see the command in [Install](#install-alternatives)), or run the clone from a non-protected folder. | +| Setup blocked by Windows Defender (Controlled Folder Access), often shown as `Could not find file` | Allow PowerShell through for the duration of the install and remove it afterwards (see [Install](#install-alternatives)). Moving the clone does not help: it is the write to `Documents` that is blocked. | | `running scripts is disabled on this system` | Run `Set-ExecutionPolicy -Scope CurrentUser RemoteSigned`. (The recommended one-liner runs an in-memory scriptblock, which isn't subject to the script-file execution policy.) | | Prompt shows boxes / missing glyphs | The terminal font isn't a Nerd Font. Set your Windows Terminal profile font to the one setup installed (e.g. *CaskaydiaCove Nerd Font*) and restart WT. | | `oh-my-posh` not found right after install | Reopen the terminal (PATH refresh) or run `Update-SessionPathFromRegistry`; confirm with `psp-doctor`. |