Last active
February 24, 2023 14:37
-
-
Save bugged-codes/5b8c7e835fd7bbfc4d92920c955a7bc2 to your computer and use it in GitHub Desktop.
Customized Powershell Profile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# powershell profile is located at %userporfile%/documents/PowerShell/Microsoft.PowerShell_profile.ps1 | |
using namespace System.Management.Automation | |
using namespace System.Management.Automation.Language | |
# PSReadLine | |
Import-Module PSReadLine | |
Set-PSReadLineKeyHandler -key Tab -Function Complete | |
Set-PSReadLineOption -PredictionSource History | |
Set-PSReadLineOption -PredictionViewStyle ListView | |
Set-PSReadLineOption -EditMode Windows | |
#PSReadLine Custom Options taken from Scott Hanselman's powershell and tim sneath gists. | |
# This key handler shows the entire or filtered history using Out-GridView. The typed text is used as the substring pattern for filtering. | |
#A selected command is inserted to the command line without invoking. Multiple command selection is supported, e.g. selected by Ctrl + Click. | |
Set-PSReadLineKeyHandler -Key F7 ` | |
-BriefDescription History ` | |
-LongDescription 'Show command history' ` | |
-ScriptBlock { | |
$pattern = $null | |
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$pattern, [ref]$null) | |
if ($pattern) | |
{ | |
$pattern = [regex]::Escape($pattern) | |
} | |
$history = [System.Collections.ArrayList]@( | |
$last = '' | |
$lines = '' | |
foreach ($line in [System.IO.File]::ReadLines((Get-PSReadLineOption).HistorySavePath)) | |
{ | |
if ($line.EndsWith('`')) | |
{ | |
$line = $line.Substring(0, $line.Length - 1) | |
$lines = if ($lines) | |
{ | |
"$lines`n$line" | |
} | |
else | |
{ | |
$line | |
} | |
continue | |
} | |
if ($lines) | |
{ | |
$line = "$lines`n$line" | |
$lines = '' | |
} | |
if (($line -cne $last) -and (!$pattern -or ($line -match $pattern))) | |
{ | |
$last = $line | |
$line | |
} | |
} | |
) | |
$history.Reverse() | |
$command = $history | Out-GridView -Title History -PassThru | |
if ($command) | |
{ | |
[Microsoft.PowerShell.PSConsoleReadLine]::RevertLine() | |
[Microsoft.PowerShell.PSConsoleReadLine]::Insert(($command -join "`n")) | |
} | |
} | |
# The next four key handlers are designed to make entering matched quotes, parens, and braces a nicer experience. | |
# I'd like to include functions in the module that do this, but this implementation still isn't as smart as ReSharper, so I'm just providing it as a sample. | |
Set-PSReadLineKeyHandler -Key '"',"'" ` | |
-BriefDescription SmartInsertQuote ` | |
-LongDescription "Insert paired quotes if not already on a quote" ` | |
-ScriptBlock { | |
param($key, $arg) | |
$quote = $key.KeyChar | |
$selectionStart = $null | |
$selectionLength = $null | |
[Microsoft.PowerShell.PSConsoleReadLine]::GetSelectionState([ref]$selectionStart, [ref]$selectionLength) | |
$line = $null | |
$cursor = $null | |
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor) | |
# If text is selected, just quote it without any smarts | |
if ($selectionStart -ne -1) | |
{ | |
[Microsoft.PowerShell.PSConsoleReadLine]::Replace($selectionStart, $selectionLength, $quote + $line.SubString($selectionStart, $selectionLength) + $quote) | |
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($selectionStart + $selectionLength + 2) | |
return | |
} | |
$ast = $null | |
$tokens = $null | |
$parseErrors = $null | |
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$ast, [ref]$tokens, [ref]$parseErrors, [ref]$null) | |
function FindToken | |
{ | |
param($tokens, $cursor) | |
foreach ($token in $tokens) | |
{ | |
if ($cursor -lt $token.Extent.StartOffset) { continue } | |
if ($cursor -lt $token.Extent.EndOffset) { | |
$result = $token | |
$token = $token -as [StringExpandableToken] | |
if ($token) { | |
$nested = FindToken $token.NestedTokens $cursor | |
if ($nested) { $result = $nested } | |
} | |
return $result | |
} | |
} | |
return $null | |
} | |
$token = FindToken $tokens $cursor | |
# If we're on or inside a **quoted** string token (so not generic), we need to be smarter | |
if ($token -is [StringToken] -and $token.Kind -ne [TokenKind]::Generic) { | |
# If we're at the start of the string, assume we're inserting a new string | |
if ($token.Extent.StartOffset -eq $cursor) { | |
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("$quote$quote ") | |
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor + 1) | |
return | |
} | |
# If we're at the end of the string, move over the closing quote if present. | |
if ($token.Extent.EndOffset -eq ($cursor + 1) -and $line[$cursor] -eq $quote) { | |
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor + 1) | |
return | |
} | |
} | |
if ($null -eq $token -or | |
$token.Kind -eq [TokenKind]::RParen -or $token.Kind -eq [TokenKind]::RCurly -or $token.Kind -eq [TokenKind]::RBracket) { | |
if ($line[0..$cursor].Where{$_ -eq $quote}.Count % 2 -eq 1) { | |
# Odd number of quotes before the cursor, insert a single quote | |
[Microsoft.PowerShell.PSConsoleReadLine]::Insert($quote) | |
} | |
else { | |
# Insert matching quotes, move cursor to be in between the quotes | |
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("$quote$quote") | |
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor + 1) | |
} | |
return | |
} | |
# If cursor is at the start of a token, enclose it in quotes. | |
if ($token.Extent.StartOffset -eq $cursor) { | |
if ($token.Kind -eq [TokenKind]::Generic -or $token.Kind -eq [TokenKind]::Identifier -or | |
$token.Kind -eq [TokenKind]::Variable -or $token.TokenFlags.hasFlag([TokenFlags]::Keyword)) { | |
$end = $token.Extent.EndOffset | |
$len = $end - $cursor | |
[Microsoft.PowerShell.PSConsoleReadLine]::Replace($cursor, $len, $quote + $line.SubString($cursor, $len) + $quote) | |
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($end + 2) | |
return | |
} | |
} | |
# We failed to be smart, so just insert a single quote | |
[Microsoft.PowerShell.PSConsoleReadLine]::Insert($quote) | |
} | |
Set-PSReadLineKeyHandler -Key '(','{','[' ` | |
-BriefDescription InsertPairedBraces ` | |
-LongDescription "Insert matching braces" ` | |
-ScriptBlock { | |
param($key, $arg) | |
$closeChar = switch ($key.KeyChar) | |
{ | |
<#case#> '(' { [char]')'; break } | |
<#case#> '{' { [char]'}'; break } | |
<#case#> '[' { [char]']'; break } | |
} | |
$selectionStart = $null | |
$selectionLength = $null | |
[Microsoft.PowerShell.PSConsoleReadLine]::GetSelectionState([ref]$selectionStart, [ref]$selectionLength) | |
$line = $null | |
$cursor = $null | |
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor) | |
if ($selectionStart -ne -1) | |
{ | |
# Text is selected, wrap it in brackets | |
[Microsoft.PowerShell.PSConsoleReadLine]::Replace($selectionStart, $selectionLength, $key.KeyChar + $line.SubString($selectionStart, $selectionLength) + $closeChar) | |
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($selectionStart + $selectionLength + 2) | |
} else { | |
# No text is selected, insert a pair | |
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("$($key.KeyChar)$closeChar") | |
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor + 1) | |
} | |
} | |
Set-PSReadLineKeyHandler -Key ')',']','}' ` | |
-BriefDescription SmartCloseBraces ` | |
-LongDescription "Insert closing brace or skip" ` | |
-ScriptBlock { | |
param($key, $arg) | |
$line = $null | |
$cursor = $null | |
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor) | |
if ($line[$cursor] -eq $key.KeyChar) | |
{ | |
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor + 1) | |
} | |
else | |
{ | |
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("$($key.KeyChar)") | |
} | |
} | |
Set-PSReadLineKeyHandler -Key Backspace ` | |
-BriefDescription SmartBackspace ` | |
-LongDescription "Delete previous character or matching quotes/parens/braces" ` | |
-ScriptBlock { | |
param($key, $arg) | |
$line = $null | |
$cursor = $null | |
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor) | |
if ($cursor -gt 0) | |
{ | |
$toMatch = $null | |
if ($cursor -lt $line.Length) | |
{ | |
switch ($line[$cursor]) | |
{ | |
<#case#> '"' { $toMatch = '"'; break } | |
<#case#> "'" { $toMatch = "'"; break } | |
<#case#> ')' { $toMatch = '('; break } | |
<#case#> ']' { $toMatch = '['; break } | |
<#case#> '}' { $toMatch = '{'; break } | |
} | |
} | |
if ($toMatch -ne $null -and $line[$cursor-1] -eq $toMatch) | |
{ | |
[Microsoft.PowerShell.PSConsoleReadLine]::Delete($cursor - 1, 2) | |
} | |
else | |
{ | |
[Microsoft.PowerShell.PSConsoleReadLine]::BackwardDeleteChar($key, $arg) | |
} | |
} | |
} | |
# F1 for help on the command line - naturally | |
Set-PSReadLineKeyHandler -Key F1 ` | |
-BriefDescription CommandHelp ` | |
-LongDescription "Open the help window for the current command" ` | |
-ScriptBlock { | |
param($key, $arg) | |
$ast = $null | |
$tokens = $null | |
$errors = $null | |
$cursor = $null | |
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$ast, [ref]$tokens, [ref]$errors, [ref]$cursor) | |
$commandAst = $ast.FindAll( { | |
$node = $args[0] | |
$node -is [CommandAst] -and | |
$node.Extent.StartOffset -le $cursor -and | |
$node.Extent.EndOffset -ge $cursor | |
}, $true) | Select-Object -Last 1 | |
if ($commandAst -ne $null) | |
{ | |
$commandName = $commandAst.GetCommandName() | |
if ($commandName -ne $null) | |
{ | |
$command = $ExecutionContext.InvokeCommand.GetCommand($commandName, 'All') | |
if ($command -is [AliasInfo]) | |
{ | |
$commandName = $command.ResolvedCommandName | |
} | |
if ($commandName -ne $null) | |
{ | |
Get-Help $commandName -ShowWindow | |
} | |
} | |
} | |
} | |
### Tim sneaths profile | |
### From https://gist.github.com/timsneath/19867b12eee7fd5af2ba | |
### | |
### As a reminder, to enable unsigned script execution of local scripts on client Windows, | |
### you need to run this line (or similar) from an elevated PowerShell prompt: | |
### Set-ExecutionPolicy -ExecutionPolicy RemoteSigned | |
### This is the default policy on Windows Server 2012 R2 and above for server Windows. For | |
### more information about execution policies, run Get-Help about_Execution_Policies. | |
# Find out if the current user identity is elevated (has admin rights) | |
$identity = [Security.Principal.WindowsIdentity]::GetCurrent() | |
$principal = New-Object Security.Principal.WindowsPrincipal $identity | |
$isAdmin = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) | |
# If so and the current host is a command line, then change to red color | |
# as warning to user that they are operating in an elevated context | |
if (($host.Name -match "ConsoleHost") -and ($isAdmin)) | |
{ | |
$host.UI.RawUI.BackgroundColor = "DarkRed" | |
$host.PrivateData.ErrorBackgroundColor = "White" | |
$host.PrivateData.ErrorForegroundColor = "DarkRed" | |
Clear-Host | |
} | |
# Useful shortcuts for traversing directories | |
function cd... { cd ..\.. } | |
function cd.... { cd ..\..\.. } | |
# Compute file hashes - useful for checking successful downloads | |
function md5 { Get-FileHash -Algorithm MD5 $args } | |
function sha1 { Get-FileHash -Algorithm SHA1 $args } | |
function sha256 { Get-FileHash -Algorithm SHA256 $args } | |
# Set up command prompt and window title. Use UNIX-style convention for identifying | |
# whether user is elevated (root) or not. Window title shows current version of PowerShell | |
# and appends [ADMIN] if appropriate for easy taskbar identification | |
function prompt | |
{ | |
if ($isAdmin) | |
{ | |
"[" + (Get-Location) + "] # " | |
} | |
else | |
{ | |
"[" + (Get-Location) + "] $ " | |
} | |
} | |
$Host.UI.RawUI.WindowTitle = "PowerShell {0}" -f $PSVersionTable.PSVersion.ToString() | |
if ($isAdmin) | |
{ | |
$Host.UI.RawUI.WindowTitle += " [ADMIN]" | |
} | |
# Simple function to start a new elevated process. If arguments are supplied then | |
# a single command is started with admin rights; if not then a new admin instance | |
# of PowerShell is started. | |
function admin | |
{ | |
if ($args.Count -gt 0) | |
{ | |
$argList = "& '" + $args + "'" | |
Start-Process "pwsh" -Verb runAs -ArgumentList $argList | |
} | |
else | |
{ | |
Start-Process "pwsh" -Verb runAs | |
} | |
} | |
# Set UNIX-like aliases for the admin command, so sudo <command> will run the command | |
# with elevated rights. | |
Set-Alias -Name su -Value admin | |
Set-Alias -Name sudo -Value admin | |
# We don't need these any more; they were just temporary variables to get to $isAdmin. | |
# Delete them to prevent cluttering up the user profile. | |
Remove-Variable identity | |
Remove-Variable principal | |
# Oh-My-Posh settings | |
<# Install OMP: | |
winget install JanDeDobbeleer.OhMyPosh -s winget | |
#> | |
# Created variables for OMP theme. | |
# In order to change theme just change .json theme in $OMPThemePath | |
$OMPThemesFolder = $($env:APPDATA)+'\..\Local\Programs\oh-my-posh\themes\' | |
$OMPThemePath = $OMPThemesFolder + 'powerlevel10k_rainbow.omp.json' | |
oh-my-posh init pwsh --config $OMPThemePath | Invoke-Expression | |
# Terminal Icons | |
Import-Module -Name Terminal-Icons | |
# this is single line comment | |
<# Block-Comment | |
To change theme, replace name of the theme with the one you want to install, i.e. the word after ..\themes\ and keep extension as ".omp.json" | |
After changing theme, apply the current profile by giving ".$PROFILE" command in powershell. | |
My Favoriate themes: | |
1. tokyo | |
2. quick-term | |
3. emodipt-extend | |
4. slim | |
5. space | |
6. plague | |
7. powerlevel10k_rainbow | |
8. montys | |
9. kushal | |
Install **file type icons** type command: | |
Install-Module -Name Terminal-Icons -Repository PSGallery | |
and then add following command to profile file of powershell: | |
Import-Module -Name Terminal-Icons | |
To install Z use coommand: | |
install-module -name z -force | |
To install PSReadLine: | |
install-module -name PSReadLine -AllowPrerelese -scope CurrentUser -force -SkipPublisherCheck | |
Options for PSReadLine: | |
set-PSReadLineOption -PredictionSource History | |
restart terminal/shell | |
set-PSReadLineOption -PredictionViewStyle ListView | |
#> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment