Reputation: 12234
Using Windows PowerShell, how do I change the command prompt?
For example, the default prompt says
PS C:\Documents and Settings\govendes\My Documents>
I want to customize that string.
Upvotes: 111
Views: 82943
Reputation: 171
PROMPT in PowerShell
A better way to track the path, while keeping the hostname and logging time/date in every line run:
function prompt {
$dateTime = get-date -Format "dd.MM.yyyy HH:mm:ss"
$currentDirectory = $(Get-Location)
$UncRoot = $currentDirectory.Drive.DisplayRoot
write-host "$dateTime" -NoNewline -ForegroundColor YELLOW
write-host " $UncRoot" -ForegroundColor White
# Convert-Path needed for pure UNC-locations
write-host "$ENV:COMPUTERNAME-PS:$(Convert-Path $currentDirectory)>" -NoNewline -ForegroundColor GREEN
return " "
}
...and you get:
myservername-C:\Users\myusername\Documents\WindowsPowerShell\scripts>
Finally! :)
Upvotes: 1
Reputation: 171
In case someone is looking for a more sophisticated answer, here's my PowerShell v7 prompt that I have developed over the course of a year. To put it into context, it's part of my personal PowerShell profile:
https://github.com/StefanGreve/profile
The easiest way to get a fancy PowerShell prompt up and running is to use established solutions created by the pwsh community, so if you just need something that works with few lines of code to write on your end, you might want to take a look at this project:
https://github.com/dahlbyk/posh-git
However, if you are like me and want to write your own custom prompt from scratch, then the code snippets below might be able to give you some ideas on how to approach this problem.
I will break down the most important pieces here. To start things of, I added the necessary code to determine the current platform we are on (since some bits are OS-specific and I also use this function on Unix-based operating systems):
enum OS
{
Unknown = 0
Windows = 1
Linux = 2
MacOS = 3
}
# I map these booleans to an Enum so that I can switch over them
$global:OperatingSystem = if ([OperatingSystem]::IsWindows()) {
[OS]::Windows
} elseif ([OperatingSystem]::IsLinux()) {
[OS]::Linux
} elseif ([OperatingSystem]::IsMacOS()) {
[OS]::MacOS
} else {
[OS]::Unknown
}
# In the prompt function below this is used to toggle the leading char ('>' or '#') to indicate elevated privilages
if ([OperatingSystem]::IsWindows()) {
$global:IsAdmin = ([Principal.WindowsPrincipal][Principal.WindowsIdentity]::GetCurrent()).IsInRole([Principal.WindowsBuiltInRole]::Administrator)
}
if ([OperatingSystem]::IsLinux()) {
$global:IsAdmin = $(id -u) -eq 0
}
# Required for Python if you want to set the venv indicator in the terminal yourself, else skip this part
$env:VIRTUAL_ENV_DISABLE_PROMPT = 1
# Returns the execution time of the last command you ran, or 0 on init
function Get-ExecutionTime {
$History = Get-History
$ExecTime = $History ? ($History[-1].EndExecutionTime - $History[-1].StartExecutionTime) : (New-TimeSpan)
Write-Output $ExecTime
}
After the build up, we can continue to dive into the actual prompt function:
function prompt {
$ExecTime = Get-ExecutionTime
# Only show the current branch if we are inside a Git repository. Notice that the Git command writes to stderr if we are not inside a Git repository
$Branch = if ($(git rev-parse --is-inside-work-tree 2>&1) -eq $true) {
# If you version of git doesn't support the --show-current flag yet, use this command instead:
# git rev-parse --abbrev-ref HEAD
# It's less readable so I opted for the more modern approach but you may want to use the command above if using the latest versions of programs isn't your thing
[string]::Format(" {0}({1}){2}", $PSStyle.Foreground.Blue, $(git branch --show-current), $PSStyle.Foreground.White)
}
# You can delete this part if you don't use Python, it is used to indicate whether a virtual environment is active
$Venv = if ($env:VIRTUAL_ENV) {
[string]::Format(" {0}({1}){2}", $PSStyle.Foreground.Magenta, [Path]::GetFileName($env:VIRTUAL_ENV), $PSStyle.Foreground.White)
}
$Computer = switch ($global:OperatingSystem) {
([OS]::Windows) {
[PSCustomObject]@{
UserName = $env:USERNAME
HostName = $env:COMPUTERNAME
}
}
([OS]::Linux) {
[PSCustomObject]@{
UserName = $env:USER
HostName = hostname
}
}
([OS]::MacOS) {
# I don't have a Mac so I cannot guarantee that this bit works, but in theory it should do the trick based on what I found online
[PSCustomObject]@{
UserName = id -un
HostName = scutil --get ComputerName
}
}
}
return [System.Collections.ArrayList]@(
"[",
$PSStyle.Foreground.BrightCyan,
$Computer.UserName,
$PSStyle.Foreground.White,
"@",
$Computer.HostName,
" ",
$PSStyle.Foreground.Green,
[DirectoryInfo]::new($ExecutionContext.SessionState.Path.CurrentLocation).BaseName,
$PSStyle.Foreground.White,
"]",
" ",
$PSStyle.Foreground.Yellow,
"(",
$ExecTime.Hours.ToString("D2"),
":",
$ExecTime.Minutes.ToString("D2"),
":",
$ExecTime.Seconds.ToString("D2"),
":",
$ExecTime.Milliseconds.ToString("D3"),
")",
$PSStyle.Foreground.White,
$Branch,
$Venv, # (you may want to remove this line, see remark above)
"`n",
[string]::new($global:IsAdmin ? "#" : ">", $NestedPromptLevel + 1),
" "
) -join ""
}
Upvotes: 4
Reputation: 151
To just show the drive letter I use:
function prompt {(get-location).drive.name+"\...>"}
Then to revert to the path I use:
function prompt {"$pwd>"}
Upvotes: 10
Reputation: 141
At the prompt, I like a current timestamp and resolved drive letters for network drives. To make it more readable, I put it in two lines, and played a bit with colors.
With CMD, I ended up with
PROMPT=$E[33m$D$T$H$H$H$S$E[37m$M$_$E[1m$P$G
For PowerShell, I got the same result with:
function prompt {
$dateTime = get-date -Format "dd.MM.yyyy HH:mm:ss"
$currentDirectory = $(Get-Location)
$UncRoot = $currentDirectory.Drive.DisplayRoot
write-host "$dateTime" -NoNewline -ForegroundColor White
write-host " $UncRoot" -ForegroundColor Gray
# Convert-Path needed for pure UNC-locations
write-host "PS $(Convert-Path $currentDirectory)>" -NoNewline -ForegroundColor Yellow
return " "
}
Which is a little more readable :-)
BTW:
powershell_ise.exe $PROFILE
instead of (dumb) Notepad.Upvotes: 14
Reputation: 1067
Related to a comment to Ocaso Protal's answer, the following is needed for Windows Server 2012 as well as Windows 7 (in a PowerShell window):
new-item -itemtype file -path $profile -force
notepad $PROFILE
I would suggest the following as a prompt if you run with multiple user names (e.g. yourself + a production login):
function Global:prompt {"PS [$Env:username]$PWD`n>"}
(Credit goes to David I. McIntosh for this one.)
Upvotes: 30
Reputation: 20267
Just put the function prompt
in your PowerShell profile (notepad $PROFILE
), e.g.:
function prompt {"PS: $(get-date)>"}
or colored:
function prompt
{
Write-Host ("PS " + $(get-date) +">") -nonewline -foregroundcolor White
return " "
}
Upvotes: 139
Reputation: 521
This version of Warren Stevens' answer avoids the noisy "Microsoft.PowerShell.Core\FileSystem" in the path if you Set-Location
to network shares.
function prompt {"PS [$Env:username@$Env:computername]$($PWD.ProviderPath)`n> "}
Upvotes: 7
Reputation: 994
If you want to do it yourself, then Ocaso Protal's answer is the way to go. But if you're lazy like me and just want something to do it for you, then I highly recommend Luke Sampson's Pshazz package.
Just to show you how lazy you can be, I'll provide a quick tutorial.
scoop install pshazz
)pshazz use msys
)Pshazz also allows you to create your own themes, which is as simple as configuring a JSON file. Check out mine to see how easy it is!
Upvotes: 10