My PowerShell profile

We all like to customize our PowerShell profile to our own needs, so there is no right or wrong in how to do this, but I’d like to show you mine nonetheless.

UPDATE: Kirk Munro (@Poshoholic) was good enough to point out that I had a bug in my path shortener, so in the process of rewriting it, I decided to do a small overhaul of my entire PowerShell Profile.

# PowerShell Profile – Øyvind Kallstad
# Last updated: 27.11.2014
# Get the original prompt
$originalPrompt = (Get-Item function:prompt).ScriptBlock
# define our new custom prompt
$customPrompt = {
$currentLocaction = $executionContext.SessionState.Path.CurrentLocation.ToString()
$host.UI.RawUI.WindowTitle = $currentLocaction.Replace('Microsoft.PowerShell.Core\','')
Write-Host '[' NoNewLine
if (Test-Path variable:/PSDebugContext) {
Write-Host 'DBG' NoNewline ForegroundColor 'Red'
Write-Host "$($env:COMPUTERNAME)" NoNewLine ForegroundColor 'Red'
Write-Host "$($env:COMPUTERNAME)" NoNewLine ForegroundColor 'DarkGray'
Write-Host "] $(Invoke-PathShortener $currentLocaction)$('>' * ($nestedPromptLevel + 1))" NoNewLine
return ' '
# define a demo prompt
$demoPrompt = {
$host.UI.RawUI.WindowTitle = $executionContext.SessionState.Path.CurrentLocation.ToString()
return '[Øyvind Kallstad] > '
function Set-Prompt {
param ([ScriptBlock] $ScriptBlock)
$null = New-Item Path function:prompt Value $ScriptBlock Force
function Invoke-PathShortener {
Path Shortener
Author: Øyvind Kallstad
Date: 27.11.2014
Version: 1.0
param (
# Path to shorten.
[Parameter(Position = 0)]
[string] $Path,
# Defines how many path levels to keep after the root before shortening.
[Parameter(Position = 1)]
[int] $KeepAfterRoot = 1
$regexString = '^(.+:{1,2}|\\{2}.+?\\.+?(?=\\))(.*)'
$separator = [System.IO.Path]::DirectorySeparatorChar
# first we need to clean up the path
if ($path.StartsWith('Microsoft.PowerShell.Core\FileSystem')) {
$path = $path.Replace('Microsoft.PowerShell.Core\FileSystem::','')
elseif ($path.StartsWith('Microsoft.PowerShell.Core')) {
$path = $path.Replace('Microsoft.PowerShell.Core\','')
# use regex to separate the root from the rest of the path
$matches = [regex]::Matches($path,$regexString)
$pathRoot = $matches.Groups[1].Value
$pathRest = ($matches.Groups[2].Value).TrimStart('\')
# split on the separator character to get an array of path parts
$pathParts = $pathRest.Split($separator)
# put together the outpath string
if ($pathParts) {
if ($pathParts.Length -ge ($KeepAfterRoot + 2)) {
$outPath += $pathRoot
for ($i = 0; $i -lt $KeepAfterRoot; $i++) {
$outPath += $separator + $pathParts[$i]
$outPath += '' + $separator + $pathParts[-1]
else { $outPath += $pathRoot + $separator + $pathRest }
else { $outPath += $pathRoot }
Write-Output $outPath
function Open-SublimeText{
# Øyvind Kallstad //2014
[Parameter(ValueFromPipeline = $true, ValueFromPipelinebyPropertyName = $true)]
if(-not(Test-Path Path $env:ProgramFiles Filter '\Sublime Text *\sublime_text.exe')){break}
$p = @()
foreach ($thisPath in $Path) {
$p += $thisPath
$exe = ((Get-Item "$($env:ProgramFiles)\Sublime Text *\sublime_text.exe" | Sort-Object 'LastWriteTime' Descending | Select-Object First 1).FullName)
& $exe $p
function Invoke-GetLocationEx { (Get-Location).ToString() }
function Invoke-IsAdmin {
$windowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($windowsIdentity)
Write-Output ($windowsPrincipal.IsInRole($adm))
Set-Alias Name 'st' Value 'Open-SublimeText'
Set-Alias Name 'pwd' Value 'Invoke-GetLocationEx' Option 'AllScope' Force
Set-Prompt $customPrompt
Set-Location Path 'E:\Users\ojk\Documents\Scripts'
$env:Path += ';C:\Program Files (x86)\ConfigMgr 2012 Toolkit R2\ClientTools'
if ($Host.Name -eq 'Windows PowerShell ISE Host') {
Import-Module 'ISESteroids'
Start-Sleep Seconds 2

I start by saving the original PowerShell prompt. I then define my new custom prompt, as well as a third demo prompt. I created a short function (Set-Prompt) that I can use to change my prompt on the fly with the prompts I have predefined in my profile.

Next I have my new and improved path shortener, that now also works when using PowerShell providers like registry, variable etc.

I have also created a function that lets me open files for editing in Sublime Text, as well as an extension function of Get-Location (that I later use when overriding the pwd alias further down).

I also converted my old code to check if the current user is running as admin to a function instead.

Next are my alias definitions, followed by setting the new prompt, my custom location and updating my environment variables.

Lastly I load my modules. I have included a check for ISE so that I can use the same profile for both ISE and the normal host.

That’s it. Any comments and suggestions are always welcome!


  1. My profile looks alot like Ed Wilson’s. I copied his years ago, but I like what you’re doing with yours as well. I plan on stealing some of your ideas too, after I take a nap.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s