HackF5.ProfileAlias.psm1
function Get-ProfileAliasDataDirectory { $path = [System.Environment]::GetFolderPath( [System.Environment+SpecialFolder]::LocalApplicationData, [System.Environment+SpecialFolderOption]::Create) $path = Join-Path -Path $path -ChildPath "pshw\alias" New-Item -ItemType Directory -Force -Path $path } function Get-ProfileAliasJsonPath { $path = Join-Path -Path (Get-ProfileAliasDataDirectory) -ChildPath "profile-alias.json" if (-not (Test-Path -Path $path)) { Set-Content -Path $path -Value "{ `"aliases`": [] }" } return $path } function Get-ProfileAliasModulePath { return Join-Path -Path (Get-ProfileAliasDataDirectory) -ChildPath "profile-alias-generated.psm1" } function Remove-ProfileAliasModule { if ($null -ne (Get-Module 'profile-alias-generated')) { Remove-Module 'profile-alias-generated' } } function Import-ProfileAliasModule { $jsonPath = Get-ProfileAliasJsonPath $modulePath = Get-ProfileAliasModulePath $json = Get-Content $jsonPath | ConvertFrom-Json $module = "" foreach ($alias in $json.aliases) { if (-not $alias.Extended) { Set-Alias -Name $($alias.name) -Value $($alias.command) -Scope Global -Option ReadOnly continue } $functionName = "Publish-ProfileAlias_$($alias.name)" $module += "function $functionName { $($alias.command) `$args }`n" $module += "Set-Alias -Name $($alias.name) -Value $functionName -Scope Global -Option ReadOnly" } Set-Content -Path $modulePath -Value $module Import-Module $modulePath -Global -Force } function Set-ProfileAlias { <# .SYNOPSIS Sets an alias that is loaded as part of your profile. .PARAMETER Name The name of the alias .PARAMETER Command The command to alias. This can either be any valid input to a standard PowerShell alias. Or it can be a string containing an executable object along with a predefined set of arguments. .PARAMETER Extended A switch that defaults to false. When false a standard PowerShell alias will be registered. When true a bash style alias will be created. .PARAMETER Force A switch that defaults to false. When false if an alias with that name already exists then an error will be raised. When true the alias will always be created or overwritten if it can be. .EXAMPLE Set-ProfileAlias -Name setp -Command Set-ProfileAlias Create an alias to the Set-ProfileAlias method so that you can now use `setp -Name foo -Command Get-Item`. But seriously don't do this. A better use is to create an alias for an executable that is not currently on your path and where you don't want to add the entire directory. There is a registry hack that supposedly purports to do this, but good luck with that. Set-ProfileAlias -Name laws -Command "docker run --network mynet --rm -it -v $env:userprofile\.aws\localstack:/root/.aws amazon/aws-cli --endpoint-url=http://localstack:4566" -Extended Creates the alias `laws` that allows you run the dockerized aws-cli against your dockerized localstack (yes, this is the posterboy for why PowerShell needs bash style aliases). So you can execute: laws sns list-topics And you will list all of the sns topics in your local stack. .LINK https://github.com/hackf5/powershell-profile-alias #> param ( [Parameter(Mandatory=$true)] [String] $Name, [Parameter(Mandatory=$true)] [String] $Command, [switch] $Extended, [switch] $Force ) $systemAlias = Get-Alias | Where-Object {$_.Name -eq $Name} if (($null -ne $systemAlias) -and (-not $Force)) { Write-Error "Alias '$Name' already exists, to overwrite use the -Force flag." Write-Output $systemAlias return } $jsonPath = Get-ProfileAliasJsonPath $json = Get-Content $jsonPath | ConvertFrom-Json $json.aliases = @($json.aliases | Where-Object {$_.name -ne $Name}) $alias = "" | Select-Object name, command, extended $alias.name = $Name $alias.command = $Command $alias.extended = $Extended.IsPresent $json.aliases += $alias ConvertTo-Json $json -Depth 10 | Set-Content $jsonPath -Force Import-ProfileAliasModule Write-Output $alias } function Remove-ProfileAlias { <# .SYNOPSIS Removes a profile alias. .PARAMETER Name The name of the profile alias to remove. .EXAMPLE Remove-ProfileAlias -Name alias1 .NOTES If no profile alias with this name exists then an error is raised. #> param ( [Parameter(Mandatory=$true)] [String] $Name ) $jsonPath = Get-ProfileAliasJsonPath $json = Get-Content $jsonPath | ConvertFrom-Json if ($null -eq ( Get-Alias | Where-Object {$_.Name -eq $Name})) { Write-Error "Alias '$Name' does not exist." return } if ($null -eq ($json.aliases | Where-Object {$_.name -eq $Name})) { Write-Error "Alias '$Name' is an alias, but not a profile alias. Use Remove-Alias instead." return } Remove-Alias -Name $Name -Force $json.aliases = @($json.aliases | Where-Object {$_.name -ne $Name}) ConvertTo-Json $json | Set-Content $jsonPath -Force Import-ProfileAliasModule } function Get-ProfileAlias { <# .SYNOPSIS Lists all of the profile aliases that are currently active. .OUTPUTS An array of { name, command, extended } where - name: the name of the alias - command: the command that is executed when the alias is invoked - extended: a value indicating whether this is a bash style alias .EXAMPLE Get-ProfileAlias Gets all currently registered aliases Get-ProfileAlias | Where-Object {$_.name -eq "alias1"} Gets the alias with name "alias1" or returns null if no such alias exists. .NOTES The profile alias module can be used for easily registering persistent PowerShell style aliases, or for registering persistent bash style aliases. They are persistent in the sense that they are loaded as part of your profile, so are available between sessions. A bash style alias is one that takes an arbitrary string as it's alias which is then executed, along with any additional arguments, when the alias is invoked. These are identified by extended=true. A PowerShell style alias, by comparison, is a rather limited beast that essentially allows a command, executable, etc... to be referred to by another name. They provide some utility, but are rather limited. #> $jsonPath = Get-ProfileAliasJsonPath $json = Get-Content $jsonPath | ConvertFrom-Json Write-Output $json.aliases } Export-ModuleMember Set-ProfileAlias Export-ModuleMember Remove-ProfileAlias Export-ModuleMember Get-ProfileAlias Import-ProfileAliasModule |