Skip to content

Instantly share code, notes, and snippets.

@neggles
Forked from apfelchips/Profile.ps1
Last active April 12, 2021 03:45
Show Gist options
  • Save neggles/71aa954bd93750d3c1dadc9302e52654 to your computer and use it in GitHub Desktop.
Save neggles/71aa954bd93750d3c1dadc9302e52654 to your computer and use it in GitHub Desktop.
my crossplatform PowerShell Profile
# Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
# src: https://gist.github.com/neg2led/71aa954bd93750d3c1dadc9302e52654
# New-Item $(Split-Path "$($PROFILE.CurrentUserCurrentHost)") -ItemType Directory -ea 0; Invoke-WebRequest -Uri "https://git\.io/JOL0Xu" -OutFile "$($PROFILE.CurrentUserCurrentHost)"
Clear-Host # remove advertisements
# bash-like
Set-Alias cat Get-Content -Option AllScope
Set-Alias cd Set-Location -Option AllScope
Set-Alias clear Clear-Host -Option AllScope
Set-Alias cp Copy-Item -Option AllScope
Set-Alias history Get-History -Option AllScope
Set-Alias kill Stop-Process -Option AllScope
Set-Alias lp Out-Printer -Option AllScope
Set-Alias ls Get-Childitem -Option AllScope
Set-Alias ll Get-Childitem -Option AllScope
Set-Alias mv Move-Item -Option AllScope
Set-Alias ps Get-Process -Option AllScope
Set-Alias pwd Get-Location -Option AllScope
#Set-Alias which Get-Command -Option AllScope
Set-Alias env Get-Environment -Option AllScope
Set-Alias open Invoke-Item -Option AllScope
Set-Alias basename Split-Path -Option AllScope
# cmd-like
Set-Alias rm Remove-Item -Option AllScope
Set-Alias rmdir Remove-Item -Option AllScope
Set-Alias echo Write-Output -Option AllScope
Set-Alias cls Clear-Host -Option AllScope
Set-Alias chdir Set-Location -Option AllScope
Set-Alias copy Copy-Item -Option AllScope
Set-Alias del Remove-Item -Option AllScope
Set-Alias dir Get-Childitem -Option AllScope
Set-Alias erase Remove-Item -Option AllScope
Set-Alias move Move-Item -Option AllScope
Set-Alias rd Remove-Item -Option AllScope
Set-Alias ren Rename-Item -Option AllScope
Set-Alias set Set-Variable -Option AllScope
Set-Alias type Get-Content -Option AllScope
# src: https://devblogs.microsoft.com/scripting/use-a-powershell-function-to-see-if-a-command-exists/
function Test-CommandExists {
Param ($command)
$oldPreference = $ErrorActionPreference
$ErrorActionPreference = 'stop'
try { if ( Get-Command $command ) { return $true } }
catch { return $false }
finally { $ErrorActionPreference = $oldPreference }
}
function Clean-Object {
process {
$_.PSObject.Properties.Remove('PSComputerName')
$_.PSObject.Properties.Remove('RunspaceId')
$_.PSObject.Properties.Remove('PSShowComputerName')
}
#Where-Object { $_.PSObject.Properties.Value -ne $null}
}
function Get-DefaultAliases {
Get-Alias | Where-Object { $_.Options -match "ReadOnly" }
}
function Remove-CustomAliases {
# https://stackoverflow.com/a/2816523
Get-Alias | Where-Object { ! $_.Options -match "ReadOnly" } | ForEach-Object { Remove-Item alias:$_ }
}
function Get-Environment {
# Get-Variable to show all Powershell Variables accessible via $
if ( $args.Count -eq 0 ) {
Get-ChildItem env:
} elseif ( $args.Count -eq 1 ) {
Start-Process (Get-Command $args[0]).Source
} else {
Start-Process (Get-Command $args[0]).Source -ArgumentList $args[1..($args.Count - 1)]
}
}
# function Set-EnvironmentAndPSVariable{
# if (([Environment]::GetEnvironmentVariable($args[0]))){
# Set-Variable -Name "$args[0]" -Value ([Environment]::GetEnvironmentVariable("$args[0]"))
# }
# else {
# [Environment]::SetEnvironmentVariable($args[0], $args[1], 'User')
# Set-Variable -Name $args[0] -Value $args[1]
# }
# }
# define these environment variables if not set already and also provide them as PSVariables
if (-not $env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME = Join-Path -Path "$HOME" -ChildPath ".config" }; $XDG_CONFIG_HOME = $env:XDG_CONFIG_HOME
if (-not $env:XDG_DATA_HOME) { $env:XDG_DATA_HOME = Join-Path -Path "$HOME" -ChildPath ".local/share" }; $XDG_DATA_HOME = $env:XDG_DATA_HOME
if (-not $env:XDG_CACHE_HOME) { $env:XDG_CACHE_HOME = Join-Path -Path "$HOME" -ChildPath ".cache" }; $XDG_CACHE_HOME = $env:XDG_CACHE_HOME
if (-not $env:DESKTOP_DIR) { $env:DESKTOP_DIR = Join-Path -Path "$HOME" -ChildPath "desktop" }; $DESKTOP_DIR = $env:DESKTOP_DIR
if (-not $env:NOTES_DIR) { $env:NOTES_DIR = Join-Path -Path "$HOME" -ChildPath "notes" }; $NOTES_DIR = $env:NOTES_DIR
if (-not $env:CHEATS_DIR) { $env:CHEATS_DIR = Join-Path -Path "$env:NOTES_DIR" -ChildPath "cheatsheets" }; $CHEATS_DIR = $env:CHEATS_DIR
if (-not $env:TODO_DIR) { $env:TODO_DIR = Join-Path -Path "$env:NOTES_DIR" -ChildPath "_ToDo" }; $TODO_DIR = $env:TODO_DIR
if (-not $env:DEVEL_DIR) { $env:DEVEL_DIR = Join-Path -Path "$HOME" -ChildPath "devel" }; $DEVEL_DIR = $env:DEVEL_DIR
if (-not $env:PORTS_DIR) { $env:PORTS_DIR = Join-Path -Path "$HOME" -ChildPath "ports" }; $PORTS_DIR = $env:PORTS_DIR
function cdc { Set-Location "$XDG_CONFIG_HOME" }
function cdd { Set-Location "$DESKTOP_DIR" }
function cdn { Set-Location "$NOTES_DIR" }
function cdcheat { Set-Location "$CHEATS_DIR" }
function cdt { Set-Location "$TODO_DIR" }
function cddev { Set-Location "$DEVEL_DIR" }
function cdports { Set-Location "$PORTS_DIR" }
function cf {
if ( $null -ne $(Get-Module PSFzf) ) {
Get-ChildItem . -Recurse -Attributes Directory | Invoke-Fzf | Set-Location
} else {
Write-Host "please install PSFzf"
}
}
function .. { Set-Location ".." }
function .... { Set-Location (Join-Path -Path ".." -ChildPath "..") }
if ( $(Test-CommandExists 'git') ) {
Set-Alias g git -Option AllScope
function git-root {
$gitrootdir = (git rev-parse --show-toplevel)
if ($gitrootdir) {
Set-Location $gitrootdir
}
}
if ( $IsWindows -or ($PSVersionTable.PSEdition -eq "Desktop") ) {
function git-bash {
if ( $args.Count -eq 0 ) {
. $(Join-Path -Path $(Split-Path -Path $(Get-Command git).Source) -ChildPath "..\bin\bash") -l
} else {
. $(Join-Path -Path $(Split-Path -Path $(Get-Command git).Source) -ChildPath "..\bin\bash") $args
}
}
}
}
function Select-Value {
# src: https://geekeefy.wordpress.com/2017/06/26/selecting-objects-by-value-in-powershell/
[Cmdletbinding()]
param(
[parameter(Mandatory = $true)] [String] $Value,
[parameter(ValueFromPipeline = $true)] $InputObject
)
process {
# Identify the PropertyName for respective matching Value, in order to populate it Default Properties
$Property = ($PSItem.properties.Where( { $_.Value -Like "$Value" })).Name
If ($Property) {
# Create Property a set which includes the 'DefaultPropertySet' and Property for the respective 'Value' matched
$DefaultPropertySet = $PSItem.PSStandardMembers.DefaultDisplayPropertySet.ReferencedPropertyNames
$TypeName = ($PSItem.PSTypenames)[0]
Get-TypeData $TypeName | Remove-TypeData
Update-TypeData -TypeName $TypeName -DefaultDisplayPropertySet ($DefaultPropertySet + $Property | Select-Object -Unique)
$PSItem | Where-Object { $_.properties.Value -like "$Value" }
}
}
}
# Convert bytecount into nice prettyprinted string
function Format-Bytes {
param (
[Parameter(Mandatory = $true,
ValueFromPipeline = $true)]
[ValidateNotNullOrEmpty()]
[uint64]
$byteval
)
process {
switch ($byteval) {
{ $_ -lt 1KB } { "{0}B" -f $byteval; break }
{ $_ -lt 1MB } { "{0}KB" -f [math]::round($byteval / 1KB, 2); break }
{ $_ -lt 1GB } { "{0}MB" -f [math]::round($byteval / 1MB, 2); break }
{ $_ -lt 1TB } { "{0}GB" -f [math]::round($byteval / 1GB, 2); break }
{ $_ -lt 1PB } { "{0}TB" -f [math]::round($byteval / 1TB, 2); break }
Default { "{0}PB" -f [math]::round($byteval / 1PB, 2); break }
}
}
}
# returns '[2020-05-05 13:23:08Z]' or similar
function Get-TimeStamp {
return "[{0:u}]" -f (Get-Date)
}
# Find a cmdlet/executable, like on linux
function which {
param (
[Parameter(Mandatory = $true)]
[String]
$name
)
Get-Command $name | Select-Object CommandType, Name, Definition -ExpandProperty Definition
}
if ( $IsWindows ) {
# add registry drives that are missing by default
function Add-RegistryDrives {
$Hives = @(
@{ Name = 'HKCR'; Root = 'HKEY_CLASSES_ROOT' }
@{ Name = 'HKUU'; Root = 'HKEY_USERS' }
@{ Name = 'HKCC'; Root = 'HKEY_CURRENT_CONFIG' }
)
foreach ($Hive in $Hives) {
if ((Get-PSDrive -Name $Hive.Name -ErrorAction SilentlyContinue)) {
Write-Verbose "PSDrive $($Hive.Name + ':\') found for hive $($Hive.Root), skipping" -Verbose
} else {
New-PSDrive @Hive -PSProvider Registry -Scope Global
Write-Verbose "PSDrive $($Hive.Name + ':\') added for hive $($Hive.Root)"
}
}
}
# one-shot to sync all DCs
function Sync-DCs {
[CmdletBinding()]
param (
# Specifies a path to one or more locations.
[Parameter(Mandatory = $false,
Position = 0,
HelpMessage = "List of Domain Controllers to sync.")]
[Alias("DCs", "DomainControllers", "DomainControllerList")]
[ValidateNotNullOrEmpty()]
[string[]]
$DCList = "All",
# Number of times to loop repadmin
[Parameter(Mandatory = $false,
Position = 1,
HelpMessage = "Number of times to loop synchronization. Defaults to 3")]
[int]
$LoopCount = 3
)
if ($DCList -eq "All") {
# Import AD module
try {
Write-Output "All domain controllers specified, getting list from AD"
Import-Module ActiveDirectory -ErrorAction Stop
$DCList = (Get-ADDomainController -Filter * -ErrorAction Stop).Name
} catch {
Write-Error -Message "Unable to retrieve domain controller list; do you have the AD PowerShell module installed?" -Category NotInstalled -ErrorAction Stop
}
}
Invoke-Command -ComputerName $DCList -ThrottleLimit 4 -ScriptBlock {
$LoopCount = $Using:LoopCount
$DCList = $Using:DCList
[int32]$InstanceID = $DCList.IndexOf($($DCList -match $Env:COMPUTERNAME))
for ($i = 1; $i -le $Using:LoopCount; $i++) {
Write-Progress -Id $InstanceID -Activity "Synchronizing $Env:COMPUTERNAME" -Status "Loop $i of $Using:LoopCount" -CurrentOperation "Pushing..." -PercentComplete $(100 / $LoopCount * ($i - 1) + (50 / $LoopCount))
Start-Process -FilePath "$Env:SystemRoot\system32\repadmin.exe" -ArgumentList "/syncall", "/APedq" -NoNewWindow -Wait
Start-Sleep -Seconds 3
Write-Progress -Id $InstanceID -Activity "Synchronizing $Env:COMPUTERNAME" -Status "Loop $i of $Using:LoopCount" -CurrentOperation "Pulling..." -PercentComplete $(100 / $LoopCount * $i)
Start-Process -FilePath "$Env:SystemRoot\system32\repadmin.exe" -ArgumentList "/syncall", "/Aedq" -NoNewWindow -Wait
Start-Sleep -Seconds 3
}
Write-Progress -Id $InstanceID -Activity "Synchronizing $Env:COMPUTERNAME" -Status "Complete" -Completed
Write-Output "Completed sync for $Env:COMPUTERNAME"
}
Write-Host "Done!" -ForegroundColor Green
}
}
function Show-Env {
Get-ChildItem Env: | Sort-Object -Property Name
}
# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions?view=powershell-7#piping-objects-to-functions
function all {
process { $_ | Select-Object * }
}
function list {
process { $_ | Format-List * }
}
function string {
process { $_ | Out-String -Stream }
}
function grep {
process { $_ | Select-String -Pattern $args }
}
function help {
Get-Help $args[0] | Out-Host -Paging
}
function man {
Get-Help $args[0] | Out-Host -Paging
}
function mkdir {
New-Item -type directory -Path (Join-Path "$args" -ChildPath "")
}
function md {
New-Item -type directory -Path (Join-Path "$args" -ChildPath "")
}
function pause($message = "Press any key to continue . . . ") {
Write-Host -NoNewline $message
$i = 16, 17, 18, 20, 91, 92, 93, 144, 145, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183
while ($null -eq $k.VirtualKeyCode -or $i -Contains $k.VirtualKeyCode) {
$k = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
Write-Host
}
if ( "${env:ChocolateyInstall}" -eq "" ) {
function Install-Chocolatey {
if (Get-Command choco -ErrorAction SilentlyContinue) {
Write-Output "chocolatey already installed!";
} else {
Start-Process (Get-HostExecutable) -ArgumentList "-Command Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1') -Verb RunAs"
}
}
} else {
function choco {
Start-Process (Get-HostExecutable) -ArgumentList "-Command choco.exe ${args}; pause" -Verb runAs
}
}
if ( Test-Path("${env:ChocolateyInstall}\helpers\chocolateyProfile.psm1") ) {
Import-Module "${env:ChocolateyInstall}\helpers\chocolateyProfile.psm1"
}
function Reload-Profile {
. $PROFILE.CurrentUserCurrentHost
}
function Download-Latest-Profile {
New-Item $( Split-Path $($PROFILE.CurrentUserCurrentHost) ) -ItemType Directory -ea 0
if ( $(Get-Content "$($PROFILE.CurrentUserCurrentHost)" | Select-String "71aa954bd93750d3c1dadc9302e52654" | Out-String) -eq "" ) {
Move-Item -Path "$($PROFILE.CurrentUserCurrentHost)" -Destination "$($PROFILE.CurrentUserCurrentHost).bak"
}
Invoke-WebRequest -Uri "https://gist.githubusercontent.com/neg2led/71aa954bd93750d3c1dadc9302e52654/raw/Profile.ps1" -OutFile "$($PROFILE.CurrentUserCurrentHost)"
Reload-Profile
}
if ( $IsWindows -or ($PSVersionTable.PSEdition -eq "Desktop") ) {
# src: http://serverfault.com/questions/95431
function isAdmin {
$user = [Security.Principal.WindowsIdentity]::GetCurrent();
(New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator);
}
<#
function subl {
start-process "${Env:ProgramFiles}\Sublime Text 3\subl.exe" -ArgumentList $args -WindowStyle Hidden # hide subl shim script
}
#>
<#
function stree($directory = $pwd) {
$gitrootdir = (Invoke-Command{Set-Location $args[0]; git rev-parse --show-toplevel 2>&1;} -ArgumentList $directory)
if ( Test-Path -Path "$gitrootdir\.git" -PathType Container){
$newestExe = Get-Item "${env:ProgramFiles(x86)}\Atlassian\SourceTree\SourceTree.exe" | select -Last 1
# Write-Host "Opening $gitrootdir with $newestExe"
start-process -filepath $newestExe -ArgumentList "-f `"$gitrootdir`" log"
}
else {
Write-Host "git directory not found"
}
}
#>
}
function Get-HostExecutable {
if ( $PSVersionTable.PSEdition -eq "Core" ) {
$ConsoleHostExecutable = (Get-Command pwsh).Source
} else {
$ConsoleHostExecutable = (Get-Command powershell).Source
}
return $ConsoleHostExecutable
}
# don't override chocolatey sudo or unix sudo
if ( -not $(Test-CommandExists 'sudo') ) {
function sudo() {
if ( $args.Length -eq 0 ) {
Start-Process (get-hostexecutable) -Verb "runAs"
}
if ( $args.Length -eq 1 ) {
Start-Process $args[0] -Verb "runAs"
}
if ( $args.Length -gt 1 ) {
Start-Process $args[0] -ArgumentList $args[1..$args.Length] -Verb "runAs"
}
}
}
function Clear-SavedHistory {
# src: https://stackoverflow.com/a/38807689
[CmdletBinding(ConfirmImpact = 'High', SupportsShouldProcess)]
param()
$havePSReadline = ( $null -ne $(Get-Module -EA SilentlyContinue PSReadline) )
$target = if ( $havePSReadline ) { "entire command history, including from previous sessions" } else { "command history" }
if ( -not $pscmdlet.ShouldProcess($target) ) { return }
if ( $havePSReadline ) {
Clear-Host
# Remove PSReadline's saved-history file.
if ( Test-Path (Get-PSReadLineOption).HistorySavePath ) {
# Abort, if the file for some reason cannot be removed.
Remove-Item -EA Stop (Get-PSReadLineOption).HistorySavePath
# To be safe, we recreate the file (empty).
$null = New-Item -Type File -Path (Get-PSReadLineOption).HistorySavePath
}
# Clear PowerShell's own history
Clear-History
[Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory()
} else {
# Without PSReadline, we only have a *session* history.
Clear-Host
Clear-History
}
}
function Install-MyModules {
Install-Module PSReadLine -Scope CurrentUser -Repository 'PSGallery' -AllowPrerelease -Force
Install-Module posh-git -Scope CurrentUser -Repository 'PSGallery' -AllowPrerelease -Force
Install-Module PSFzf -Scope CurrentUser -Repository 'PSGallery' -Force
}
function Install-PowershellGet {
Start-Process "$(Get-HostExecutable)" -ArgumentList "-noProfile -Command Install-Module -Name PowerShellGet -Repository PSGallery -Force -AllowClobber -SkipPublisherCheck; pause"
}
# if (($host.Name -eq 'ConsoleHost') -and ($null -ne (Get-Module -ListAvailable -Name PowershellGet))) {
# Import-Module PowershellGet
# }
if ( ($host.Name -eq 'ConsoleHost') -and ($null -ne (Get-Module -ListAvailable -Name PSReadLine)) ) {
# example: https://github.com/PowerShell/PSReadLine/blob/master/PSReadLine/SamplePSReadLineProfile.ps1
Import-Module PSReadLine
# Set-PSReadLineOption -EditMode Emac
Set-PSReadLineKeyHandler -Key Tab -Function MenuComplete
Set-PSReadLineOption -HistorySearchCursorMovesToEnd
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward
Set-PSReadLineKeyHandler -Chord 'Shift+Tab' -Function Complete
Set-PSReadLineOption -PredictionSource history
if ( $null -ne $(Get-Module PSFzf) ) {
#Set-PSReadLineKeyHandler -Key Tab -ScriptBlock { Invoke-FzfTabCompletion }
#$FZF_COMPLETION_TRIGGER='...'
Set-PsFzfOption -PSReadlineChordProvider 'Ctrl+t' -PSReadlineChordReverseHistory 'Ctrl+r'
}
}
if ( ($host.Name -eq 'ConsoleHost') -and ($null -ne (Get-Module -ListAvailable -Name posh-git)) ) {
Import-Module posh-git
}
if ( ($host.Name -eq 'ConsoleHost') -and ($null -ne (Get-Module -ListAvailable -Name oh-my-posh)) ) {
Import-Module oh-my-posh
Set-PoshPrompt -Theme Paradox
}
# already expanded to save time https://github.com/nvbn/thefuck/wiki/Shell-aliases#powershell
if ( $(Test-CommandExists 'thefuck') ) {
function fuck {
$PYTHONIOENCODING_BKP = $env:PYTHONIOENCODING
$env:PYTHONIOENCODING = "utf-8"
$history = (Get-History -Count 1).CommandLine;
if (-not [string]::IsNullOrWhiteSpace($history)) {
$fuck = $(thefuck $args $history);
if (-not [string]::IsNullOrWhiteSpace($fuck)) {
if ($fuck.StartsWith("echo")) { $fuck = $fuck.Substring(5); }
else { Invoke-Expression "$fuck"; }
}
}
[Console]::ResetColor()
$env:PYTHONIOENCODING = $PYTHONIOENCODING_BKP
}
Set-Alias f fuck -Option AllScope
}
# hacks for old powerhsell versions
if ( "$PSVersionTable.PSVERSION.Major" -lt 7 ) {
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8' # Fix Encoding for PS 5.1 -> 6.0 https://stackoverflow.com/a/40098904
function Get-ExitBoolean($command) {
# fixed: https://github.com/PowerShell/PowerShell/pull/9849
& $command | Out-Null; $?
}
Set-Alias geb Get-ExitBoolean
function Use-Default {
# $var = d $Value : "DefaultValue" eg. ternary # fixed: https://toastit.dev/2019/09/25/ternary-operator-powershell-7/
for ($i = 1; $i -lt $args.Count; $i++) {
if ($args[$i] -eq ":") {
$coord = $i; break
}
}
if ($coord -eq 0) {
throw new System.Exception "No operator!"
}
if ($args[$coord - 1] -eq "") {
$toReturn = $args[$coord + 1]
} else {
$toReturn = $args[$coord - 1]
}
return $toReturn
}
Set-Alias d Use-Default
}
Write-Host "`$PSVersion: $($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor).$($PSVersionTable.PSVersion.Patch)"
Write-Host "`$PSEdition: $($PSVersionTable.PSEdition | Out-String -NoNewline)"
Write-Host "`$Profile: $PSCommandPath"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment