Customizing PowerShell–Using $Profile

A copy of the profile described here is at: Charlie_Profile

Probably one of the first scripts any new Windows PowerShell user writes is a custom profile. Your PowerShell profile ($profile in PowerShell speak), is run every time you open a PowerShell window, and it allows you to do a lot of different things to set up your environment the way you want it. Actually, though, there are four profiles that affect your PowerShell window, as described in this MSDN article. There are arguments for which profile you should be editing, but my personal preference is to use the most specific one:

%UserProfile%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

The only problem is, that’s not really were “My Documents” is for me. So, how to be sure you always work on the right one, wherever it’s located? Easy – let PowerShell tell you!

First, let’s see if we have a $profile yet:

PS1> Test-Path $profile
False

Nope. So, how to make one. First,let’s create the path:

PS1> mkdir (Split-Path $profile)

    Directory: C:UserscprDocuments

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        12/22/2010  12:05 PM            WindowsPowerShell

Now,use your favourite plain text editor to create the file. In my case that would be:

PS1> gvim $profile

And here you can start to build your customizations for PowerShell. There are lots of possibilities, including changing the colouring, updating the title bar, creating aliases and functions that are always available. Really the possibilities are nearly endless.

In my own case, I like to distinguish between a regular window and an elevated one, so I change the colour of all my regular PowerShell windows to white with dark blue text (works better for screen shots), and my elevated windows to dark red with white text. I also use a multiline prompt, and do some other customizations.

Here’s my full $profile:

# This is Charlie”s custom PS Profile…
#
# ModHist: 26/05/2007 – Initial
#        : 08/06/2007 – Added clear-host and winzip alias
#        : 10/06/2007 – Changed OS detection
#        : 22/07/2007 – support for running from local home
#        : 14/03/2008 – changed to Microsoft.PowerShell_profile.ps1
#        : 16/03/2008 – added productID test for Vista
#        : 24/03/2009 – added mapdrives for admin shell
#        : 17/10/2010 – minor cleanup before sending to VanTUG
#        : 26/02/2011 - modified to post cleaner on WordPress
#
#***************************************************************************
#

# Get the name of this version...
$CallingProfile = $myInvocation.mycommand.path
$FileRegEx = "(?<name>.*)(?<dot>\.)(?<extension>[pP][sS]1)"
$CallingProfile -match $FileRegEx

# Find out who we are...
$id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$p = New-Object system.security.principal.windowsprincipal($id)
$admin=$p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)

# Get System WMI info -- Get it once, use it multiple
$SysWMI =  Get-WmiObject Win32_OperatingSystem
$hostname = $(hostname).tolower()
$otherway = ($ENV:computername).tolower()

$ProdID=(gi ''HKLM:/Software/Microsoft/Windows NT/CurrentVersion'').getvalue(''ProductID'')

# Build a hashtable with information about versions, etc.
$SystemHash = @{}  # Initialize the variable as a hashtable
$SystemHash["Build"] = $SysWMI.BuildNumber
$SystemHash["SPNumber"] = $SysWMI.CSDVersion
$SystemHash["Caption"] = $SysWMI.Caption
$SystemHash["SKU"] = $SysWMI.OperatingSystemSKU
$SystemHash["Architecture"] = $SysWMI.OSArchitecture
$SystemHash["Hostname"] = $SysWMI.CSName.ToLower()
$SystemHash["Arch"] = $ENV:Processor_Architecture
$SystemHash["ProductID"] = $ProdID

# We’ll need the build number to persist in the environment
$Build = $SystemHash["Build"]

switch -regex ($SystemHash["Build"]) {
2600 { $ver="XP" }
3790 { if ($SystemHash["Caption"] -match "XP") {
$ver = "XPx64"
} else {
$ver = "Server 2003"
}
}
6000 { $ver="Vista" }
6001 { if ($SystemHash["Caption"] -match "Vista" ) {
$ver="Vista"
} else {
$ver="Server 2008"
}
}
7600 { if ($SystemHash["Caption"] -match "Windows 7" ) {
$ver="Windows 7"
} else {
$ver="Server 2008 R2"
}
}
7601 { if ($SystemHash["Caption"] -match "Windows 7" ) {
$ver="Windows 7 SP1"
} else {
$ver="Server 2008 R2 SP1"
}
}
}

if ($SystemHash["Arch"] -eq "AMD64" ) {
$64bit=$true
$32bit=$false
} else{
$64bit=$false
$32bit=$true
}

# Find out if we''re running as admin (IsInRole)
# if we are, change the window colour and set effectivename variable
# But only on Windows Vista or Later
if ($admin -and ($build -ge 6000 ))
{
$effectivename = "Administrator"
$host.UI.RawUI.Backgroundcolor="DarkRed"
$host.UI.RawUI.Foregroundcolor="White"
clear-host
$maps=''C:\Windows\system32\mapdrives.cmd''  #cmd file to map standard drives
if (Test-Path $maps) {& $maps }
} else {
$effectivename = $id.name
$host.UI.RawUI.Backgroundcolor="White"
$host.UI.RawUI.Foregroundcolor="DarkBlue"
clear-host
}

$host.ui.rawui.WindowTitle = $effectivename + "@" + $HostName +" >"
function global:prompt {
if ( $effectivename -eq "Administrator" ) {
write-host ("[") -nonewline -foregroundcolor red
write-host ($Hostname) -nonewline -foregroundcolor Magenta
write-host ("]") -nonewline -foregroundcolor Red
Write-Host ([string]$(get-location) +":") -foregroundcolor Green
write-host ("PSH>" ) -nonewline -foregroundcolor White
} else {
write-host ("[") -nonewline -foregroundcolor red
write-host ($Hostname) -nonewline -ForegroundColor Magenta
write-host ("]") -nonewline -foregroundcolor Red
Write-Host ([string]$(get-location) + ''> '') -ForegroundColor DarkGreen
write-host ("PSH>" ) -nonewline -foregroundcolor DarkBlue
}
return " "
}

# function to elevate a command. Finally.
function sudo ([string]$file, [string]$arguments) {
$psi = new-object System.Diagnostics.ProcessStartInfo $file;
$psi.Arguments = $arguments;
$psi.Verb = "runas";
$psi.WorkingDirectory = get-location;
[System.Diagnostics.Process]::Start($psi);
}

# Now, a function to edit the executable script without knowing where it is.
function fvi
{
param($script )
$s = (get-command -ea silentlycontinue $script).definition
if ( $s ) { gvim $s }
else { "$script not found" }
}

# Update the path to make life easier, and add a function while we''re at it...
$ENV:Path="$ENV:PATH;" + "U:\psbin;" + "$ENV:HOMEDRIVE" + "$ENV:HOMEPATH" + "\psbin;"
function path {
write-host $env:path
}

# Now, start to build some aliases. These may be machine specific, so be careful...

if ($64bit) {
set-alias winzip -value "C:\Program Files (x86)\WinZip\WinZip32.exe"
set-alias word -value "C:\Program Files (x86)\Microsoft Office\Office14\WinWord.exe"
set-alias excel -value "C:\Program Files (x86)\Microsoft Office\Office14\Excel.exe"
set-alias OneNote -value "C:\Program Files (x86)\Microsoft Office\Office14\OneNote.exe"
set-alias Visio -value "& mstsc C:\Program Files (x86)\RemotePackages\Visio_2010.rdp"
set-alias hyperv -value "C:\Program Files\Hyper-V\virtmgmt.msc"
set-alias vm -value "C:\Program Files\Hyper-V\vmconnect.exe"
} else {
set-alias winzip -value "C:\Program Files\WinZip\WinZip32.exe"
set-alias word -value "C:\Program Files\Microsoft Office\Office14\WinWord.exe"
set-alias excel -value "C:\Program Files\\Microsoft Office\Office14\Excel.exe"
set-alias OneNote -value "C:\Program Files\Microsoft Office\Office14\OneNote.exe"
set-alias Visio -value "& mstsc C:\Program Files\RemotePackages\Visio_2010.rdp"
}

set-alias edit -value "C:Windows\gvim.bat"
set-alias vi -value "C:windows\gvim.bat"

# set-alias ping test-connection # disabled. More annoying than useful

# The following is useful if you have automatic startup PowerShell windows...
if ( ! $Admin ) {
cd $home
}

There, that’s complicated enough for most uses. :-)
But hopefully you’ll find some useful stuff in this that you can use for your own $profile.

Charlie.

Comments are closed.