I'm in love with PowerShell. It's the perfect blend of feature-richness and readability in scripting (power) and laconism in the command line (shell). But a rant on the cross-platform open-source awesomeness of PowerShell is best saved for another article (which I've already written and which you must read if you want your life to have meant something).
Once you've accepted PowerShell into your heart and onto your laptop, the tips in this article can help you tweak PowerShell just the way you like, for hours upon hours of PowerShelling delight.
Configuring startup settings
Bash users will be familiar with the .bashrc
or .bash_profile
file, which contains commands that run each time a shell instance starts up. PowerShell has a similar file, though its location is system-specific. The full path of that file is available in the $profile
variable in PowerShell. If you wish to make use of any or all of the tweaks described below, simply place them into this file.
Ding-dong, the ding is dead
If you run PowerShell on Windows (don't worry, we won't judge), you might run into a small auditory nuisance: if you press Backspace in an empty prompt, you may hear an annoying bell-type sound. You can turn it off with this command:
Set-PSReadlineOption -BellStyle None
Take a tab at Windows
Tab completion is one of PowerShell's most amazing features. When you type a portion of a cmdlet or a parameter on Linux or MacOS and then press Tab, PowerShell will show you all the possible completions of the cmdlet or parameter you typed. You can even type just the name of a cmdlet followed by a hyphen, then press Tab to see all the parameters quickly:
PS /home/yevster/Documents/ArticlesInProgress> Get-Command -
Name ArgumentList InformationAction
Verb All ErrorVariable
Noun ListImported WarningVariable
Module ParameterName InformationVariable
FullyQualifiedModule ParameterType OutVariable
CommandType Verbose OutBuffer
TotalCount Debug PipelineVariable
Syntax ErrorAction
ShowCommandInfo WarningAction
Unfortunately, the default behavior on Windows is different. When you type a part of a cmdlet or a parameter on Windows, PowerShell will provide just the first available completion. You can then press Tab again (and again and again) to cycle through the other completions. Yuck!
Fortunately, fixing this abomination takes much less time than describing it did. Just add this line to your $profile
:
Set-PSReadlineOption -EditMode Emacs
The blight on white
If you have configured your terminal to use black text on a white background, you may run into ugliness when using PowerShell:
Although PowerShell inherits the parent terminal's colors for background and foreground, it independently colorizes specific tokens on the command line. For example, by default object members and numbers are colored white, which makes them hard to see on a white background.
Fortunately, this problem is easy to fix by sticking this little gem into your $profile
:
$colorScheme = @{
None = "Black";
Comment = "DarkMagenta";
Keyword = "DarkGreen";
String = "DarkBlue";
Operator = "DarkRed";
Variable = "DarkGreen";
Command = "DarkRed";
Parameter = "DarkGreen";
Type = "DarkGray";
Number = "DarkGray";
Member = "DarkGray";
}
$colorScheme.Keys | % { Set-PSReadlineOption -TokenKind $_ -ForegroundColor $colorScheme[$_] }
Feel free to tweak the $colorScheme
map above to your liking (as if you need my permission). You can see all the available color options by typing [ConsoleColor].GetEnumNames()
.
Make it prompt
You can customize the PowerShell prompt to display whatever you want: the time, your username, insults about your coworkers. To customize the prompt, all you need to do is define a function named prompt
. The string that this function returns will be your PowerShell prompt.
Here's how my prompt normally looks:
07:10PM /home/yevster>
I say "normally" because I added a nifty little tweak: When a command (or a cmdlet) exits with an error status, I've rigged PowerShell to let me know:
Seeing the return status can be helpful when, as in the example above, messages written to standard error are balefully suppressed.
Here's how I configured my PowerShell prompt in my $profile (and so can you)
:
function prompt {
$lastResult = Invoke-Expression '$?'
if (!$lastResult) {
Write-Host "Last command exited with error status." -ForegroundColor Red
}
Write-Output "${msg}$(
# Show time as 12:05PM
Get-Date -UFormat "%I:%M%p"
# Show current directory
) $(Get-Location)> "
}
The key is in the chords
PowerShell offers oodles of ways to minimize typing. Tab completion is one. Aliases are another. Here's one more: You can configure PowerShell to execute a specific script block in response to a key combination (chord) of your choice.
Let's imagine I am a social media addict and want to make it easy to check Facebook compulsively. I would add this line to my $profile
:
Set-PSReadlineKeyHandler -Chord Ctrl+F -ScriptBlock { google-chrome https://www.facebook.com }
It's up to you to ensure the chord you specify isn't already used by your terminal application. If it is, the key combination may not get relayed to PowerShell.
Here's a more productive use of the chord binding functionality: Committing changes to Git and pushing them to the remote repository origin
with one swift key combo:
Set-PSReadlineKeyHandler -Chord Ctrl+G -ScriptBlock {
$message = Read-Host "Please enter a commit message"
/usr/bin/git commit -m "$message" | Write-Host
$branch = (/usr/bin/git rev-parse --abbrev-ref HEAD)
Write-Host "Pushing ${branch} to remote"
/usr/bin/git push origin $branch | Write-Host
}
Note: Standard output of any command launched via a key chord will not be displayed in the terminal. If you do want to see output from a command in the terminal, pipe it to the Write-Host
CMDlet, as I did in the example above.
All's well that ends
Since you have braved my heinous puns to get this far, I hope you have in the process made your PowerShell even more enjoyable to use. If you have any favorite hacks that I've missed, I'd love to see them. Please comment and/or tweet me.
Happy PowerShelling!
9 Comments