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 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 billkindle commented Jul 13, 2018

Very nice!

@Amir-Mir

This comment has been minimized.

Copy link

@Amir-Mir Amir-Mir 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 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 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 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 fatherjack commented Mar 16, 2019

code tidy up and regions added

@fatherjack

This comment has been minimized.

Copy link
Owner Author

@fatherjack 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 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 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 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