Developer tooling on Windows: A cleaner PowerShell profile
I originally published this post in french on 42 lignes à l'heure
If you've been talking code with me, there's a chance PowerShell came to the table at some point. Before PowerShell was introduced in 2006, developers on Windows who wanted to take a shot at the command line would have to deal with good old BATCH (cmd.exe). Sure, one can manage to get some things done with it and somehow cope with all its awkward bits, but the fact is that BATCH is far from being a great tool.
Enters PowerShell, that takes us much further by solving several pain points that make developers' life miserable in BATCH. One of them is the lack of native support for profile scripts. That is what this post is about.
This quick guide suggests a simple way to create a reusable, structured and evolutive PowerShell profile.
Create a Git repository for our scripts
This is the obvious way to store profile scripts. I personnaly chose GitHub, but a number of options exist out there. Gitlab and Bitbucket both offer free private repositories, if that matters to you.
Repository structure
powershell-dev-environment/
├── src/
│ ├── profile.ps1
│ ├── _imports.ps1
│ ├── _prompt.ps1
│ └── _ui.ps1
└── install.ps1
The entry point
The file profile.ps1
is the entry point of our profile.
# profile.ps1
$env:devProfileDir = $PSScriptRoot
. "$env:devProfileDir\_imports.ps1";
. "$env:devProfileDir\_ui.ps1";
. "$env:devProfileDir\_prompt.ps1";
Note that we define $env:devProfileDir
, an environment variable that will store the location of our scripts. It may be of use.
The file _imports.ps1
is used to load all third-party modules that we want to have available in our PowerShell sessions.
# _imports.ps1
Import-Module posh-git
# an so on...
CAREFUL HERE, some modules can take a lot o time to load (yep, I'm totally looking at you Carbon), so be selective on what you choose to include in this file.
Colors
Terminal display colors are configured in _ui.ps1
# _ui.ps1
$console = $host.UI.RawUI
$console.ForegroundColor = "white"
$console.BackgroundColor = "black"
$colors = $host.PrivateData
$colors.VerboseForegroundColor = "white"
$colors.VerboseBackgroundColor = "blue"
$colors.WarningForegroundColor = "yellow"
$colors.WarningBackgroundColor = "darkgreen"
$colors.ErrorForegroundColor = "white"
$colors.ErrorBackgroundColor = "red"
Clear-Host
Prompt function
The Prompt function is a special, kind of "reserved" PowerShell function. It is executed to render the command line prompt. Once you define it in your profile, you have total control over how your prompt will look. Here's mine:
# _prompt.ps1
function Prompt {
$realLASTEXITCODE = $LASTEXITCODE
$Host.UI.RawUI.ForegroundColor = $GitPromptSettings.DefaultForegroundColor
Write-Host
Write-Host "$ENV:USERNAME@" -NoNewline -ForegroundColor DarkYellow
Write-Host "$ENV:COMPUTERNAME" -ForegroundColor Magenta -NoNewline
Write-Host (Get-Date -Format " | MM/dd/yyyy | HH:MM:ss") -ForegroundColor DarkGray
Write-Host $($(Get-Location) -replace ($env:USERPROFILE).Replace('\','\\'), "~") -NoNewline -ForegroundColor Gray
Write-VcsStatus
Write-Host
$global:LASTEXITCODE = $realLASTEXITCODE
return ""
}
Here's how it looks in the terminal :
Execute profile scripts on PowerShell session startup
If you're like me, you like to have all your repositories in the same place. So the path of your newly created repostory might be something like c:\users\me\dev\powershell-dev-environment
, and you probably want to keep it this way.
There is a built-in $profile
variable that stores the path of the current user's PowerShell profile. It typically points to something like C:\Users\Me\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
. When this file exists, Powershel will automatically execute it on each new session.
Problem is we can't change that path. Our only option is to call our profile directly from there. We just have to tap into this file by adding the following line that calls our script:
. "c:\users\me\dev\powershell-dev-environment\src\profile.ps1"
Because we're all so lazy : a little install script
The previous step can easily be automated with the following bits:
# install.ps1
$installedHint = "#https://github.com/thatfrankdev/powershell-dev-environment"
$installed = $false
if(-not (Test-Path $profile)){
New-Item $profile
}
else{
$installed = (Select-String -Path $profile -pattern $installedHint | Measure-Object).Count -gt 0
}
if(-not $installed){
Add-Content $profile ""
Add-Content $profile ". `"$PSScriptRoot\src\profile.ps1`" $installedHint"
powershell.exe
}
The next step
We now have versatile base structure to build on. That's just a start...
In a next post, I will explore some handy helper functions that can greatly improve your daily flow.
Thanks for reading, hope you enjoyed it :)
English is my second language, so please tell me if you spot a typo, a grammar error or anything that could make this post hard to read. I'm constantly trying to get better at it.
Top comments (0)