Prior to the Windows Terminal in 2020, people used to either use ‘conhost’; the default program which renders both powershell and cmd, or ‘cmder’; a much better open source alternative. You couldn’t do much to the conhost interface and cmder required some knowledge.

Now, with Terminal, you can install a piece of software called oh-my-posh. This renders over the terminal and adds a set of emojis (for which there is no glossary but can be figured out by trial and error).

PowerShell Profile

You will need to import both of the following modules every time you start up by adding them to the PowerShell profile. I have described the process of creating a profile.

See my PowerShell profile: __Download

You need a PowerShell profile file to start modules start every time and to assign aliases.

Windows has 6 PowerShell profiles . All hosts, current and all users is loaded every time, The others depend on the users, host and whether it is console or the ISE editing environment:

Host→
User ↓
All Hosts Current Host - Console Current Host - ISE
All Users $PsHome\Profile.ps1 $PsHome\Microsoft.PowerShell_profile.ps1 $PsHome\Microsoft.PowerShellISE_profile.ps1
Current User $Home\[My ]Documents\Profile.ps1 $profile a.k.a.;
$Home\[My ]Documents\WindowsPowerShell\Profile.ps1
$Home\[My ]Documents\WindowsPowerShell\Microsoft.P owerShellISE_profile.ps1

The All Hosts scripts and the All & Current User scripts for the current host scripts will run EVERY SINGLE TIME you open powershell in a Host. Ie command line or the ISE software.

All the following will go into the Current user, command line script found with the powershell environment variable : $profile.

$PSHome by contrast shows the installation directory for Powershell.

First, create the profile file if it doesn’t already exist:

if (!(Test-Path -Path $PROFILE ))
{ New-Item -Type File -Path $PROFILE -Force }

Open the Profile:

notepad $profile

Re-direct the profile to a file in your personal directory where all your dotfiles and profiles can be stored and synced in a git repo. Paste in the following to the $profile notepad file and save.

. $env:userprofile/profiles/pwsh.ps1

Or in linux:

. "~/.config/pwsh.ps1"

Then run the install scripts to get all the modules.

Commands

In PowerShell, the Write-Host and Write-Output cmdlets are used to write text to the console, but they have some important differences in their behavior and use cases.

Write-Host is used to display text on the console and its output is not captured by the pipeline. This means that the output of Write-Host is not passed to the next command in the pipeline, and it is not available for redirection or variable assignment.

Write-Output is used to send text to the pipeline and its output is captured by the pipeline. This means that the output of Write-Output is passed to the next command in the pipeline, and it is available for redirection or variable assignment.

Here is an example that illustrates the difference between Write-Host and Write-Output:

$output = “Hello World” Write-Host $output Write-Output $output

In this example, the string “Hello World” is assigned to the $output variable and then passed to both Write-Host and Write-Output. The output of Write-Host is displayed on the console, but the output of Write-Output is not displayed, but it is passed to the pipeline and can be assigned to a variable or passed to the next command.

In general, it’s recommended to use Write-Output instead of Write-Host in scripts and functions because it allows for more flexibility and composability, but if you want to display text on the console without affecting the pipeline, you can use Write-Host.

Please let me know if you have any more questions on this topic.

Add Icons to ls standard output

The fastest improvement you can make it to decorate your file-lists with colour and icons.

Install-Module -Name Terminal-Icons -Repository PSGallery
Import-Module -Name Terminal-Icons

oh-my-posh

My oh-my-posh theme file is here: Download.

On windows, install with winget:

winget install JanDeDobbeleer.OhMyPosh -s winget

ON linux install manually:

sudo wget https://github.com/JanDeDobbeleer/oh-my-posh/releases/latest/download/posh-linux-amd64 -O /usr/local/bin/oh-my-posh
sudo chmod +x /usr/local/bin/oh-my-posh

mkdir ~/.poshthemes
wget https://github.com/JanDeDobbeleer/oh-my-posh/releases/latest/download/themes.zip -O ~/.poshthemes/themes.zip
unzip ~/.poshthemes/themes.zip -d ~/.poshthemes
chmod u+rw ~/.poshthemes/*.omp.*
rm ~/.poshthemes/themes.zip

Check it works:

oh-my-posh init pwsh | Invoke-Expression

You should see a more colourful terminal with these placeholder characters: ▯

You have to install a font which can represent all the relevant character with:

oh-my-posh font install

This didn’t work for me, so I had to download the ‘nerd’ fonts manually from Nerdfonts.com. Open the downloaded folder, then right-click on the ‘complete’ version of any given font of your choosing and install it into windows. Now you can go into the settings of your PowerShell profile in the terminal and adjust the font to the appropriate one.

git symbols

StackOverFlow

Symbol Description
Remote: GitHub / GitLab
Branch name
Remote: ‘Up to date’
Remote: Ahead
Remote: Behind
? Worktree: Untracked files
~ Worktree: Modified files
+ Index: Staged new files
~ Index: Staged Modified files
? Index: Conflicted files

Edit The Themes

You will very quickly find that the default theme is to cluttered and annoying. Each theme is completely defined by a .json config file. All the emojis are predefined in the oh-my-posh software, so all you themes do is turn features on an off, right or left align and change colours.

You can go into the themes folder and change the theme config json. When you installed the oh-my-posh software, it should have created the environment variable called ‘‘POSH_THEMES_PATH”. Mine is at %userprofile%\scoop\apps\oh-my-posh\current\themes.

oh-my-posh init pwsh --config 
"$env:POSH_THEMES_PATH/bubblesextra.omp.json" | Invoke-Expression

Note, that %userprofile%\… is the CMD format path which is in the environment variables in the Windows System Properties Window. The equivalent Powershell format is $env:userprofile\… or shorthand: ~\… . CMD and Powershell have different environment variable syntax. %…% vs $env:….

Each emoji item in a theme is represented as a ‘segment’ item in the .json file. Sadly, there are no images in the oh my posh website so you have to experiment with deleting things and turn on true and false parameters to see what is is what. The git segment is particularly confusing. The actual emoji they render don’t correspond to any Unicode code points, so they seem to have created custom svgs, rather than using stock emoji.

There is also two different git segments git and poshgit. Apparently posh-git is a newer but different implementation, the stock themes don’t seem to use it and it is an identical copy, but it just also includes auto-completion. It breaks my oh my posh, so I ignore it. Perhaps you have to install it separately.

I use the bubblesextra.omp.json default theme with a few edits.

Powershell Autocomplete

The best way to improve your efficiency in the command line is to add autocompletion. There are a few different types:

  • Tab-completion: press tab and it toggles folder or file suggestions.
  • Menu-complete: press Ctrl-Space and it displays either folder-file suggestion or command option in a tabular menu, which you can navigate around with arrow keys.
  • Auto-prediction: press the right-arrow and it auto-completes the full command based on either history or autogenerated predictions.

PSReadline provides Menu-complete and auto-prediction. poshgit provides menu-complete for git commands and z provides auto-prediction for folder-paths.

PowerShell Profile

You will need to import all of these modules every time you start up by adding them to the PowerShell profile. I have described this at in PowerShell profile.

See my PowerShell profile: __Download

Install z Module

z … is functionally equivalent to cd … but it remembers your recent calls, so you can press tab halfway through to autocomplete. It prioritises autocompletion suggestions via recency and frequency. Z is the most useful module I have.

A quick-start guide is here.

Here is the source code.

Install-Module z -AllowClobber

Some additional commands:

z -l # list z dirs
z -d # Delete dead path from suggestions
z -x # remove the current directory from the list

poshgit

Poshgit provides:

  • Menucomplete for git commands (Ctrl +Space)
  • A less pretty Git status summary information than oh-my-posh (Disabled by default if using oh-my-posh).

First install nuget:

Install-PackageProvider -Name NuGet

Command line didn’t work for me , so I installed from nuget.org

Then install posh-git from nuget:

PowerShellGet\Install-Module posh-git -Scope CurrentUser -Force
Import-Module posh-git

Instructions at GitHub

Now you should be able to menu-complete with git.

PSReadline

PSReadline provides:

  • Autocomplete for PowerShell command (From a Predictor and/or history) (Arrow Keys)
  • MenuComplete for PowerShell commands (Ctrl + Space)

First check PowerShell version is 7 or above. Need to download the v7 or later newest one from windows store.

`$PSVersionTable.PSVersion`

Install the module:

Install-Module PSReadLine

Install the Azure commands prediction plugin separately. This is explained basically nowhere, but I found the commands here.

Install-module -name Az.Accounts -Force
Install-module -name Az.Tools.Predictor -Force
Enable-AzPredictor -AllSession

I also added the CompletetionPredictor but it didn’t seem to add any useful suggestions.

Install-Module -Name CompletionPredictor -Repository PSGallery
Import-Module -Name CompletionPredictor

I actually leave both of these plugins deactivated as they add 10s to the start-up time.

Display Options

Now you have installed, you have 2 choices for your suggestions:

  1. Choose between history and plugins:
Set-PSReadLineOption -PredictionSource HistoryAndPlugin # or History or Plugin or  none
  1. Choose between Inline suggestions and tabulated suggestions. Press F2 to change the prediction style.

PSReadline Useful Resources

Windows ‘User Shell Folders’

This is the name for my documents, Videos, Pictures etc.

These all have registry keys. Registry keys are the default locations for various types of files and folders on a user’s system. It is effectively a list of paths.

If you have an invasive work environment installed, they may change these and confuse the hell out of your. Why is my PowerShell profile suddenly in the wrong place for example? Because the registry key for the ‘Personal’ User Shell Folder was changed.

See the locations with:

Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders'

Why is there 3 Program Files Directories on Windows?

The Program Files and Program Files (x86) folders in Windows are used to store the files and resources for installed software and applications. These folders are specific to a particular user, meaning that the files and folders in these directories are only accessible to the user who installed the software or application. The Program Files (x86) folder is used to store 32-bit software, which can run on both 32-bit and 64-bit processors. This allows for software to be installed in the appropriate folder based on its architecture, which can help to ensure that the software runs correctly and that there are no compatibility issues.

The ProgramData folder, on the other hand, is used to store data that is not specific to a particular user and is intended to be shared by multiple users.

Commands

If you want to run a path with spaces in cmd you would just do:

"C:\Program Files\My Program\myprogram.exe"

Whereas in powershelllyou need to add an &

& "C:\Program Files\My Program\myprogram.exe"

Likewise if you want to add arguements, add a second space speared string.

Errors

Different path in system to the powershell path.

Change might be “delayed”, so try one or more of these solutions:

  • Log off and on again;
  • Task Manager > Restart “Windows Explorer” (explorer.exe)
  • Restart your launcher app (launchy, SlickRun, etc)
  • Reboot

If there are any current installs running or other processes, then you may have to wait for them to finish before the PowerShell path is updated.

![[Pasted image 20230111163340.png]]

VSCode PowerShell throws errors:

It may say PSFalsePS. This is a vscode specific thing which means its loading a different PS to the default for the software.

Code command prints the VSCode log to the terminal:

Remove :

C:\Program Files\Microsoft VS Code\

From the path.

Add instead the bin subfolder:

C:\Program Files\Microsoft VS Code\bin

This will run code.cmd not code.exe.

Can’t Find Modules

Check $env:path and $env:PSModulePath for the module files.

get-module -listavailable

WinGet

Can’t get source or add source:

winget source reset --force

& was unexpected at this time.

You have an autorun on your CMD in the registry

Run:

Get-ItemProperty -ea Ignore ('HKCU:', 'HKLM:' -replace '$', '\Software\Microsoft\Command Processor') AutoRun |
  Remove-ItemProperty -Name AutoRun -WhatIf

Remove the -WhatIf when you’re happy what you’re doing.