WINDOWS POWERSHELL

Git, Readline Bash and Custom Prompt

PowerShell modules can enhance functionality and the user interface. In this example, the profile is updated to use git over an SSH connection, readline settings for a bash like experience, custom color output and a custom prompt.

PowerShell Profile

If there is not an existing profile for the current logged in user, create one with the New-Item cmdlet. To check if a profile exists, use Test-Path $profile. $profile is an environmental variable for the path to the CurrentUserCurrentHost profile.

Test-Path $profile

If the test returns false, use the New-Item cmdlet to create the profile script. For example:

New-Item $profile -ItemType File -Force

There should now be a WindowsPowerShell\Microsoft.PowerShell_profile.ps1 file in the Documents folder.

My Customized PowerShell
PowerShell screenshot with the updated profile loaded using the ls command alias to list files.

Custom Prompt

Add these two functions to the top of the Microsoft.PowerShell_profile.ps1 script. The first function checks to see if PowerShell is running with Administrator privileges. This check is used to add (Elevated) to the prompt as needed. The second function, aptly named prompt modifies it’s output.

Microsoft.PowerShell_profile.ps1
function Test-Administrator {
    $user = [Security.Principal.WindowsIdentity]::GetCurrent();
    (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}

function prompt {
    # https://github.com/dahlbyk/posh-git/wiki/Customizing-Your-PowerShell-Prompt
    $origLastExitCode = $LastExitCode
    Write-VcsStatus

    if (Test-Administrator) {  # if elevated
        Write-Host "(Elevated) " -NoNewline -ForegroundColor White
    }

    Write-Host "$env:USERNAME@" -NoNewline -ForegroundColor DarkYellow
    Write-Host "$env:COMPUTERNAME" -NoNewline -ForegroundColor Magenta
    Write-Host ": " -NoNewline -ForegroundColor DarkGray

    $curPath = $ExecutionContext.SessionState.Path.CurrentLocation.Path
    if ($curPath.ToLower().StartsWith($Home.ToLower()))
    {
        $curPath = "~" + $curPath.SubString($Home.Length)
    }2018/12/new-webpack-development-2018/12/new-webpack-development-server-pluginserver-plugin

    Write-Host $curPath -NoNewline -ForegroundColor Green

    $LastExitCode = $origLastExitCode
    "`n$('>' * ($nestedPromptLevel + 1)) "
}

PSReadline

Next, Import the PSReadline module that is included with PowerShell 5.x and set some configuration options.

Microsoft.PowerShell_profile.ps1
Import-Module PSReadLine

Set-PSReadLineOption -HistoryNoDuplicates
Set-PSReadLineOption -HistorySearchCursorMovesToEnd
Set-PSReadLineOption -HistorySaveStyle SaveIncrementally
Set-PSReadLineOption -MaximumHistoryCount 4000
# history substring search
Set-PSReadlineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadlineKeyHandler -Key DownArrow -Function HistorySearchForward

# Tab completion
Set-PSReadlineKeyHandler -Chord 'Shift+Tab' -Function Complete
Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete

SSH Agent

Since the release of OpenSSH in Windows, this is no longer needed.

We will use Mark Embling’s ssh-agent-utils Powershell script with functions for starting and managing ssh-agent. Download the ssh-agent-utils.ps1 Gist and place the script into the WindowsPowerShell folder for current logged in user, for example, %UserProfile%\Documents\WindowsPowerShell. In this example, both Microsoft.PowerShell_profile.ps1 and ssh-agent-utils.ps1 should be in the same WindowsPowerShell folder.

Install these modules into the default PSModulePath for the current logged in user, for example, %UserProfile%\Documents\WindowsPowerShell\Modules. PowerShellGet is required, which is included in Windows 10 and WMF 5.

posh-git

The posh-git module integrates Git and PowerShell.

Install-Module posh-git -Scope CurrentUser

Check the prerequisites in the posh-git repository to make sure Git is properly configured for use.

Get-ChildItemColor

The Get-ChildItemColor module adds colors to the output of Get-ChildItem cmdlet.

Install-Module Get-ChildItemColor -Scope CurrentUser

Finally, import and setup the remaining modules and load the SSH agent utilities.

Microsoft.PowerShell_profile.ps1
Import-Module Get-ChildItemColor

Set-Alias l Get-ChildItemColor -option AllScope
Set-Alias ls Get-ChildItemColorFormatWide -option AllScope

Import-Module posh-git

$global:GitPromptSettings.BeforeText = '['
$global:GitPromptSettings.AfterText  = '] '

# Update path for SSH (Loaded in PowerShell Profile)
$env:path += ";" + (Get-Item "Env:ProgramFiles").Value + "\Git\bin"
$env:path += ";" + (Get-Item "Env:ProgramFiles").Value + "\Git\usr\bin"

# Load SSH agent utils
. (Resolve-Path ~/Documents/WindowsPowershell/ssh-agent-utils.ps1)

Pop-Location

Add-SshKey

Solve “filename too long” error by changing the long paths support in Git for Windows that is disabled by default.

git config --system core.longpaths true

Folders and Files

Here is a tree view of the folders, ssh-agent-utility and profile scripts used in the examples.

  • Documents
    • WindowsPowerShell
      • Modules
        • Get-ChildItemColor
        • posh-git
      • Microsoft.PowerShell_profile.ps1
      • ssh-agent-utils.ps1
Source Code

Resources

comments powered by Disqus