PowerShell-profile/
├── Microsoft.PowerShell_profile.ps1 # Main orchestrator
├── Core/
│ ├── ModuleInstaller.ps1 # Module installation & caching
│ ├── UnifiedModuleManager.ps1 # Module loading & caching
│ ├── Utils/
│ │ ├── unified_aliases.ps1 # Centralized aliases & command cache
│ │ ├── CommonUtils.ps1 # Common utility functions
│ │ ├── FileSystemUtils.ps1 # File/archive operations
│ │ ├── SearchUtils.ps1 # Search utilities (ff, search)
│ │ └── profile_management.ps1 # Profile state reset
│ ├── Apps/
│ │ ├── appsManage.ps1 # Package manager operations (scoop/choco/pip/npm)
│ │ ├── InstallMissingTools.ps1 # Missing tool detection & install
│ │ ├── UpdateApps.ps1 # App update orchestrator
│ │ ├── UpdateAppsHelper.ps1 # Update helper functions
│ │ ├── WindowsUpdateHelper.ps1 # Windows Update management
│ │ └── Updates/SystemUpdater.ps1 # System-wide update management
│ └── System/
│ ├── chezmoi.ps1 # Chezmoi dotfile manager
│ ├── clean.ps1 # Disk cleanup utilities
│ ├── fzf.ps1 # Fuzzy finder integration
│ └── linuxLike.ps1 # Linux-like utility functions
├── Config/
│ ├── starship.toml # Prompt configuration
│ └── *-cache.* # Auto-generated caches
└── tools/
├── install-dependencies.ps1 # Dependency installer
└── generate_function_docs.ps1 # Documentation generator
Add to Microsoft.PowerShell_profile.ps1:
function My-CustomFunction {
param([string]$Path)
# Your logic here
Get-ChildItem $Path -Recurse
}Create Core/Utils/MyCustomUtils.ps1:
<#
.SYNOPSIS
Custom utilities for my workflow
.DESCRIPTION
Collection of personalized helper functions
#>
function Deploy-Application {
<#
.SYNOPSIS
Deploy application to target environment
.EXAMPLE
Deploy-Application -Environment Production
#>
param(
[Parameter(Mandatory)]
[ValidateSet('Dev', 'Staging', 'Production')]
[string]$Environment
)
Write-Host "Deploying to $Environment..."
# Deployment logic
}
Export-ModuleMember -Function Deploy-ApplicationThen load in profile:
# In Microsoft.PowerShell_profile.ps1
. "$PSScriptRoot\Core\Utils\MyCustomUtils.ps1"Add to Core/Utils/unified_aliases.ps1:
# Custom development aliases
Set-Alias -Name deploy -Value Deploy-Application
Set-Alias -Name build -Value Invoke-Build
# Tool shortcuts
if (Test-CommandExist 'kubectl') {
Set-Alias -Name k -Value kubectl
Set-Alias -Name kx -Value kubectx
}Add directly to Microsoft.PowerShell_profile.ps1:
Set-Alias -Name myalias -Value My-CustomFunctionAdd custom modules to the profile using the lazy-loading pattern:
# In Microsoft.PowerShell_profile.ps1
Register-EngineEvent -SourceIdentifier PowerShell.OnIdle -MaxTriggerCount 1 -Action {
$mod = Get-Module -ListAvailable -Name MyCompanyModule -ErrorAction SilentlyContinue
if ($mod) { Import-Module MyCompanyModule -ErrorAction SilentlyContinue }
} | Out-Null# Load Azure modules only in work directories
if ($PWD.Path -match 'C:\\Work') {
Import-Module Az.Accounts, Az.Resources -ErrorAction SilentlyContinue
}Add to profile:
$env:MY_API_KEY = 'secret-key'
$env:WORKSPACE_ROOT = 'C:\Dev\Projects'[System.Environment]::SetEnvironmentVariable(
'MY_VAR',
'value',
[System.EnvironmentVariableTarget]::User
)Edit Config/starship.toml:
# Add custom modules
[custom.myproject]
command = "echo 🚀 MyProject"
when = "test -d .myproject"
style = "bold blue"
format = "[$output]($style) "
# Modify existing modules
[git_branch]
symbol = "🌱 "
style = "bold purple"Invalidate cache after changes:
Remove-Item Config\starship-init-cache.*
. $PROFILEAdd to Core/Utils/SearchUtils.ps1:
function Search-CodePattern {
<#
.SYNOPSIS
Search for specific code patterns
#>
param(
[string]$Pattern,
[string]$Path = '.'
)
if (Test-CommandExist fd) {
fd -e ps1 -e psm1 -x rg $Pattern {} $Path
} else {
Get-ChildItem $Path -Recurse -Include *.ps1,*.psm1 |
Select-String $Pattern
}
}# Add to profile
$script:MyCache = @{}
function Get-CachedData {
param([string]$Key)
if (-not $script:MyCache.ContainsKey($Key)) {
$script:MyCache[$Key] = Invoke-ExpensiveOperation $Key
}
return $script:MyCache[$Key]
}The profile uses PowerShell.OnIdle events to load modules after the prompt renders, adding zero startup cost:
Register-EngineEvent -SourceIdentifier PowerShell.OnIdle -MaxTriggerCount 1 -Action {
$VerbosePreference = 'SilentlyContinue'
# Modules loaded here run after the first prompt appears
if (Get-Command my-tool -ErrorAction SilentlyContinue) {
$mod = Get-Module -ListAvailable -Name MyToolCompletion -ErrorAction SilentlyContinue
if ($mod) { Import-Module MyToolCompletion -ErrorAction SilentlyContinue }
}
} | Out-NullAdd to Core/Utils/unified_aliases.ps1 or a custom utils file:
function New-FeatureBranch {
param([Parameter(Mandatory)]
[string]$Name)
$branchName = "feature/$Name"
git checkout -b $branchName
git push -u origin $branchName
}
Set-Alias -Name gfb -Value New-FeatureBranchAdd to Core/Apps/Updates/SystemUpdater.ps1:
function Update-CustomTools {
<#
.SYNOPSIS
Update custom tool installations
#>
# Example: Update rust tools
if (Test-CommandExist cargo) {
cargo install-update -a
}
# Example: Update npm globals
if (Test-CommandExist npm) {
npm update -g
}
}Register in main updater:
# In Update-AllSystems function
Update-CustomToolsCreate tests/MyCustomUtils.Tests.ps1:
BeforeAll {
. "$PSScriptRoot\..\Core\Utils\MyCustomUtils.ps1"
}
Describe 'Deploy-Application' {
It 'Should accept valid environments' {
{ Deploy-Application -Environment Dev } | Should -Not -Throw
}
It 'Should reject invalid environments' {
{ Deploy-Application -Environment InvalidEnv } | Should -Throw
}
}Run tests:
Invoke-Pester -Path tests\Custom functions automatically included in docs if properly commented:
function My-Function {
<#
.SYNOPSIS
Brief description
.DESCRIPTION
Detailed description
.PARAMETER Name
Parameter description
.EXAMPLE
My-Function -Name "Test"
Example usage
.NOTES
Additional notes
#>
param([string]$Name)
# Implementation
}Regenerate docs:
.\tools\generate_function_docs.ps1 -Verbose- Use structured comments - Enable auto-documentation
- Cache expensive operations - Improve load times
- Conditional loading - Only load what's needed
- Test-CommandExist - Check tool availability before use
- Export-ModuleMember - Explicit module exports
- Validate parameters - Use
[ValidateSet],[Parameter(Mandatory)] - Version control - Commit custom changes separately
- Document decisions - Comments for complex logic
# File: Core/Utils/ProjectUtils.ps1
<#
.SYNOPSIS
Project management utilities
#>
# Cache for project paths
$script:ProjectCache = @{}
function Set-ProjectRoot {
<#
.SYNOPSIS
Register a project root directory
.EXAMPLE
Set-ProjectRoot -Name "MyApp" -Path "C:\Dev\MyApp"
#>
param(
[Parameter(Mandatory)]
[string]$Name,
[Parameter(Mandatory)]
[string]$Path
)
$script:ProjectCache[$Name] = $Path
}
function Go-Project {
<#
.SYNOPSIS
Navigate to registered project
.EXAMPLE
Go-Project MyApp
#>
param([Parameter(Mandatory)]
[string]$Name)
if ($script:ProjectCache.ContainsKey($Name)) {
Set-Location $script:ProjectCache[$Name]
} else {
Write-Warning "Project '$Name' not registered"
}
}
# Auto-register common projects
Set-ProjectRoot -Name "Profile" -Path "$HOME\Documents\PowerShell"
Set-ProjectRoot -Name "Repos" -Path "$HOME\source\repos"
# Aliases
Set-Alias -Name gp -Value Go-Project
Export-ModuleMember -Function Set-ProjectRoot, Go-Project -Alias gpLoad in profile:
. "$PSScriptRoot\Core\Utils\ProjectUtils.ps1"