Terminal & PowerShell

  Windows   Terminal   PowerShell

Remember

  • Windows Terminal documentation
  • Use CTRL + Space to show “MenuComplete” i.e. available options based on the input provided so far
  • Use Arrow key (right) for basic auto-complete
  • Set up advanced auto-complete - see this article
  • Toggle command history with F2

Customise Windows Terminal default layout

  1. Create a desktop shortcut
  2. Set the target as C:\Users\[Username]\AppData\Local\Microsoft\WindowsApps\wt.exe
  3. Append any customisations to the above target, e.g. -p "PowerShell 7 (x86)" ; split-pane -H -p "Ubuntu" to open with two horizontal panes with Powershell and Bash
  4. Add a keyboard shortcut and/or select Open as Administrator if you want

Autostart Windows Terminal with Powershell in quake mode

  1. Hit Win + R and type shell:startup to open the Startup folder
  2. Create a shortcut with the target "C:\Program Files\PowerShell\7\pwsh.exe" -WorkingDirectory ~ -Command wt -w _quake pwsh -window minimized

Basic commands

Check version of PowerShell

(Get-PSReadlineOption).HistorySavePath

Find your PowerShell command history

$PSVersionTable

Get & display content of a file i.e. cat equivalent

gc [file_name]

Use WSL

List all distros:

wsl --list --verbose

Shutdown one distro:

wsl -t [distro_name]

Shutdown all distros:

wsl --shutdown

Restart a distro:

wsl --distribution [distro_name]

Get and unzip an archive file

wget [URL + file_name]
Expand-Archive ./filetounzip.zip ./folder-to-extract-to

Copying files

xcopy "some_folder\subfolder\" "another_folder\subfolder\" /E /K /D /H /Y

Find directory of a process

Get-Process -Id $PID # Name of current shell you are running
(Get-Process [outcome_of_above] | select -First 1).Path # Returns absolute directory

Using variables

Get environment variable:

echo $env:JAVA_HOME

Get variable:

Get-Variable -Name "VARIABLE_NAME"

Set global environment variable:

setx VARIABLE_NAME "some_value"

Set variable:

The below won’t set the variable permanently. If you want to retain the variable beyond the current session, consider adding it to your profile or with the above method.
Set-Variable -Name "desc" -Value "A description" 

# Syntax
Set-Variable 
   [-Name] <String[]> 
   [[-Value] <Object>] 
   [-Include <String[]>] 
   [-Exclude <String[]>] 
   [-Description <String>] 
   [-Option <ScopedItemOptions>] 
   [-Force] 
   [-Visibility <SessionStateEntryVisibility>] 
   [-PassThru] 
   [-Scope <String>] 
   [-WhatIf] 
   [-Confirm] 
   [<CommonParameters>]

Working with your Powershell profile

Open the profile:

code $profile

Add variable to profile:

# Paste variable you want to set into your profile like this:
Set-Variable -Name "LOCAL_POSTGRES_PASSWORD" -Value "password" -Scope global 

Add simple alias for an application:

Set-Alias -Name idea -Value 'C:\{...}\IntelliJ IDEA Ultimate\bin\idea64.exe'
Set-Alias -Name webstorm -Value 'C:\{...}\WebStorm\bin\webstorm64.exe'
Set-Alias -Name rider -Value 'C:\{...}\Rider\bin\rider64.exe'

Add alias with args for an application:

# Example with Visual VM and Zulu 17 JDK, allowing for additional args
function Start-VisualVM {
    & 'C:\Program Files\visualvm_217\bin\visualvm.exe' --jdkhome "C:\Program Files\Zulu\zulu-17" --userdir "C:\Users\{...}\visualvm_userdir" $args
}
Set-Alias -Name visualvm -Value Start-VisualVM

Set “aliases” for folders:

# Allows changing folder e.g. 'fo user'
function fo {
    switch ($args[0]) {
        {$_ -eq "user" -or $_ -eq "home"} { Set-Location -Path 'C:\Users\{...}' }
        {$_ -eq "ssh"} { Set-Location -Path 'C:\Users\{...}\.ssh' } 
        {$_ -eq "aws"} { Set-Location -Path 'C:\Users\{...}\.aws' } 
        {$_ -eq "pro"} { Set-Location -Path 'C:\Users\{...}\projects' }
        default {
            Write-Host "Error: Folder not recognised."
            Write-Host "Recognised folders are user/home, ssh, aws, pro."
      }
    }
}

Set “aliases” for files:

# Allows opening files in VS Code e.g. 'fi ssh'
function fi {
    switch ($args[0]) {
        {$_ -eq "ssh"} { code 'C:\Users\{...}\.ssh\config' } 
        {$_ -eq "aws"} { code 'C:\Users\{...}\.aws\config' } 
        {$_ -eq "p" -or $_ -eq "profile"} { code $profile } 
        default { 
            Write-Host "Error: File not recognised." 
            Write-Host "Recognised files are ssh, aws, p/profile."
        }
    }
}

Reload/refresh profile:

.$profile

Other random things:

Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete # Enables auto-complete
$env:POWERSHELL_UPDATECHECK = 'Off' # Disables update banner in Terminal startup

Useful scripts/snippets

The grep equivalent / Select-String

Example for processing a single file and storing output in new file:

Get-Content -Path SomeFile.log | Select-String -Pattern "`"500`"" | Out-File -FilePath 500.log

Example for processing multiple files and storing output in new file:

Get-ChildItem -Filter *.log | ForEach-Object { Select-String -Path $_.FullName -Pattern "`"500`"" } | Out-File -FilePath 500.log

Split command output and print line by line

# Maven dependencies classpath example
& ./mvnw dependency:build-classpath | ForEach-Object { $_ -split ';' }

Switch between different Java versions

  1. Create the folder C:\Program Files\Java\scripts

  2. Paste the following scripts (and/or new scripts for other Java versions):

    # File name: switchto-java11.ps1
    $Env:JAVA_HOME="C:\Program Files\Java\jdk-11" 
    $Env:Path="$Env:JAVA_HOME\bin;$Env:Path" 
    Write-Host Java 11 activated.
    
    # File name: switchto-java17.ps1
    $Env:JAVA_HOME="C:\Program Files\Java\jdk-17" 
    $Env:Path="$Env:JAVA_HOME\bin;$Env:Path" 
    Write-Host Java 17 activated.
    
  3. Add C:\Program Files\Java\scripts to Path so you can access the scripts from anywhere

  4. Modify/set up other Java-related environment variables like so:

    1. The user variables (top section of the environmental variables window) should not contain any Java-related entries
    2. The lower list (“System variables”) should contain an entry JAVA_HOME = C:\Program Files\Java\jdk-19 (or similar, depending you the Java version and installation directory).
    3. Delete the following entries under “Path” (if they exist): C:\ProgramData\Oracle\Java\javapath and C:\Program Files (x86)\Common Files\Oracle\Java\javapath
    4. Insert the following Path variable %JAVA_HOME%\bin

Show list of options for incomplete prompt

  1. Update your profile
    Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete
    
  2. When typing a prompt, press the Tab key to display available options to choose from

Copy port number for Docker container to clipboard

This is useful when working with Docker containers with random ports that you need to access frequently. Example for Mysql container:

$sql_docker_container=$(docker ps | Select-String -Pattern "mysql:")
if ($null -eq $sql_docker_container) {
  Write-Host "Port number not found. Check if Mysql container is running."
} else {
  $port_number=$sql_docker_container -replace '.*:(\d+).*', '$1' | ForEach-Object { $_.Trim() }
  Set-Clipboard -Value $port_number
  Write-Host "Mysql port number ($port_number) copied to clipboard."
}