diff --git a/PSProfile/PSProfile.Aliases.ps1 b/PSProfile/PSProfile.Aliases.ps1 new file mode 100644 index 0000000..4a4a643 --- /dev/null +++ b/PSProfile/PSProfile.Aliases.ps1 @@ -0,0 +1,7 @@ +Set-Alias -Name 'Desktop' -Value 'Set-LocationDesktop' +Set-Alias -Name 'Downloads' -Value 'Set-LocationDownloads' +Set-Alias -Name 'Documents' -Value 'Set-LocationDocuments' +Set-Alias -Name 'Pictures' -Value 'Set-LocationPictures' +Set-Alias -Name 'Music' -Value 'Set-LocationMusic' +Set-Alias -Name 'Videos' -Value 'Set-LocationVideos' +Set-Alias -Name 'DevDrive' -Value 'Set-LocationDevDrive' diff --git a/PSProfile/PSProfile.Functions.ps1 b/PSProfile/PSProfile.Functions.ps1 new file mode 100644 index 0000000..79f7621 --- /dev/null +++ b/PSProfile/PSProfile.Functions.ps1 @@ -0,0 +1,269 @@ +# --------------------------------------------------------------------- +# PowerShell Profile - Custom Functions +# --------------------------------------------------------------------- + +Function Update-Environment { + Refresh-Profile + Refresh-Path + Refresh-Module + Refresh-Function + Refresh-Alias + Refresh-Variable + +} +Function Invoke-ProfileReload { + & $PROFILE +} + +Function Get-PublicIP { + (Invoke-WebRequest 'http://ifconfig.me/ip' ).Content +} + +Function Get-Timestamp { + Get-Date -Format u +} + +Function Get-RandomPassword { + $length = 16 + $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+' + -join ((0..$length) | ForEach-Object { $chars[(Get-Random -Maximum $chars.Length)] }) +} + +Function Update-WinGet { + Params( + [Switch]$Admin, + [Switch]$Interactive + ) + + if (Get-PSResource -Name WingetTools -ErrorAction SilentlyContinue) { + Import-Module WingetTools + } else { + Install-Module WingetTools -Force -SkipPublisherCheck + } + + if ($Admin) { + } else { + winget upgrade --all + } +} +Function Update-Chocolatey {} +Function Update-Scoop {} +Function Update-R {} +Function Update-Python {} + +Function Update-Node {} + +Function Update-Pip {} +Function Update-Windows {} + +Function Mount-DevDrive { + if (-not(Test-Path -Path 'X:\')) { + + if (Get-PSDrive -Name 'Dev' -ErrorAction SilentlyContinue) { + Write-Host 'Mapped PSDrive for DevDrive already exists. Aborting Mounting...' -ForegroundColor Yellow + Return + } else { + + $cmd = "sudo powershell.exe -Command 'Mount-VHD -Path I:\DevDrive\DevDrive.vhdx'" + + try { + Write-Verbose 'Mounting DevDrive...' + Invoke-Expression -Command $cmd + } catch { + Write-Warning 'Failed to mount DevDrive...' + } + + Write-Verbose 'Creating DevDrive PSDrive...' + New-PSDrive -Name 'Dev' -PSProvider FileSystem -Root 'X:\' -Scope Global + } + } +} + +Function Set-LocationDesktop { + Set-Location -Path "$env:USERPROFILE\Desktop" +} + +Function Set-LocationDownloads { + Set-Location -Path "$env:USERPROFILE\Downloads" +} + +Function Set-LocationDocuments { + Set-Location -Path "$env:USERPROFILE\Documents" +} + +Function Set-LocationPictures { + Set-Location -Path "$env:USERPROFILE\Pictures" +} + +Function Set-LocationMusic { + Set-Location -Path "$env:USERPROFILE\Music" +} + +Function Set-LocationVideos { + Set-Location -Path "$env:USERPROFILE\Videos" +} + +Function Set-LocationDevDrive { + Set-Location -Path 'Dev:' +} + +Function cd... { + Set-Location -Path '..\..' +} + +Function cd.... { + Set-Location -Path '..\..\..' +} + +Function Get-MD5Hash { Get-FileHash -Algorithm MD5 $args } + +Function Get-SHA1Hash { Get-FileHash -Algorithm SHA1 $args } + +Function Get-SHA256Hash { Get-FileHash -Algorithm SHA256 $args } + +Function Invoke-Notepad { notepad.exe $args } + + +# Drive shortcuts +function HKLM: { Set-Location HKLM: } +function HKCU: { Set-Location HKCU: } +function Env: { Set-Location Env: } + +if (Test-Path HKCU:\SOFTWARE\Microsoft\OneDrive) { + $onedrive = Get-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\OneDrive + if (Test-Path $onedrive.UserFolder) { + New-PSDrive -Name OneDrive -PSProvider FileSystem -Root $onedrive.UserFolder -Description 'OneDrive' + function OneDrive: { Set-Location OneDrive: } + } + Remove-Variable onedrive +} + +Function Invoke-Admin { + if ($args.Count -gt 0) { + $argList = "& '" + $args + "'" + Start-Process "$PSHOME\pwsh.exe" -Verb runAs -ArgumentList $argList + } else { + Start-Process "$PSHOME\pwsh.exe" -Verb RunAs + } +} + +Function Edit-PSProfile { + $cmd = "$Env:Editor $PROFILE.CurrentUserAllHosts" + Invoke-Expression -Command $cmd +} + +Function Edit-PSProfileProject { + if (-not($ProfileRootPath)) { + Write-Warning 'ProfileRootPath not found.' + $Global:ProfileRootPath = Split-Path -Path $PROFILE -Parent + } + + $cmd = "$Env:Editor $ProfileRootPath" + Invoke-Expression -Command $cmd +} + +Function Invoke-WingetUpdate { + Import-Module WingetTools + +} + +# Get-ProfileFunctions: Lists all custom functions in the current PowerShell profile. + +Function Get-PSProfileFunctions { + <# + .SYNOPSIS + Lists all custom functions in the current PowerShell profile. + .DESCRIPTION + Lists all custom functions in the current PowerShell profile. + .EXAMPLE + Get-ProfileFunctions + .NOTES + Author: Jimmy Briggs + #> + + $Functions = @( + + [PSCustomObject]@{ + Name = 'Get-PSProfileFunctions' + Description = 'Lists all custom functions in the current PowerShell profile.' + Alias = 'psprofilefunctions' + } + + [PSCustomObject]@{ + Name = 'Get-PSProfileModules' + Description = 'Lists all loaded modules in the current PowerShell profile.' + Alias = 'psprofilemodules' + } + + [PSCustomObject]@{ + Name = 'Update-Environment' + Description = 'Updates the current environment.' + Alias = 'refreshenv' + } + + [PSCustomObject]@{ + Name = 'Invoke-ProfileReload' + Description = 'Reloads the current PowerShell profile.' + Alias = 'reloadpsprofile' + } + + [PSCustomObject]@{ + Name = 'Get-PublicIP' + Description = 'Gets the public IP address of the current machine.' + Alias = 'publicip' + } + + [PSCustomObject]@{ + Name = 'Get-Timestamp' + Description = 'Gets the current timestamp.' + Alias = 'timestamp' + } + + [PSCustomObject]@{ + Name = 'Get-RandomPassword' + Description = 'Generates a random password.' + Alias = 'randompassword' + } + + [PSCustomObject]@{ + Name = 'Update-WinGet' + Description = 'Updates the Windows Package Manager (WinGet).' + Alias = 'updatewinget' + } + + [PSCustomObject]@{ + Name = 'Update-Chocolatey' + Description = 'Updates the Chocolatey Package Manager.' + Alias = 'updatechoco' + } + + [PSCustomObject]@{ + Name = 'Update-Scoop' + Description = 'Updates the Scoop Package Manager.' + Alias = 'updatescoop' + } + + [PSCustomObject]@{ + Name = 'Update-R' + Description = 'Updates the R Programming Language.' + Alias = 'updater' + } + + [PSCustomObject]@{ + Name = 'Update-Python' + Description = 'Updates the Python Programming Language.' + Alias = 'updatepython' + } + + [PSCustomObject]@{ + Name = 'Update-Node' + Description = 'Updates the Node.js JavaScript Runtime.' + Alias = 'updatenode' + } + + ) + + Write-Host 'PowerShell Profile Custom Functions:' -ForegroundColor Cyan + + $Functions | Format-Table -AutoSize +} diff --git a/PSProfile/PSProfile.Modules.ps1 b/PSProfile/PSProfile.Modules.ps1 new file mode 100644 index 0000000..0f9cd88 --- /dev/null +++ b/PSProfile/PSProfile.Modules.ps1 @@ -0,0 +1,42 @@ +# Alternate PSModulesPath (User) +if ($isWindows) { + $LocalAppDataModulePath = Join-Path -Path $env:LOCALAPPDATA -ChildPath 'PowerShell\Modules' + if (-not(Test-Path -Path $LocalAppDataModulePath)) { + New-Item -Path $LocalAppDataModulePath -ItemType Directory -Force + } + # Add to Start of PSModulePath + $env:PSModulePath = $LocalAppDataModulePath + [IO.Path]::PathSeparator + $env:PSModulePath +} + +$ProfileModulesToImport = @( + 'PSReadLine' + 'posh-git' + 'Terminal-Icons' + 'PSFzf' + 'PSEverything' + 'CompletionPredictor' + 'Microsoft.PowerShell.ConsoleGuiTools' + 'F7History' +) + +ForEach ($Mod in $ProfileModulesToImport) { + try { + Write-Verbose "Importing Module: $Mod" + Import-Module $Mod -ErrorAction Stop + } catch { + Write-Warning "Failed to install module: $Mod" + try { + Install-PSResource $Mod -Scope CurrentUser -Force -ErrorAction Stop + } catch { + Write-Warning "Failed to install module: $Mod" + Continue + } + } finally { + Import-Module -Name $Mod -ErrorAction SilentlyContinue + } +} + +if (Get-PSResource -Name ZLocation) { + Import-Module ZLocation + Write-Host -Foreground Green "`n[ZLocation] knows about $((Get-ZLocation).Keys.Count) locations.`n" +} diff --git a/PSProfile/PSProfile.Prompt.ps1 b/PSProfile/PSProfile.Prompt.ps1 new file mode 100644 index 0000000..9da0cc1 --- /dev/null +++ b/PSProfile/PSProfile.Prompt.ps1 @@ -0,0 +1,37 @@ +# ----------------------------------------------------------------------------- +# PowerShell Profile - Prompt +# ----------------------------------------------------------------------------- + +Class OMPThemes : System.Management.Automation.IValidateSetValuesGenerator { + [String[]] GetValidValues() { + $OMPThemes = ((Get-ChildItem -Path "$Env:POSH_THEMES_PATH" -Filter "*.omp.json").Name -replace ".omp.json", "") + return [String[]]$OMPThemes + } +} + +Function Set-OMPTheme { + [CmdletBinding()] + Param( + [ValidateSet([OMPThemes])] + [String]$Theme + ) + + try { + $ConfigPath = Join-Path "$Env:POSH_THEMES_PATH" "$Theme.omp.json" + (& oh-my-posh init pwsh --config=$ConfigPath --print) -join "`n" | Invoke-Expression + } catch [CommandNotFoundException] { + Write-Warning "Failed to set oh-my-posh theme" + return + } finally { + if ($?) { + Write-Verbose "oh-my-posh theme set to '$Theme'" + $Global:POSH_THEME = $Theme + } + } + +} + +if (Get-Command oh-my-posh -ErrorAction SilentlyContinue) { + Write-Verbose "Setting oh-my-posh theme..." + Set-OMPTheme -Theme space +} diff --git a/Profile.ps1 b/Profile.ps1 new file mode 100644 index 0000000..28559d4 --- /dev/null +++ b/Profile.ps1 @@ -0,0 +1,67 @@ +using namespace System.Management.Automation +using namespace System.Management.Automation.Language +using namespace System.Diagnostics.CodeAnalysis + +# Version: 0.1.0 + +# -------------------------------------------------------------------- +# Current User, All Hosts Powershell Core v7 $PROFILE +# Path: $Home\Documents\PowerShell\Profile.ps1 +# -------------------------------------------------------------------- + +<# + .SYNOPSIS + Current User, All Hosts PowerShell `$PROFILE`: `Profile.ps1` + .DESCRIPTION + This script is executed when a new PowerShell session is created for the current user, on any host. + .PARAMETER Vanilla + Runs a "vanilla" session, without any configurations, variables, customizations, modules or scripts pre-loaded. + .PARAMETER NoImports + Skips importing modules and scripts. + .NOTES + Author: Jimmy Briggs +#> +#Requires -Version 7 +[SuppressMessageAttribute('PSAvoidAssignmentToAutomaticVariable', '', Justification = 'PS7 Polyfill')] +[SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Profile Script')] +Param( + [Parameter()] + [Switch]$Vanilla, + + [Parameter()] + [Switch]$NoImports +) + +# -------------------------------------------------------------------- +# Profile Variables +# -------------------------------------------------------------------- + +# Profile Paths +$ProfileRootPath = Split-Path -Path $PROFILE -Parent +$ProfileSourcePath = Join-Path -Path $ProfileRootPath -ChildPath 'Profile' + +# System Information +if ($PSEdition -eq 'Desktop') { + $isWindows = $true + $isLinux = $false + $isMacOS = $false +} + +# -------------------------------------------------------------------- +# Profile Environment +# -------------------------------------------------------------------- + +# Set editor to VSCode +if (Get-Command code -Type Application -ErrorAction SilentlyContinue) { + $ENV:EDITOR = 'code' +} + +if ($Host.Name -eq 'ConsoleHost') { + Write-Verbose "Detected Host: 'ConsoleHost'. Loading 'PSReadLine' Setup..." + . "$ProfileSourcePath/Profile.PSReadLine.ps1" +} + +. "$ProfileSourcePath/Profile.Shorthands.ps1" +. "$ProfileSourcePath/Profile.Helpers.ps1" +. "$ProfileSourcePath/Profile.Integrations.ps1" +. "$ProfileSourcePath/Profile.Modules.ps1" diff --git a/profile.ps1 b/profile.ps1 deleted file mode 100644 index 3d57631..0000000 --- a/profile.ps1 +++ /dev/null @@ -1,10 +0,0 @@ -#Requires -Version 7 - -# Version: 0.1.0 - -# ---------------------------------------------------- -# Current User, All Hosts Powershell Core v7 $PROFILE: -# ---------------------------------------------------- - -$psfiles = Join-Path (Split-Path -Parent $profile) "Profile" | Get-ChildItem -Filter "*.ps1" -ForEach ($file in $psfiles) { . $file }