Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 99 additions & 44 deletions Microsoft.PowerShell_profile.ps1
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
### PowerShell Profile Refactor
### Version 1.03 - Refactored
### Version 1.04 - Refactored

$debug = $false

# Define the path to the file that stores the last execution time
$timeFilePath = [Environment]::GetFolderPath("MyDocuments") + "\PowerShell\LastExecutionTime.txt"

# Define the update interval in days, set to -1 to always check
$updateInterval = 7

#################################################################################################################################
############ ############
############ !!! WARNING: !!! ############
Expand Down Expand Up @@ -41,9 +35,6 @@ $updateInterval = 7
############ Set-PredictionSource ############
#################################################################################################################################

### PowerShell Profile Refactor
### Version 1.04 - Refactored

if ($debug_Override){
# If variable debug_Override is defined in profile.ps1 file
# then use it instead
Expand All @@ -61,13 +52,26 @@ if ($repo_root_Override){
$repo_root = "https://raw.githubusercontent.com/ChrisTitusTech"
}

# Helper function for cross-edition compatibility
function Get-ProfileDir {
if ($PSVersionTable.PSEdition -eq "Core") {
return "$env:userprofile\Documents\PowerShell"
} elseif ($PSVersionTable.PSEdition -eq "Desktop") {
return "$env:userprofile\Documents\WindowsPowerShell"
} else {
Write-Error "Unsupported PowerShell edition: $($PSVersionTable.PSEdition)"
return $null
}
}

# Define the path to the file that stores the last execution time
if ($timeFilePath_Override){
# If variable $timeFilePath_Override is defined in profile.ps1 file
# then use it instead
$timeFilePath = $timeFilePath_Override
} else {
$timeFilePath = "$env:USERPROFILE\Documents\PowerShell\LastExecutionTime.txt"
$profileDir = Get-ProfileDir
$timeFilePath = "$profileDir\LastExecutionTime.txt"
}

# Define the update interval in days, set to -1 to always check
Expand Down Expand Up @@ -103,13 +107,24 @@ if ($debug) {
}


#opt-out of telemetry before doing anything, only if PowerShell is run as admin
# Opt-out of telemetry before doing anything, only if PowerShell is run as admin
if ([bool]([System.Security.Principal.WindowsIdentity]::GetCurrent()).IsSystem) {
[System.Environment]::SetEnvironmentVariable('POWERSHELL_TELEMETRY_OPTOUT', 'true', [System.EnvironmentVariableTarget]::Machine)
}

# Initial GitHub.com connectivity check with 1 second timeout
$global:canConnectToGitHub = Test-Connection github.com -Count 1 -Quiet -TimeoutSeconds 1
# Initial GitHub.com connectivity check
function Test-GitHubConnection {
if ($PSVersionTable.PSEdition -eq "Core") {
# If PowerShell Core, use a 1 second timeout
return Test-Connection github.com -Count 1 -Quiet -TimeoutSeconds 1
} else {
# For PowerShell Desktop, use .NET Ping class with timeout
$ping = New-Object System.Net.NetworkInformation.Ping
$result = $ping.Send("github.com", 1000) # 1 second timeout
return ($result.Status -eq "Success")
}
}
$global:canConnectToGitHub = Test-GitHubConnection

# Import Modules and External Profiles
# Ensure Terminal-Icons module is installed before importing
Expand All @@ -127,7 +142,7 @@ function Update-Profile {
# If function "Update-Profile_Override" is defined in profile.ps1 file
# then call it instead.
if (Get-Command -Name "Update-Profile_Override" -ErrorAction SilentlyContinue) {
Update-Profile_Override;
Update-Profile_Override
} else {
try {
$url = "$repo_root/powershell-profile/main/Microsoft.PowerShell_profile.ps1"
Expand Down Expand Up @@ -166,7 +181,7 @@ function Update-PowerShell {
# If function "Update-PowerShell_Override" is defined in profile.ps1 file
# then call it instead.
if (Get-Command -Name "Update-PowerShell_Override" -ErrorAction SilentlyContinue) {
Update-PowerShell_Override;
Update-PowerShell_Override
} else {
try {
Write-Host "Checking for PowerShell updates..." -ForegroundColor Cyan
Expand Down Expand Up @@ -275,6 +290,13 @@ function Edit-Profile {
}
Set-Alias -Name ep -Value Edit-Profile

function Invoke-Profile {
if ($PSVersionTable.PSEdition -eq "Desktop") {
Write-Host "Note: Some Oh My Posh/PSReadLine errors are expected in PowerShell 5. The profile still works fine." -ForegroundColor Yellow
}
& $PROFILE
}

function touch($file) { "" | Out-File $file -Encoding ASCII }
function ff($name) {
Get-ChildItem -recurse -filter "*${name}*" -ErrorAction SilentlyContinue | ForEach-Object {
Expand All @@ -283,21 +305,21 @@ function ff($name) {
}

# Network Utilities
function Get-PubIP { (Invoke-WebRequest http://ifconfig.me/ip).Content }
function pubip { (Invoke-WebRequest http://ifconfig.me/ip).Content }

# Open WinUtil full-release
function winutil {
irm https://christitus.com/win | iex
Invoke-Expression (Invoke-RestMethod https://christitus.com/win)
}

# Open WinUtil dev-release
function winutildev {
# If function "WinUtilDev_Override" is defined in profile.ps1 file
# If function "WinUtilDev_Override" is defined in profile.ps1 file
# then call it instead.
if (Get-Command -Name "WinUtilDev_Override" -ErrorAction SilentlyContinue) {
WinUtilDev_Override
} else {
irm https://christitus.com/windev | iex
Invoke-Expression (Invoke-RestMethod https://christitus.com/windev)
}
}

Expand All @@ -319,7 +341,7 @@ function uptime {
# find date/time format
$dateFormat = [System.Globalization.CultureInfo]::CurrentCulture.DateTimeFormat.ShortDatePattern
$timeFormat = [System.Globalization.CultureInfo]::CurrentCulture.DateTimeFormat.LongTimePattern

# check powershell version
if ($PSVersionTable.PSVersion.Major -eq 5) {
$lastBoot = (Get-WmiObject win32_operatingsystem).LastBootUpTime
Expand All @@ -329,7 +351,7 @@ function uptime {
$lastBoot = $bootTime.ToString("$dateFormat $timeFormat")
} else {
# the Get-Uptime cmdlet was introduced in PowerShell 6.0
$lastBoot = (Get-Uptime -Since).ToString("$dateFormat $timeFormat")
$lastBoot = (Get-Uptime -Since).ToString("$dateFormat $timeFormat")
$bootTime = [System.DateTime]::ParseExact($lastBoot, "$dateFormat $timeFormat", [System.Globalization.CultureInfo]::InvariantCulture)
}

Expand All @@ -354,10 +376,6 @@ function uptime {
}
}

function reload-profile {
& $profile
}

function unzip ($file) {
Write-Output("Extracting", $file, "to", $pwd)
$fullFile = Get-ChildItem -Path $pwd -Filter $file | ForEach-Object { $_.FullName }
Expand All @@ -368,16 +386,16 @@ function hb {
Write-Error "No file path specified."
return
}

$FilePath = $args[0]

if (Test-Path $FilePath) {
$Content = Get-Content $FilePath -Raw
} else {
Write-Error "File path does not exist."
return
}

$uri = "http://bin.christitus.com/documents"
try {
$response = Invoke-RestMethod -Uri $uri -Method Post -Body $Content -ErrorAction Stop
Expand Down Expand Up @@ -468,12 +486,12 @@ function trash($path) {
### Quality of Life Aliases

# Navigation Shortcuts
function docs {
function docs {
$docs = if(([Environment]::GetFolderPath("MyDocuments"))) {([Environment]::GetFolderPath("MyDocuments"))} else {$HOME + "\Documents"}
Set-Location -Path $docs
}
function dtop {

function dtop {
$dtop = if ([Environment]::GetFolderPath("Desktop")) {[Environment]::GetFolderPath("Desktop")} else {$HOME + "\Documents"}
Set-Location -Path $dtop
}
Expand Down Expand Up @@ -524,6 +542,20 @@ function cpy { Set-Clipboard $args[0] }

function pst { Get-Clipboard }

# Set-PSReadLineOption Compatibility for PowerShell Desktop
function Set-PSReadLineOptionsCompat {
param([hashtable]$Options)
if ($PSVersionTable.PSEdition -eq "Core") {
Set-PSReadLineOption @Options
} else {
# Remove unsupported keys for Desktop and silence errors
$SafeOptions = $Options.Clone()
$SafeOptions.Remove('PredictionSource')
$SafeOptions.Remove('PredictionViewStyle')
Set-PSReadLineOption @SafeOptions
}
}

# Enhanced PowerShell Experience
# Enhanced PSReadLine Configuration
$PSReadLineOptions = @{
Expand All @@ -546,7 +578,7 @@ $PSReadLineOptions = @{
PredictionViewStyle = 'ListView'
BellStyle = 'None'
}
Set-PSReadLineOption @PSReadLineOptions
Set-PSReadLineOptionsCompat -Options $PSReadLineOptions

# Custom key handlers
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward
Expand All @@ -568,15 +600,19 @@ Set-PSReadLineOption -AddToHistoryHandler {
return ($null -eq $hasSensitive)
}

# Fix Set-PredictionSource for Desktop
function Set-PredictionSource {
# If function "Set-PredictionSource_Override" is defined in profile.ps1 file
# If "Set-PredictionSource_Override" is defined in profile.ps1 file
# then call it instead.
if (Get-Command -Name "Set-PredictionSource_Override" -ErrorAction SilentlyContinue) {
Set-PredictionSource_Override;
Set-PredictionSource_Override
} elseif ($PSVersionTable.PSEdition -eq "Core") {
# Improved prediction settings
Set-PSReadLineOption -PredictionSource HistoryAndPlugin
Set-PSReadLineOption -MaximumHistoryCount 10000
} else {
# Improved prediction settings
Set-PSReadLineOption -PredictionSource HistoryAndPlugin
Set-PSReadLineOption -MaximumHistoryCount 10000
# Desktop version - use History only
Set-PSReadLineOption -MaximumHistoryCount 10000
}
}
Set-PredictionSource
Expand All @@ -589,7 +625,7 @@ $scriptblock = {
'npm' = @('install', 'start', 'run', 'test', 'build')
'deno' = @('run', 'compile', 'bundle', 'test', 'lint', 'fmt', 'cache', 'info', 'doc', 'upgrade')
}

$command = $commandAst.CommandElements[0].Value
if ($customCompletions.ContainsKey($command)) {
$customCompletions[$command] | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
Expand All @@ -608,10 +644,29 @@ $scriptblock = {
}
Register-ArgumentCompleter -Native -CommandName dotnet -ScriptBlock $scriptblock

if (Get-Command -Name "Get-Theme_Override" -ErrorAction SilentlyContinue){
Get-Theme_Override;
# If function "Get-Theme_Override" is defined in profile.ps1 file
# then call it instead.
if (Get-Command -Name "Get-Theme_Override" -ErrorAction SilentlyContinue) {
Get-Theme_Override
} else {
oh-my-posh init pwsh --config https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/cobalt2.omp.json | Invoke-Expression
# Oh My Posh initialization with local theme fallback and auto-download
$localThemePath = Join-Path (Get-ProfileDir) "cobalt2.omp.json"
if (-not (Test-Path $localThemePath)) {
# Try to download the theme file to the detected local path
$themeUrl = "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/cobalt2.omp.json"
try {
Invoke-RestMethod -Uri $themeUrl -OutFile $localThemePath
Write-Host "Downloaded missing Oh My Posh theme to $localThemePath"
} catch {
Write-Warning "Failed to download theme file. Falling back to remote theme. Error: $_"
}
}
if (Test-Path $localThemePath) {
oh-my-posh init pwsh --config $localThemePath | Invoke-Expression
} else {
# Fallback to remote theme if local file doesn't exist
oh-my-posh init pwsh --config https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/cobalt2.omp.json | Invoke-Expression
}
}

if (Get-Command zoxide -ErrorAction SilentlyContinue) {
Expand All @@ -635,6 +690,7 @@ $($PSStyle.Foreground.Yellow)=======================$($PSStyle.Reset)
$($PSStyle.Foreground.Green)Update-Profile$($PSStyle.Reset) - Checks for profile updates from a remote repository and updates if necessary.
$($PSStyle.Foreground.Green)Update-PowerShell$($PSStyle.Reset) - Checks for the latest PowerShell release and updates if a new version is available.
$($PSStyle.Foreground.Green)Edit-Profile$($PSStyle.Reset) - Opens the current user's profile for editing using the configured editor.
$($PSStyle.Foreground.Green)Invoke-Profile$($PSStyle.Reset) - Runs the current user's profile to reload settings.

$($PSStyle.Foreground.Cyan)Git Shortcuts$($PSStyle.Reset)
$($PSStyle.Foreground.Yellow)=======================$($PSStyle.Reset)
Expand All @@ -656,7 +712,7 @@ $($PSStyle.Foreground.Green)ep$($PSStyle.Reset) - Opens the profile for editing.
$($PSStyle.Foreground.Green)export$($PSStyle.Reset) <name> <value> - Sets an environment variable.
$($PSStyle.Foreground.Green)ff$($PSStyle.Reset) <name> - Finds files recursively with the specified name.
$($PSStyle.Foreground.Green)flushdns$($PSStyle.Reset) - Clears the DNS cache.
$($PSStyle.Foreground.Green)Get-PubIP$($PSStyle.Reset) - Retrieves the public IP address of the machine.
$($PSStyle.Foreground.Green)pubip$($PSStyle.Reset) - Retrieves the public IP address of the machine.
$($PSStyle.Foreground.Green)grep$($PSStyle.Reset) <regex> [dir] - Searches for a regex pattern in files within the specified directory or from the pipeline input.
$($PSStyle.Foreground.Green)hb$($PSStyle.Reset) <file> - Uploads the specified file's content to a hastebin-like service and returns the URL.
$($PSStyle.Foreground.Green)head$($PSStyle.Reset) <path> [n] - Displays the first n lines of a file (default 10).
Expand All @@ -679,7 +735,6 @@ $($PSStyle.Foreground.Green)sysinfo$($PSStyle.Reset) - Displays detailed system
$($PSStyle.Foreground.Green)flushdns$($PSStyle.Reset) - Clears the DNS cache.
$($PSStyle.Foreground.Green)cpy$($PSStyle.Reset) <text> - Copies the specified text to the clipboard.
$($PSStyle.Foreground.Green)pst$($PSStyle.Reset) - Retrieves text from the clipboard.
$($PSStyle.Foreground.Green)reload-profile$($PSStyle.Reset) - Reloads the current user's PowerShell profile.
$($PSStyle.Foreground.Green)sed$($PSStyle.Reset) <file> <find> <replace> - Replaces text in a file.
$($PSStyle.Foreground.Green)sysinfo$($PSStyle.Reset) - Displays detailed system information.
$($PSStyle.Foreground.Green)tail$($PSStyle.Reset) <path> [n] - Displays the last n lines of a file (default 10).
Expand Down
Loading