A modern, cross-platform PowerShell profile with auto-loading utility functions for network testing, system administration, and developer workflows.
Show-ProfileFunctionsoutput in Windows Terminal with custom prompt and color scheme.
Invoke-NetworkDiagnostic performing network diagnostics with visual graphs.
- Cross-platform compatibility - Works on Windows, macOS, and Linux
- Auto-loading functions - All functions in the
Functionsdirectory are auto-loaded with your profile - Local functions support - Add your own functions to
Functions/Local - Custom prompt - Clean, colored PowerShell prompt
- Install
- Troubleshooting
- Update
- Quick Start
- Local Functions
- Remote Sessions
- Functions
- Using Functions Standalone
- Contributing
- Author
- License
Use the provided install.ps1 script to automate backups (during install), preserve your existing Functions/Local, Help, Modules, PSReadLine, and Scripts directories, and deploy the latest profile files. The script works on PowerShell Desktop 5.1 and PowerShell Core 6+.
Note
Git is optional: If Git is available, the script clones the repository. Otherwise, it automatically downloads and extracts the repository as a zip file from GitHub.
The script is downloaded and piped directly into PowerShell. If you prefer to inspect it first, download it to disk and run it via
-File.
irm 'https://raw.githubusercontent.com/jonlabelle/pwsh-profile/main/install.ps1' |
pwsh -NoProfile -ExecutionPolicy Bypass -irm 'https://raw.githubusercontent.com/jonlabelle/pwsh-profile/main/install.ps1' |
powershell -NoProfile -ExecutionPolicy Bypass -Run install.ps1 Locally
If you already cloned this repository (or downloaded install.ps1), run it from the repo root:
pwsh -NoProfile -ExecutionPolicy Bypass -File ./install.ps1Optional Install Parameters
-SkipBackup— Install without creating a backup of your current profile directory. Only applies to install, not restore.-BackupPath <path>— When restoring, save a backup of your current profile before restoring from the backup. By default, restore does not create a backup.-SkipPreserveDirectories— Do not restore theFunctions/Local,Help,Modules,PSReadLine, andScriptsdirectories after installation.-PreserveDirectories @('Dir1','Dir2')— Only restore the directories you specify.-LocalSourcePath <path>— Copy profile files from a local directory instead of cloning from Git.-ProfileRoot <path>— Use a custom profile directory instead of the default.
For more examples, see the install.ps1 script documentation.
Restore from a Backup
You can restore your profile from a previous backup created by the install script. When you restore, the script does not create a new backup of your current profile unless you ask for one.
Restore from a backup (no new backup is made):
irm 'https://raw.githubusercontent.com/jonlabelle/pwsh-profile/main/install.ps1' |
pwsh -NoProfile -ExecutionPolicy Bypass - -RestorePath 'C:\Users\you\Documents\WindowsPowerShell-backup-20251116-110000'Restore and save a backup of your current profile before restoring:
irm 'https://raw.githubusercontent.com/jonlabelle/pwsh-profile/main/install.ps1' |
pwsh -NoProfile -ExecutionPolicy Bypass - -RestorePath 'C:\Users\you\Documents\WindowsPowerShell-backup-20251116-110000' -BackupPath 'C:\Users\you\Documents\WindowsPowerShell-backup-pre-restore'Manual Install (fallback)
Strongly Recommended: Use install.ps1 instead of manually cloning the repository. The install script provides automatic backups, preserves your local directories (
Help,Modules,PSReadLine,Scripts), and includes easy restoration capabilities that manual installation does not.
If you still prefer to install manually, you can clone this repository directly into your profile directory:
# Resolve profile directory
$profileDir = Split-Path -Path $PROFILE -Parent
# Backup existing profile directory
if (Test-Path -Path $profileDir) {
$backupPath = "$profileDir-backup-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
Move-Item -Path $profileDir -Destination $backupPath
Write-Host "Existing profile backed up to: $backupPath" -ForegroundColor Yellow
}
# Clone the repository into the profile directory
git clone 'https://github.com/jonlabelle/pwsh-profile.git' --depth 1 $profileDirTo restore from a manual backup:
# Remove the new installation
Remove-Item -Path $profileDir -Recurse -Force
# Restore from backup (replace the timestamp with your actual backup)
Move-Item -Path "$profileDir-backup-20250118-120000" -Destination $profileDirRecommended: Use install.ps1 with the -RestorePath parameter for safe restoration. If you want to keep a copy of your current profile before restoring, add the -BackupPath option.
Execution Policy Error (Windows Only)
Note: Execution policies are only enforced on Windows. macOS and Linux systems do not enforce execution policies and will not encounter this error.
If you encounter an error like this when PowerShell starts on Windows:
Microsoft.PowerShell_profile.ps1 cannot be loaded because running
scripts is disabled on this system.
For more information, see about_Execution_Policies at
https:/go.microsoft.com/fwlink/?LinkID=135170.This means your system's execution policy is preventing the profile from loading. To fix this, open a PowerShell window (no administrator privileges required) and execute:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserThis sets the execution policy for your user account only, allowing locally created scripts to run while still requiring downloaded scripts to be signed. No administrator privileges are required for the CurrentUser scope.
Alternative (requires administrator privileges): To set the execution policy for all users on the computer, run PowerShell as Administrator and execute:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachineNote: The CurrentUser scope takes precedence over LocalMachine, so setting it for your user is usually sufficient.
Verification: After setting the execution policy, restart PowerShell. Your profile should load without errors.
For more information about execution policies, see about_Execution_Policies.
Enable Verbose Logging for Troubleshooting
If you're experiencing issues with the profile loading or want to see which functions are being loaded, you can enable verbose logging. Since the profile immediately starts loading functions when it runs, you need to set the verbose preference before PowerShell loads the profile.
Launch PowerShell with the -Verbose parameter (not available in all PowerShell hosts):
# PowerShell Core (pwsh)
pwsh -NoLogo -Command "`$VerbosePreference = 'Continue'; . `$PROFILE"
# Windows PowerShell Desktop (powershell)
powershell -NoLogo -Command "`$VerbosePreference = 'Continue'; . `$PROFILE"Start PowerShell with -NoProfile, then manually set the verbose preference and load the profile:
# Start without profile
pwsh -NoProfile
# Enable verbose output
$VerbosePreference = 'Continue'
# Manually load the profile
. $PROFILE
# Reset verbose preference when done (optional)
$VerbosePreference = 'SilentlyContinue'When verbose logging is enabled, you'll see output like:
VERBOSE: Loading function: /Users/username/.config/powershell/Functions/Developer/Get-DotNetVersion.ps1
VERBOSE: Loading function: /Users/username/.config/powershell/Functions/Developer/Import-DotEnv.ps1
VERBOSE: Creating 'dotenv' alias for Import-DotEnv
VERBOSE: Loading function: /Users/username/.config/powershell/Functions/Developer/Remove-DotNetBuildArtifacts.ps1
VERBOSE: Loading function: /Users/username/.config/powershell/Functions/Security/ConvertFrom-JwtToken.ps1
...
VERBOSE: User profile loaded:
VERBOSE: /Users/username/.config/powershell/Microsoft.PowerShell_profile.ps1This shows each function file being dot-sourced, which is helpful for:
- Identifying which function file is causing errors
- Verifying all functions are being loaded
- Debugging function loading order issues
- Confirming the profile path and location
All functions in this profile include their own verbose logging. After the profile loads, you can use the -Verbose parameter on individual functions:
# See verbose output from a specific function
Get-WhichCommand git -Verbose
Test-Port localhost -Port 80 -VerboseTo pull in the latest updates from the repository:
Update-ProfileYou can check for available updates without applying them:
Test-ProfileUpdateAfter installation, try these commands to explore what the profile offers:
# View all available functions
Show-ProfileFunctions
# Test network connectivity to a host and port
Test-Port bing.com -Port 443
# Get your public IP with geolocation
Get-IPAddress -Public
# Check DNS resolution
Test-DnsNameResolution github.com
# Get SSL certificate expiration
Get-CertificateExpiration github.comOr dig deeper with a more complex example:
# Perform comprehensive network diagnostics on multiple hosts
PS > Invoke-NetworkDiagnostic 'bing.com', 'microsoft.com'
┌─ bing.com:443 (collect 2584.9ms)
│ Latency: ▂▂▃▄▄▅▆▅▆▅▄▄▇▅▇▇█▅▅▁
│ Stats : min: 27.35ms | max: 36.26ms | avg: 32.1ms | jitter: 2ms | samples: 20
│ Quality: 20/20 successful (100%) | Packet Loss: 0%
│ Findings: Healthy
└───────────────────────────────────────────────────────────────────────────────
┌─ microsoft.com:443 (collect 2586ms)
│ Latency: ▁▁▂▄▄▅▆▄▇▄▄▃▇▆███▅▆▁
│ Stats : min: 28.68ms | max: 35ms | avg: 32.08ms | jitter: 2ms | samples: 20
│ Quality: 20/20 successful (100%) | Packet Loss: 0%
│ Findings: Healthy
└───────────────────────────────────────────────────────────────────────────────Explore the full list of functions in the Functions section below.
The Functions/Local directory is available for your machine-local functions that you don't want to commit to the repository. This is perfect for:
- Work-specific utilities
- Personal helper functions
- Experimental functions you're testing
- Machine-specific automations
Any PowerShell file placed in Functions/Local will be automatically loaded, just like the built-in functions. The entire directory is git-ignored, so your local functions are never accidentally committed and remain completely untouched when you run Update-Profile to pull the latest changes.
See the local functions README for detailed instructions, templates, and examples.
PowerShell profiles don't load automatically in remote sessions—click to see how to load them
PowerShell profiles don't load automatically in remote sessions (via Enter-PSSession, New-PSSession, or Invoke-Command). This behavior is consistent across all platforms—Windows, macOS, and Linux—whether you're using WinRM (Windows-only) or SSH-based remoting (cross-platform).
Note: SSH-based remoting requires PowerShell 6+ and SSH to be installed on both local and remote computers. For setup instructions, see PowerShell remoting over SSH.
To use your profile functions in a remote session, you have two options:
Use Invoke-Command to run your local profile script on the remote computer:
$session = New-PSSession -HostName RemoteHost -UserName YourUser
Invoke-Command -Session $session -FilePath $PROFILEDot-source the profile on the remote computer using its explicit path:
$session = New-PSSession -HostName RemoteHost -UserName YourUser
Invoke-Command -Session $session -ScriptBlock {
. "$HOME/.config/powershell/Microsoft.PowerShell_profile.ps1"
}After running either command, the profile's functions and aliases will be available in $session.
For example, to use a profile function in the remote session:
# Use a function from the loaded profile
Invoke-Command -Session $session -ScriptBlock { Test-Port -ComputerName bing.com -Port 443 }
# Or enter the session interactively
Enter-PSSession $session
# Now you can use profile functions directly
Test-DnsNameResolution example.com
Exit-PSSessionNote: For Windows PowerShell Desktop 5.1, replace
.config/powershellwithDocuments\WindowsPowerShellin the path.
For more information, see Microsoft's documentation on Profiles and Remote Sessions.
The profile includes utility functions organized by category:
Get-CertificateExpiration— Gets SSL/TLS certificate expiration dates from remote hostsGet-CertificateDetails— Retrieves detailed SSL/TLS certificate information from remote hostsGet-DnsRecord— Retrieves DNS records for any record type using DNS-over-HTTPSGet-IPAddress— Gets local network interface IPs or public IP address with geolocation dataGet-IPSubnet— Calculates IP subnet information including network/broadcast addressesGet-NetworkMetrics— Collects comprehensive network performance metricsGet-Whois— Performs WHOIS lookups for domain names with registration details and nameserversInvoke-NetworkDiagnostic— Performs network diagnostics with visual graphsInvoke-Ping— Sends ICMP echo requests with detailed statistics (cross-platform ping alternative)Resolve-GeoIP— Resolves IP addresses to geographic locationsSend-TcpRequest— Sends TCP requests and retrieves responses for network testingShow-NetworkLatencyGraph— Displays visualization graphs of network latencyTest-Bandwidth— Tests network bandwidth with download speed and latency measurementsTest-DnsNameResolution— Tests DNS name resolution using cross-platform .NET methodsTest-HttpResponse— Tests HTTP/HTTPS endpoints and returns response detailsTest-Port— Tests TCP/UDP port connectivity with detailed connection informationTest-TlsProtocol— Tests which TLS protocols (1.0, 1.1, 1.2, 1.3) are supported by remote servers
Invoke-ElevatedCommand— Executes commands with elevated privileges (Run as Administrator)Set-TlsSecurityProtocol— Configures TLS security protocol settings for secure network connectionsStart-KeepAlive— Prevents the system and display from sleepingTest-Admin— Checks if the current PowerShell session is running as administrator/root/sudoTest-PendingReboot— Checks if the system has pending reboot requirementsGet-SystemInfo— Gets system information from local or remote computers
Get-DotNetVersion— Retrieves installed .NET Framework and .NET Core versionsImport-DotEnv— Loads environment variables from dotenv (.env) filesRemove-DotNetBuildArtifacts— Cleans up .NET build artifacts from a project directoryRemove-GitIgnoredFiles— Removes ignored and optionally untracked files from Git repositoriesRemove-NodeModules— Removes node_modules folders from Node.js project directoriesRemove-DockerArtifacts— Prunes unused Docker images/networks/cache/containers/volumes
ConvertFrom-JwtToken— Decodes a JWT (JSON Web Token) and returns its header and payloadProtect-PathWithPassword— Encrypts files or folders with AES-256 encryption using a passwordUnprotect-PathWithPassword— Decrypts files that were encrypted with Protect-PathWithPassword
Invoke-GroupPolicyUpdate— Forces an immediate Group Policy update on Windows systemsTest-ADCredential— Validates Active Directory user credentialsTest-ADUserLocked— Tests if an Active Directory user account is locked out
Get-OutdatedModules— Checks if any installed PowerShell modules have newer versions availableRemove-OldModules— Removes older versions of installed PowerShell modulesUpdate-AllModules— Updates all PowerShell modules to the latest versions
Show-ProfileFunctions— Shows all functions available in this PowerShell profileTest-ProfileUpdate— Checks for available profile updates from the GitHub repository
Get-MediaInfo— Retrieves comprehensive media file metadata (video and audio) using ffprobeInvoke-FFmpeg— Converts video files using Samsung TV-friendly H.264/H.265 encodingRename-VideoSeasonFile— Batch renames TV show episode files to a consistent format
Convert-LineEndings— Converts line endings between Unix and WindowsConvertFrom-Base64— Decodes Base64-encoded strings or files with URL-safe supportConvertTo-Base64— Encodes strings or files to Base64 with URL-safe supportCopy-Directory— Copies directories recursively while excluding specific directoriesExtract-Archives— Finds all archives (zip, tar, 7z, rar) and extracts themGet-CommandAlias— Displays aliases for PowerShell cmdletsGet-StringHash— Computes hash values for strings (likeGet-FileHashbut for strings)Get-WhichCommand— Locates commands and displays their type or path (cross-platform which alternative)New-RandomString— Generates random strings for passwords, tokens, and other usesRemove-OldFiles— Removes files older than a specified time period with optional empty directory cleanupReplace-StringInFile— Finds and replaces text in files with support for regex and backupsSearch-FileContent— Search files with regex, context, filtering, and colorized outputSync-Directory— Synchronizes directories using native platform tools (rsync/robocopy)Format-Bytes— Formats bytes/bits into human-friendly conversions
Functions can be used without loading the profile by dot-sourcing them directly:
# Load a specific function (any dependencies are auto-loaded)
. '~/.config/powershell/Functions/NetworkAndDns/Test-Port.ps1'
# Use it
Test-Port bing.com -Port 443Functions with dependencies automatically load what they need, so you only need to dot-source the function you want to use.
Contributions are welcome! Please follow these guidelines:
- One function per file in
Functions/{Category}(namedVerb-Noun.ps1) — auto-loaded by the main profile - Include Pester tests for new functions — both unit and integration tests where applicable (see
Tests/README.mdfor test structure and examples) - Open a pull request with a clear description and basic verification steps (linting + functional testing)
- Maintain cross-platform compatibility following the project's conventions (see
./Functionsfor examples)

