Windows Terminal PowerShell Tips

Profile Specific Settings in profile.ps1

There is an environment variable that holds the ID of the current Windows Terminal profile.

$env:WT_PROFILE_ID

I use it so that I have PSReadLine set to ListView for all but 1 profile. I have a terminal profile for presentations and find ListView to be potentially distracting.

if($env:WT_PROFILE_ID -ne "{4da51a9a-dad3-44bb-a925-38956366f573}"){
    Set-PSReadLineOption -PredictionViewStyle ListView
}

To see the profile id, you can view the JSON settings file for Windows PowerShell and take the guid for the profile you want (including {}). You can also run $env:WT_PROFILE_ID to see the id of the current profile.

C:\> $env:WT_PROFILE_ID
{4da51a9a-dad3-44bb-a925-38956366f573}
C:\>



Creating Custom Set-Location Aliases.

Sometimes you find yourself going to the same directories over and over again. It becomes helpful to have a quick way to navigate to those directories. A convenient way is to set a hashtable with the alias name and corresponding path.

$locationAliases = @{
	repos = "C:\Users\UserName\source\repos";
	proj = "C:\Git\Projects";
	cd2 = "..\..\";
	cd3 = "..\..\..\";
}

We can then make a single function making use of the $MyInvocation Automatic variable. This way we can determine which alias was used to call the function.

function Set-Location-Custom{
	&Set-Location $locationAliases[$MyInvocation.InvocationName]
}

Then just loop through the keys in the hashtable and create the aliases.

foreach($key in $locationAliases.Keys){
	Set-Alias -Name $key -Option AllScope -Value Set-Location-Custom
}

Some more advanced functionality

Say you want these to work more like the standard Set-Location command. With tab autocompletion to directories relative to the specific location. In that case we just modify the Set-Location-Custom command to take a parameter for Path.

function Set-Location-Custom {
	param(
		[String]$Path
	)
	process{
		$fullPath = Join-Path -Path "$($locationAliases[$MyInvocation.InvocationName])\" -ChildPath $Path;
		if (-not (Test-Path -Path $fullPath -PathType Container)){
			throw "Invalid path: $fullPath"
		}
		Set-Location $fullPath
	}
}

Then we just need to register a custom argument completer to give us the autocompletion we need.

Register-ArgumentCompleter -CommandName Set-Location-Custom -ParameterName Path -ScriptBlock {
	param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)

	# Set-Location-Custom is always called with an alias. We need to get that alias and find the coresponding directory.
	$path = $locationAliases[$commandAst.CommandElements[0].Extent.Text]
	
	# Change any forwardslashes to backslashes
	$wordToComplete = $wordToComplete -replace '/','\'
	
	if (-not $wordToComplete){
		# No input, so list all directories in the $path directory
		$directories = Get-ChildItem -Path $path -Directory | ForEach-Object { $_.Name + '\'}
	} elseif ($wordToComplete -notlike "*\*"){
		# There is input that does not contain any backslashes, so list directories that match the input in the $path directory
		$directories = Get-ChildItem -Path $path -Directory -Filter "$wordToComplete*" | ForEach-Object { $_.Name + '\'}
	} else{
		# The input contains at least one backslash, so list directories that match <input after last backslash>, in the directory ($path + <input through last backslash>)
		$prefix, $suffix = $wordToComplete -split '\\(?=[^\\]+$)', 2 # split input into two parts at the last backslash
		$prefix = $prefix.TrimEnd('\') + '\' # Depending on input, $prefix may or may not have an ending backslash. This makes sure there always is one and only one
		
		$path = Join-Path -Path $path -ChildPath $prefix
		$directories = Get-ChildItem -Path $path -Directory -Filter "$suffix*" | ForEach-Object { "$prefix$($_.Name)\" }
	}
	return $directories
}



Removing the Windows Message When You Launch a PowerShell.

If you want to remove this message for a cleaner look:

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

Loading personal and system profiles took 586ms.

Go into the Windows Terminal Settings. Select the PowerShell profile you want to remove the message from. Edit the "Command line" setting. Add /nologo after powershell.exe. Mine looks like this.

powershell.exe /nologo