Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
provides some useful information to your PowerShell prompt
function Prompt {
<#
.Synopsis
Your custom PowerShell prompt
# borrowing heavily from https://dbatools.io/prompt but formatting the execution time without using the DbaTimeSpanPretty C# type
.Description
Custom prompt that includes the following features:
- Admin user : if the current session is running as Administrator then the prompt shows [Admin] in black on red
- Battery : if you are working on your battery - % charged and est min remaining
- Day and date : the current day and date are shown at the left side of the prompt in all use-cases
- UTC offset : if the system timezone is not UTC then the offset in hours is shown Red/Green for + or - difference
- fun function : put some fun into your PowerShell prompt with a countdown to your next big event ()
- current path : shortens the path if there are more than 2 directories and truncates those to 7 characters
- last command : execution duration of the last command executed
#>
#region Show if using Administrator level account
$principal = [Security.Principal.WindowsPrincipal] ([Security.Principal.WindowsIdentity]::GetCurrent())
$adm = [Security.Principal.WindowsBuiltInRole]::Administrator
if ($principal.IsInRole($adm)) {
write-host -ForegroundColor "Black" -BackgroundColor "DarkRed" "[ADMIN]" -NoNewline
}
#endregion
#region Battery status
$b = (Get-CimInstance -ClassName CIM_Battery)
$Battery = $null
$Battery = @{
IsCharging = if ($b.BatteryStatus -eq 1) { $false } else { $true }
Charge = $b.EstimatedChargeRemaining
Remaining = $b.EstimatedRunTime
}
if ($Battery.Remaining -gt 90) {
$Battery.Remaining = "90m+"
}
else {
$Battery.Remaining = "$($Battery.Remaining.ToString())m"
}
Write-Verbose $Battery
if (!($Battery.IsCharging)) {
$msg = $b = $extramsg = $null
switch ($Battery.Charge[1]) {
{ $_ -gt 80 } {
$colour = "Green"
break
}
{ $_ -gt 60 } {
$colour = "DarkGreen"
break
}
{ $_ -gt 40 } {
$colour = "DarkRed"
break
}
{ $_ -gt 20 } {
$colour = "Red"
break
}
default {
$extramsg = "BATTERY VERY LOW :: SAVE YOUR WORK"
$colour = "yellow"
}
}
$msg = ("[{0}%:{1}{2}]" -f $Battery.Charge[1], $Battery.Remaining, $EXTRAmsg )
Write-Host -Object $msg -BackgroundColor $colour -ForegroundColor Black -NoNewline
}
#endregion
#region Day and date
$msg = "[{0}]" -f (Get-Date -Format "ddd HH:mm:ss")
Write-Host $msg -NoNewline
#endregion
#region UTC offset
# add info if not in home timezone
# get offset and daylight savings name
$tz = Get-TimeZone
$offset = $tz.BaseUtcOffset # need to place YOUR normal timezone here
[timespan]$adjustment = 0
# if we are in daylight saving then the offset from home will be 60 mins, not 0
if ($tz.id -eq $tz.daylightname) {
$adjustment = New-TimeSpan -minutes 60
}
$fc = "white"
$p = "GMT"
if (($offset.TotalMinutes + $adjustment.TotalMinutes) -ne 0) {
[double]$h = $offset.TotalMinutes / 60
if ($h -lt 0) {
$sign = ""
$fc = "Red"
}
else {
$sign = "+"
$fc = "Green"
}
$p = "(UK $sign$($h.ToString()))"
write-host -ForegroundColor $fc -BackgroundColor Black $p -NoNewline
}
#endregion
#region custom/fun function
if ((get-date).Month -eq 12 -and (get-date).Day -lt 25) {
$msg = "["
$msg += TimetoSanta -purpose Prompt
$msg += "]"
Write-Host $msg -NoNewline -BackgroundColor Red -ForegroundColor DarkBlue
}
#endregion
#region last command execution duration
try {
$history = Get-History -ErrorAction Ignore -Count 1
if ($history) {
$ts = New-TimeSpan $history.StartExecutionTime $history.EndExecutionTime
Write-Host "[" -NoNewline
switch ($ts) {
{$_.TotalSeconds -lt 1} {
[decimal]$d = $_.TotalMilliseconds
'{0:f3}ms' -f ($d) | Write-Host -ForegroundColor Black -NoNewline -BackgroundColor DarkGreen
break
}
{$_.totalminutes -lt 1} {
[decimal]$d = $_.TotalSeconds
'{0:f3}s' -f ($d) | Write-Host -ForegroundColor Black -NoNewline -BackgroundColor DarkYellow
break
}
{$_.totalminutes -lt 30} {
[decimal]$d = $ts.TotalMinutes
'{0:f3}m' -f ($d) | Write-Host -ForegroundColor Gray -NoNewline -BackgroundColor Red
break
}
Default {
$_.Milliseconds | Write-Host -ForegroundColor Gray -NoNewline
}
}
Write-Host "]" -NoNewline
}
}
catch { }
#endregion
#region reduce the path displayed if it is long
if (($pwd.Path.Split('\').count -gt 2)) {
$One = $pwd.path.split('\')[-1]
$Two = $pwd.path.split('\')[-2]
if ($One.Length -gt 10) {$One = "$($One[0..7] -join '')~"}
if ($Two.Length -gt 10) {$Two = "$($Two[0..7] -join '')~"}
write-host " $($pwd.path.split('\')[0], '...', $Two, $One -join ('\'))" -NoNewline
}
else {
Write-Host " $($pwd.path)" -NoNewline
}
#endregion
"> "
}
@fatherjack

This comment has been minimized.

Copy link
Owner Author

fatherjack commented Jul 12, 2018

Edit your profile and paste this function in to customise your PowerShell prompt to include the Day / Time and also the duration of the last command that you ran.
Duration shows milliseconds, seconds or minutes depending on actual duration.
2018-07-12_1306
2018-07-12_1313

Now updated to include a Red/Green hours offset from home timezone for when travelling (you'll need to change code to reference your own TZ outside UK) and also added a truncated path ahead of prompt following inspiration from @sqldbawithbeard
2019-01-26_1519

@billkindle

This comment has been minimized.

Copy link

billkindle commented Jul 13, 2018

Very nice!

@BadSqlPro

This comment has been minimized.

Copy link

BadSqlPro commented Aug 10, 2018

This is EXACTLY!!!! what I was searching for because I wanted something that will work even if the dbatools module was not loaded. Thank you very much!!

Btw, why is it necessary to name the function Prompt? I tried changing the name and it stopped working. Please help me understand.

@fatherjack

This comment has been minimized.

Copy link
Owner Author

fatherjack commented Jan 25, 2019

because it is the console prompt. If a function called Prompt exists it is used to define the prompt that you see rather than the default prompt

@fatherjack

This comment has been minimized.

Copy link
Owner Author

fatherjack commented Mar 12, 2019

bit of a revamp, added a '~' shortener if a folder name is over 10 characters
Prompt01

@fatherjack

This comment has been minimized.

Copy link
Owner Author

fatherjack commented Mar 16, 2019

Added section to identify if host is running as an Administrator level login
image

@fatherjack

This comment has been minimized.

Copy link
Owner Author

fatherjack commented Mar 16, 2019

code tidy up and regions added

@fatherjack

This comment has been minimized.

Copy link
Owner Author

fatherjack commented Apr 9, 2019

Battery status added - only visible when you are running on battery power. Was hoping to use 🔋 but cant :(

@jbirley

This comment has been minimized.

Copy link

jbirley commented Apr 9, 2019

This is great work! Have you considered using something like $PSversiontable or Get-Host to check if you are running a Windows version of Powershell to ensure that the battery region will function correctly? I tested on PowerShell Core version 6.2 and needed to pull that region out. Also, I think Get-WMIObject is deprecated in lieu of the CIM cmdlets.

@fatherjack

This comment has been minimized.

Copy link
Owner Author

fatherjack commented Apr 10, 2019

@jbirley Hi, Thanks, glad it's of interest to you. 😄

Yes, someone else mentioned the Get-WMIObject vs Get-CIMOBject idea so I have re-written it - take a look and see if it suits you now ..J

@fatherjack

This comment has been minimized.

Copy link
Owner Author

fatherjack commented Apr 10, 2019

As per above comment - now re-written to be pwsh compliant by replacing Get-WMIObject with Get-CIMObject

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.