Skip to content

Add PowerShell 7.6.4 with enhanced console configuration and Nerd Font support - #24

Open
N6REJ wants to merge 1 commit into
mainfrom
7.6.4
Open

Add PowerShell 7.6.4 with enhanced console configuration and Nerd Font support#24
N6REJ wants to merge 1 commit into
mainfrom
7.6.4

Conversation

@N6REJ

@N6REJ N6REJ commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@N6REJ
N6REJ requested a review from jwaisner July 30, 2026 20:58
@N6REJ N6REJ added the enhancement ✨ Improve program label Jul 30, 2026
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add PowerShell 7.6.4 bundle with Nerd Font console setup

✨ Enhancement 📝 Documentation ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Add a PowerShell 7.6.4 bundle with a custom launcher and profile.
• Auto-register Nerd Fonts and force UTF-8 console settings for proper glyph rendering.
• Switch PowerShell 7.5.4 oh-my-posh download to the "latest" release URL.
Diagram

graph TD
  U["User"] --> L["powershell.bat"] --> P["pwsh.exe"] --> Prof["Profile.ps1"] --> S["Enhanced session"]
  L --> RF["register-fonts.ps1"] --> R[("Console registry")]
  RF --> F[["Vendor fonts"]]
  Prof --> OP[["oh-my-posh + theme"]]
  Prof --> M[["PS modules"]]

  subgraph Legend
    direction LR
    _p["Process/Script"] ~~~ _r[("Registry") ] ~~~ _f[["Bundled files"]]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Pin oh-my-posh to a specific version (instead of releases/latest)
  • ➕ Deterministic builds and easier rollback when an upstream release breaks
  • ➕ Enables checksum verification workflows
  • ➖ Requires periodic manual bumps to pick up fixes/features
2. Make HKLM registry writes optional (HKCU-only by default)
  • ➕ Avoids requiring admin privileges; reduces machine-wide side effects
  • ➕ Safer in locked-down corporate environments
  • ➖ Some conhost configurations may still fail to recognize fonts without HKLM entries
3. Rely on Windows Terminal configuration + documentation (no registry font forcing)
  • ➕ No registry modification; simpler and less invasive
  • ➕ Works well for modern default terminals
  • ➖ Does not solve classic conhost.exe glyph/font issues; less “it just works” for users

Recommendation: The current approach is reasonable for a portable “batteries-included” console experience (font detection/registration + UTF-8 + custom profile). Consider (1) re-pinning oh-my-posh for reproducibility, and (2) gating HKLM writes behind an opt-in flag or admin check to reduce system-wide impact while preserving the conhost fallback path.

Files changed (7) +472 / -1

Enhancement (1) +52 / -0
Microsoft.PowerShell_profile.ps1Add custom PowerShell profile (oh-my-posh, PSReadLine, Terminal-Icons) +52/-0

Add custom PowerShell profile (oh-my-posh, PSReadLine, Terminal-Icons)

• Adds a bundled PowerShell profile that sets POSH_ROOT and PSModulePath, initializes oh-my-posh with a theme, imports Terminal-Icons, and configures PSReadLine options/keybindings plus an interactive banner.

bin/powershell7.6.4/config/Microsoft.PowerShell_profile.ps1

Documentation (1) +67 / -0
README.mdDocument Nerd Font requirements and customization +67/-0

Document Nerd Font requirements and customization

• Adds documentation describing the required Nerd Font, how to configure fonts in Windows Terminal/conhost, and how to customize the oh-my-posh theme and PSReadLine settings.

bin/powershell7.6.4/config/README.md

Other (5) +353 / -1
deps.propertiesTrack latest oh-my-posh release URL +1/-1

Track latest oh-my-posh release URL

• Updates the oh-my-posh dependency URL from a pinned version to the GitHub "releases/latest" download endpoint to automatically pick up new upstream releases.

bin/powershell7.5.4/deps.properties

bearsampp.confAdd PowerShell 7.6.4 bundle configuration +9/-0

Add PowerShell 7.6.4 bundle configuration

• Introduces bundle metadata for PowerShell 7.6.4, including executable names, profile path, preferred Nerd Font, and default console dimensions.

bin/powershell7.6.4/bearsampp.conf

register-fonts.ps1Add font installation + registry registration helper +137/-0

Add font installation + registry registration helper

• Adds a PowerShell helper that discovers font family names from bundled font files, copies them to the user fonts directory, registers them in the Fonts and Console TrueTypeFont registries, and broadcasts setting changes.

bin/powershell7.6.4/config/register-fonts.ps1

deps.propertiesDefine 7.6.4 dependencies (oh-my-posh, Terminal-Icons, PSReadLine, Nerd Font) +16/-0

Define 7.6.4 dependencies (oh-my-posh, Terminal-Icons, PSReadLine, Nerd Font)

• Adds dependency URLs for oh-my-posh and theme, sets the expected Nerd Font family name, and includes PowerShell Gallery packages for Terminal-Icons and PSReadLine.

bin/powershell7.6.4/deps.properties

powershell.batAdd launcher that enforces UTF-8 and configures console font via registry +190/-0

Add launcher that enforces UTF-8 and configures console font via registry

• Introduces a launcher that detects/installs a Nerd Font (with fallbacks), writes conhost console registry settings (font, code page, sizing), and starts pwsh in a new process so settings apply reliably.

bin/powershell7.6.4/powershell.bat

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (4) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Unpinned Oh My Posh exe 🐞 Bug ⛨ Security
Description
deps.properties switches Oh My Posh to a GitHub "releases/latest" URL, making builds
non-reproducible and allowing the downloaded executable to change over time. That downloaded
executable is later invoked by the PowerShell profile and its generated init script is piped to
Invoke-Expression, so an upstream change/compromise becomes direct code execution in user shells.
Code

bin/powershell7.5.4/deps.properties[1]

+oh_my_posh = https://github.com/JanDeDobbeleer/oh-my-posh/releases/latest/download/posh-windows-amd64.exe
Evidence
The changed deps file now uses a mutable latest-release URL; the build.gradle code consumes this URL
to download an EXE into vendor/oh-my-posh, and the profile executes that EXE and pipes its init
output into Invoke-Expression.

bin/powershell7.5.4/deps.properties[1-2]
build.gradle[659-689]
bin/powershell7.6.4/config/Microsoft.PowerShell_profile.ps1[18-24]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`oh_my_posh` now points to a mutable `releases/latest` asset. The build downloads that EXE into the shipped bundle and the profile executes it and `Invoke-Expression`s its generated output.

### Issue Context
- Mutable URLs break reproducibility and complicate incident response.
- Because the output is executed, integrity of the downloaded binary is critical.

### Fix Focus Areas
- bin/powershell7.5.4/deps.properties[1-1]
- bin/powershell7.6.4/deps.properties[1-2]
- build.gradle[659-689]
- bin/powershell7.6.4/config/Microsoft.PowerShell_profile.ps1[18-24]

### Suggested fix
- Pin `oh_my_posh` to an immutable versioned release URL (tagged version), not `latest`.
- Add a checksum property (e.g., `oh_my_posh_sha256`) and verify the download in `build.gradle` after `downloadFile(...)`.
- Consider hosting vetted binaries internally if this project requires stronger supply-chain control.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Add-Type redefined repeatedly 🐞 Bug ☼ Reliability
Description
register-fonts.ps1 defines the Win32.Gdi32 type via Add-Type inside the per-font install loop, so
after the first font it can fail because the type already exists, skipping AddFontResourceEx for
later fonts and emitting a misleading "Failed to install" error. This makes multi-font packages
register inconsistently in the current session.
Code

bin/powershell7.6.4/config/register-fonts.ps1[R96-104]

+                    $signature = @'
+[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
+public static extern int AddFontResourceEx(string lpszFilename, uint fl, IntPtr res);
+'@
+                    $gdi32 = Add-Type -MemberDefinition $signature -Name "Gdi32" -Namespace "Win32" -PassThru
+                    $gdi32::AddFontResourceEx($destFile, 0, [IntPtr]::Zero) | Out-Null
+                } catch {
+                    Write-Error "Failed to install font $internalName"
+                }
Evidence
The script defines the same Win32.Gdi32 type during each iteration; Add-Type commonly fails on
redefinition within the same session, and the entire font install is wrapped in a try/catch that
then logs a generic failure message.

bin/powershell7.6.4/config/register-fonts.ps1[91-105]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`register-fonts.ps1` calls `Add-Type -Name "Gdi32" -Namespace "Win32"` inside the loop that processes each font file. After the first successful call, subsequent calls can throw because the type already exists; the catch then reports a generic install failure and `AddFontResourceEx` is not executed for remaining files.

### Issue Context
This matters when `vendor/fonts` contains multiple `.ttf/.otf` files and more than one needs installation/refresh.

### Fix Focus Areas
- bin/powershell7.6.4/config/register-fonts.ps1[91-105]

### Suggested fix
- Move the `Add-Type` for `Win32.Gdi32` outside the `ForEach-Object` loop and reuse the type for all files.
- Alternatively guard with `if (-not ('Win32.Gdi32' -as [type])) { Add-Type ... }`.
- Narrow the try/catch so a type-definition error doesn’t mask successful copy/registry steps.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Silent HKLM registry failures 🐞 Bug ☼ Reliability
Description
powershell.bat attempts multiple HKLM registry writes (machine-level font/console registration) but
suppresses all output and does not check exit codes, so non-elevated runs can partially fail with no
signal. This makes font recognition issues intermittent and hard to diagnose because HKCU settings
may work in some contexts while HKLM-required contexts fail.
Code

bin/powershell7.6.4/powershell.bat[R136-145]

+for /f "tokens=2,*" %%A in ('reg query "HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "!FONT_NAME! (TrueType)" 2^>nul') do (
+    set "FONT_PATH=%%B"
+    if not "!FONT_PATH!"=="" reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "!FONT_NAME! (TrueType)" /t REG_SZ /d "!FONT_PATH!" /f >nul 2>&1
+)
+reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont" /v "000" /t REG_SZ /d "!FONT_NAME!" /f >nul 2>&1
+reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont" /v "0000" /t REG_SZ /d "!FONT_NAME!" /f >nul 2>&1
+reg add "HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont" /v "0" /t REG_SZ /d "!FONT_NAME!" /f >nul 2>&1
+reg add "HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont" /v "00" /t REG_SZ /d "!FONT_NAME!" /f >nul 2>&1
+reg add "HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont" /v "000" /t REG_SZ /d "!FONT_NAME!" /f >nul 2>&1
+
Evidence
The launcher explicitly writes HKLM values for fonts/TrueTypeFont and suppresses all command output
(>nul 2>&1), with no subsequent error handling; this is a clear silent-failure path in standard
(non-admin) executions.

bin/powershell7.6.4/powershell.bat[127-145]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The launcher writes to HKLM (admin-required) but redirects stdout/stderr to `nul` and does not check `%errorlevel%`. When run without elevation, these writes commonly fail silently.

### Issue Context
The script also writes HKCU values, which can mask partial failures: things may work in some shells but not others.

### Fix Focus Areas
- bin/powershell7.6.4/powershell.bat[127-145]

### Suggested fix
- After each HKLM `reg add`, check `if errorlevel 1` and `echo`/log a clear warning like "HKLM registration skipped (not elevated)".
- Optionally, gate HKLM writes behind an elevation check (e.g., `net session >nul 2>&1`) and only attempt HKLM writes when elevated.
- Avoid suppressing all output for failure paths; keep `>nul` only for success cases.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

4. POSH_THEMES_PATH not set 🐞 Bug ⚙ Maintainability
Description
config/README.md states the profile sets POSH_THEMES_PATH, but Microsoft.PowerShell_profile.ps1
never sets it, so users/scripts following the documentation will rely on an environment variable
that doesn’t exist. This is a documentation/config mismatch introduced with the new 7.6.4 config
docs.
Code

bin/powershell7.6.4/config/README.md[R46-51]

+## Environment Variables
+
+The profile sets these environment variables:
+- `POSH_ROOT` - Path to Oh My Posh installation
+- `POSH_THEMES_PATH` - Path to Oh My Posh themes directory
+
Evidence
The README claims POSH_THEMES_PATH is set, while the profile only assigns POSH_ROOT and
constructs the theme path directly from it.

bin/powershell7.6.4/config/README.md[46-51]
bin/powershell7.6.4/config/Microsoft.PowerShell_profile.ps1[8-21]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The README documents `POSH_THEMES_PATH`, but the profile only sets `POSH_ROOT` and uses a hardcoded theme path.

### Issue Context
Users may set automation or troubleshooting steps based on the documented env vars.

### Fix Focus Areas
- bin/powershell7.6.4/config/README.md[46-51]
- bin/powershell7.6.4/config/Microsoft.PowerShell_profile.ps1[8-21]

### Suggested fix
Either:
- Add `$env:POSH_THEMES_PATH = Join-Path $env:POSH_ROOT 'themes'` to the profile, or
- Remove/correct the README entry to reflect actual behavior.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment on lines +96 to +104
$signature = @'
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public static extern int AddFontResourceEx(string lpszFilename, uint fl, IntPtr res);
'@
$gdi32 = Add-Type -MemberDefinition $signature -Name "Gdi32" -Namespace "Win32" -PassThru
$gdi32::AddFontResourceEx($destFile, 0, [IntPtr]::Zero) | Out-Null
} catch {
Write-Error "Failed to install font $internalName"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Add-type redefined repeatedly 🐞 Bug ☼ Reliability

register-fonts.ps1 defines the Win32.Gdi32 type via Add-Type inside the per-font install loop, so
after the first font it can fail because the type already exists, skipping AddFontResourceEx for
later fonts and emitting a misleading "Failed to install" error. This makes multi-font packages
register inconsistently in the current session.
Agent Prompt
### Issue description
`register-fonts.ps1` calls `Add-Type -Name "Gdi32" -Namespace "Win32"` inside the loop that processes each font file. After the first successful call, subsequent calls can throw because the type already exists; the catch then reports a generic install failure and `AddFontResourceEx` is not executed for remaining files.

### Issue Context
This matters when `vendor/fonts` contains multiple `.ttf/.otf` files and more than one needs installation/refresh.

### Fix Focus Areas
- bin/powershell7.6.4/config/register-fonts.ps1[91-105]

### Suggested fix
- Move the `Add-Type` for `Win32.Gdi32` outside the `ForEach-Object` loop and reuse the type for all files.
- Alternatively guard with `if (-not ('Win32.Gdi32' -as [type])) { Add-Type ... }`.
- Narrow the try/catch so a type-definition error doesn’t mask successful copy/registry steps.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@@ -1,4 +1,4 @@
oh_my_posh = https://github.com/JanDeDobbeleer/oh-my-posh/releases/download/v29.18.0/posh-windows-amd64.exe
oh_my_posh = https://github.com/JanDeDobbeleer/oh-my-posh/releases/latest/download/posh-windows-amd64.exe

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Unpinned oh my posh exe 🐞 Bug ⛨ Security

deps.properties switches Oh My Posh to a GitHub "releases/latest" URL, making builds
non-reproducible and allowing the downloaded executable to change over time. That downloaded
executable is later invoked by the PowerShell profile and its generated init script is piped to
Invoke-Expression, so an upstream change/compromise becomes direct code execution in user shells.
Agent Prompt
### Issue description
`oh_my_posh` now points to a mutable `releases/latest` asset. The build downloads that EXE into the shipped bundle and the profile executes it and `Invoke-Expression`s its generated output.

### Issue Context
- Mutable URLs break reproducibility and complicate incident response.
- Because the output is executed, integrity of the downloaded binary is critical.

### Fix Focus Areas
- bin/powershell7.5.4/deps.properties[1-1]
- bin/powershell7.6.4/deps.properties[1-2]
- build.gradle[659-689]
- bin/powershell7.6.4/config/Microsoft.PowerShell_profile.ps1[18-24]

### Suggested fix
- Pin `oh_my_posh` to an immutable versioned release URL (tagged version), not `latest`.
- Add a checksum property (e.g., `oh_my_posh_sha256`) and verify the download in `build.gradle` after `downloadFile(...)`.
- Consider hosting vetted binaries internally if this project requires stronger supply-chain control.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +136 to +145
for /f "tokens=2,*" %%A in ('reg query "HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "!FONT_NAME! (TrueType)" 2^>nul') do (
set "FONT_PATH=%%B"
if not "!FONT_PATH!"=="" reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "!FONT_NAME! (TrueType)" /t REG_SZ /d "!FONT_PATH!" /f >nul 2>&1
)
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont" /v "000" /t REG_SZ /d "!FONT_NAME!" /f >nul 2>&1
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont" /v "0000" /t REG_SZ /d "!FONT_NAME!" /f >nul 2>&1
reg add "HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont" /v "0" /t REG_SZ /d "!FONT_NAME!" /f >nul 2>&1
reg add "HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont" /v "00" /t REG_SZ /d "!FONT_NAME!" /f >nul 2>&1
reg add "HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont" /v "000" /t REG_SZ /d "!FONT_NAME!" /f >nul 2>&1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

3. Silent hklm registry failures 🐞 Bug ☼ Reliability

powershell.bat attempts multiple HKLM registry writes (machine-level font/console registration) but
suppresses all output and does not check exit codes, so non-elevated runs can partially fail with no
signal. This makes font recognition issues intermittent and hard to diagnose because HKCU settings
may work in some contexts while HKLM-required contexts fail.
Agent Prompt
### Issue description
The launcher writes to HKLM (admin-required) but redirects stdout/stderr to `nul` and does not check `%errorlevel%`. When run without elevation, these writes commonly fail silently.

### Issue Context
The script also writes HKCU values, which can mask partial failures: things may work in some shells but not others.

### Fix Focus Areas
- bin/powershell7.6.4/powershell.bat[127-145]

### Suggested fix
- After each HKLM `reg add`, check `if errorlevel 1` and `echo`/log a clear warning like "HKLM registration skipped (not elevated)".
- Optionally, gate HKLM writes behind an elevation check (e.g., `net session >nul 2>&1`) and only attempt HKLM writes when elevated.
- Avoid suppressing all output for failure paths; keep `>nul` only for success cases.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +46 to +51
## Environment Variables

The profile sets these environment variables:
- `POSH_ROOT` - Path to Oh My Posh installation
- `POSH_THEMES_PATH` - Path to Oh My Posh themes directory

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Informational

4. Posh_themes_path not set 🐞 Bug ⚙ Maintainability

config/README.md states the profile sets POSH_THEMES_PATH, but Microsoft.PowerShell_profile.ps1
never sets it, so users/scripts following the documentation will rely on an environment variable
that doesn’t exist. This is a documentation/config mismatch introduced with the new 7.6.4 config
docs.
Agent Prompt
### Issue description
The README documents `POSH_THEMES_PATH`, but the profile only sets `POSH_ROOT` and uses a hardcoded theme path.

### Issue Context
Users may set automation or troubleshooting steps based on the documented env vars.

### Fix Focus Areas
- bin/powershell7.6.4/config/README.md[46-51]
- bin/powershell7.6.4/config/Microsoft.PowerShell_profile.ps1[8-21]

### Suggested fix
Either:
- Add `$env:POSH_THEMES_PATH = Join-Path $env:POSH_ROOT 'themes'` to the profile, or
- Remove/correct the README entry to reflect actual behavior.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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

Labels

enhancement ✨ Improve program

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants