Set up a reusable Powershell environment for all your Windows machines
Tired of manually copying your favorite PowerShell aliases and functions to every new machine? I solved the sync problem! I show you how to set up your $profile to pull configurations from a centralized Git repository. I'll organize a setup into neat aliases.ps1, functions.ps1, and prompt.ps1 files.
Set up a Git Repo
Create or login to github.com, go to Repositories and create your GitHub repo. In this example, we'll create a repo called powershell.
On your machine, create a Repos directory in your home folder and change directory to that path. If you want to use another filename or location for your Repos dir, change to that path.
mkdir ~/Repos; cd ~/Repos;
Inside your Repos directory, git clone the powershell repo you made on GitHub.
git clone https://github.com/<username>/powershell.git
Set up environment variables
Go to Control Panel > System.
Go to Advanced System Settings.
Go to Environment Variables.
Add a new variable REPOS_DIR and set the location of the Repos directory.
Add a new variable POWERSHELL_UTILS_DIR and set the location of the powershell repo directory.
Set up profile.ps1
Run echo $profile to see where your Powershell profile is defined.
Open your favorite text editor (Sublime Text Editor, Atom, Notepad …) and add the following lines:
$init = [string]::join([environment]::newline, (get-content -path $env:POWERSHELL_UTILS_DIR\init.ps1))
invoke-expression $init
$OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
These lines reference init.ps1, we will create inside the powershell repo. This is the only setup step you have to repeat on all your machines.
You can set different locations for your Repos directory on each machine. The reusability of POWERSHELL_UTILS_DIR and REPOS_DIR is practical because you may want to set aliases to files or scripts inside your "powershell" repo. They will work on each machine, if you reuse $env: POWERSHELL_UTILS_DIR or $env:REPOS_DIR in your aliases or functions.
Set up Powershell configurations & functions
Inside init.ps1, add a loop to load all files with Powershell customizations (files ending in .ps1) in both the base directory and the functions subdirectory, e.g.
$baseDir = $env: POWERSHELL_UTILS_DIR
$targetFolders = @(
"$baseDir",
"$baseDir\functions"
)
foreach ($folder in $targetFolders) {
if (Test-Path $folder) {
$files = Get-ChildItem -Path $folder -Filter *.ps1 -File
foreach ($file in $files) {
if ($file.FullName -ne $PSCommandPath) {
. $file.FullName
}
}
}
}
Inside aliases.ps1 inside the base directory, add useful aliases you want to reuse on every machine, e.g.
Set-Alias -Name cat -Value Get-Content -Option AllScope
Set-Alias -Name clr -Value clear
Set-Alias -Name echo -Value Write-Output -Option AllScope
Set-Alias -Name grep -Value findstr -Option AllScope
Inside a functions.ps1 inside the functions subdirectory, add useful functions you want to reuse on every machine, e.g.
function Restart-Powershell { & $profile }
Inside prompt.ps1 inside the base directory, customize your command prompt, e.g.
# Prompt format
function prompt {
Write-Host ""
# PS
Write-Host "PS " -NoNewline -ForegroundColor "white" -BackgroundColor "black"
# Working Directory
$path ="$($executionContext.SessionState.Path.CurrentLocation) "
Write-Host $path -NoNewline -ForegroundColor "blue" -BackgroundColor "black"
#Git branch
if (Test-Path .git) {
try {
$branch = git rev-parse --abbrev-ref HEAD
Write-Host "($branch) " -NoNewline -ForegroundColor "cyan" -BackgroundColor "black"
} catch { }
}
# Prompt
$userPrompt = ">"
Write-Host $userPrompt -NoNewline -ForegroundColor "white"
return " "
}
Set up a cleanup function that can be executed on each machine
Create a Function inside utils.ps1 inside the functions subdirectory:
function Remove-Clutter {
$targets = @(
"$env:USERPROFILE\Downloads\",
"$env:USERPROFILE\OneDrive\OneDrive - Federal Public Service - Finance\Afbeeldingen"
)
$shell = New-Object -ComObject Shell.Application
foreach ($target in $targets) {
if (Test-Path $target) {
Write-Host "Cleaning files at $target" -ForegroundColor Yellow
Get-ChildItem -Path $target -File -Recurse | ForEach-Object {
Write-Host "Cleaning file $($_.FullName)"
$item = $shell.Namespace(0).ParseName($_.FullName)
$item.InvokeVerb("delete")
}
}
}
}
In this example, we set an array of general file paths that need to be cleaned. Then, we iterate over the array and recursively remove all the files and directories nested under that file path. Notice the * after each file path, which makes sure only the children of that directory are deleted.





Top comments (0)