Last active
March 26, 2025 08:42
-
-
Save QNimbus/ded1f938a2b50ac5531201f3844d1219 to your computer and use it in GitHub Desktop.
PowerShell profile #windows #powershell
This file contains hidden or 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
# Deploy: pwsh -EncodedCommand "cAB3AHMAaAAgAC0ARQB4AGUAYwB1AHQAaQBvAG4AUABvAGwAaQBjAHkAIABVAG4AcgBlAHMAdAByAGkAYwB0AGUAZAAgAC0AQwBvAG0AbQBhAG4AZAAgAHsAIABTAHQAYQByAHQALQBQAHIAbwBjAGUAcwBzACAAcAB3AHMAaAAgAHsAIAAtAEMAbwBtAG0AYQBuAGQAIAAiACAATgBlAHcALQBJAHQAZQBtACAALQBUAHkAcABlACAARABpAHIAZQBjAHQAbwByAHkAIAAtAEYAbwByAGMAZQAgACIAIgAkAEUAbgB2ADoAVQBTAEUAUgBQAFIATwBGAEkATABFAFwARABvAGMAdQBtAGUAbgB0AHMAXABQAG8AdwBlAHIAUwBoAGUAbABsACIAIgAgAHwAIABPAHUAdAAtAE4AdQBsAGwAOwAgAEkAbgB2AG8AawBlAC0AVwBlAGIAUgBlAHEAdQBlAHMAdAAgAC0ASABlAGEAZABlAHIAcwAgAEAAewAiACIAQwBhAGMAaABlAC0AQwBvAG4AdAByAG8AbAAiACIAPQAiACIAbgBvAC0AYwBhAGMAaABlACIAIgB9ACAALQBPAHUAdABGAGkAbABlACAAIgAiACQARQBuAHYAOgBVAFMARQBSAFAAUgBPAEYASQBMAEUAXABEAG8AYwB1AG0AZQBuAHQAcwBcAFAAbwB3AGUAcgBTAGgAZQBsAGwAXABNAGkAYwByAG8AcwBvAGYAdAAuAFAAbwB3AGUAcgBTAGgAZQBsAGwAXwBwAHIAbwBmAGkAbABlAC4AcABzADEAIgAiACAALQBVAHIAaQAgACcAaAB0AHQAcABzADoALwAvAGcAaQBzAHQALgBnAGkAdABoAHUAYgB1AHMAZQByAGMAbwBuAHQAZQBuAHQALgBjAG8AbQAvAFEATgBpAG0AYgB1AHMALwBkAGUAZAAxAGYAOQAzADgAYQAyAGIANQAwAGEAYwA1ADUAMwAxADIAMAAxAGYAMwA4ADQANABkADEAMgAxADkALwByAGEAdwAvAE0AaQBjAHIAbwBzAG8AZgB0AC4AUABvAHcAZQByAFMAaABlAGwAbABfAHAAcgBvAGYAaQBsAGUALgBwAHMAMQAnACAAIgAgAH0AfQA=" | |
# This command deploys the PowerShell profile by running a base64 encoded command that sets up the environment. | |
# | |
# To force: Set-Item Env:\__ForceUpdateCheck $true; Start-Process pwsh | |
# References: | |
# - Installation of oh-my-posh: | |
# https://ohmyposh.dev/docs/installation/windows | |
# - Tutorial - Set up a custom prompt for PowerShell or WSL with Oh My Posh: | |
# https://learn.microsoft.com/en-us/windows/terminal/tutorials/custom-prompt-setup | |
# - How to make a pretty prompt in Windows Terminal with Powerline, Nerd Fonts, Cascadia Code, WSL, and oh-my-posh: | |
# https://www.hanselman.com/blog/how-to-make-a-pretty-prompt-in-windows-terminal-with-powerline-nerd-fonts-cascadia-code-wsl-and-ohmyposh | |
# | |
# TL;DR: | |
# - ```ps | |
# winget install JanDeDobbeleer.OhMyPosh -s winget | |
# Install-Module -Name Terminal-Icons -Repository PSGallery | |
# ``` | |
using namespace System.Management.Automation | |
using namespace System.Management.Automation.Language | |
# Variable to determine how many shells 'deep' we are | |
if (-not $Env:__ShellDepth) { | |
$Env:__ShellDepth = 0 | |
} | |
$Env:__ShellDepth = [int] $Env:__ShellDepth + 1 | |
# Timestamp of file to use to determine if code section has to be run | |
$dailyFile = $PROFILE | |
# Skip if we're in MS VSCode or if this is a subshell | |
$forceUpdate = $Env:__ForceUpdateCheck -eq $True | |
$isFirstShell = $Env:__ShellDepth -eq 1 | |
$isNotVSCode = $Env:TERM_PROGRAM -ne 'vscode' | |
$isDailyCheckDue = ((Get-Date) - (Get-Item $dailyFile).LastWriteTime).TotalHours -ge 24 | |
# Skip if we're in MS VSCode or if this is a subshell | |
if ($forceUpdate -Or ($isFirstShell -And $isNotVSCode -And $isDailyCheckDue)) { | |
# Update timestamp of $PROFILE file | |
(Get-Item $dailyFile).LastWriteTime = Get-Date | |
Write-Host "Daily check for packages that can be updated..." | |
# Packages not to update | |
$skipUpdate = @( | |
'Microsoft.DotNet.SDK.6', | |
'Microsoft.WindowsSDK' | |
) | |
class Software { | |
[string]$Name | |
[string]$Id | |
[string]$Version | |
[string]$AvailableVersion | |
[string]$Source | |
} | |
# Check if Scoop is installed and perform updates | |
if (Get-Command scoop -ErrorAction SilentlyContinue) { | |
Write-Host "Scoop is installed. Checking for updates..." | |
# Get outdated packages using Scoop | |
$scoopUpdates = scoop status | Select-String -Pattern '^\s*(\w+)\s+(\w+)\s+\->\s+(\w+)' | ForEach-Object { | |
$matches = $_ -match '^\s*(\w+)\s+(\w+)\s+\->\s+(\w+)' | |
[PSCustomObject]@{ | |
Name = $matches[1] | |
InstalledVersion = $matches[2] | |
LatestVersion = $matches[3] | |
} | |
} | |
if ($scoopUpdates.Count -gt 0) { | |
Write-Host "The following Scoop packages have updates available:" | |
$scoopUpdates | Format-Table | |
$timeoutSeconds = 10 | |
$defaultResponse = "N" | |
$response = $defaultResponse | |
Write-Host "You have $timeoutSeconds seconds to respond." | |
Write-Host "Would you like to update these packages? (Y/N) [Default: $defaultResponse] " -NoNewLine | |
While ((-not $Host.UI.RawUI.KeyAvailable) -and ($timeoutSeconds -gt 0)) { | |
Start-Sleep -Seconds 1 | |
$timeoutSeconds-- | |
} | |
if ($Host.UI.RawUI.KeyAvailable) { | |
$response = ($Host.UI.RawUI.ReadKey()).Character | |
} | |
Write-Host "" | |
if ($response -eq "Y") { | |
Write-Host "Updating Scoop packages..." | |
scoop update | |
} | |
else { | |
Write-Host "To update Scoop packages manually, run: scoop update" | |
} | |
} | |
else { | |
Write-Host "No Scoop packages need updates." | |
} | |
} | |
else { | |
Write-Host "Scoop is not installed. Skipping Scoop update check." | |
} | |
# Get available upgrades | |
$upgradeResult = winget upgrade --include-unknown --source winget | |
# Loop through the list and get package data | |
$upgrades = @() | |
$idStart = -1 | |
$isStartList = 0 | |
$upgradeResult | ForEach-Object -Process { | |
if ($isStartList -lt 1 -and -not $_.StartsWith("Name") -or $_.StartsWith("---") -or $_.StartsWith("The following packages")) { | |
return | |
} | |
if ($_.StartsWith("Name")) { | |
$idStart = $_.toLower().IndexOf("id") | |
$isStartList = 1 | |
return | |
} | |
if ($_.Length -lt $idStart) { | |
return | |
} | |
$Software = [Software]::new() | |
$Software.Name = $_.Substring(0, $idStart - 1) | |
$info = $_.Substring($idStart) -split '\s+' | |
$Software.Id = $info[0] | |
$Software.Version = $info[1] | |
$Software.AvailableVersion = $info[2] | |
$Software.Source = $info[3] | |
$upgrades += $Software | |
} | |
if ($upgrades.Length -ge 1) { | |
# View list | |
$upgrades | Format-Table | |
$timeoutSeconds = 10 | |
$defaultResponse = "N" | |
$response = $defaultResponse | |
Write-Host "You have $timeoutSeconds seconds to respond." | |
Write-Host "Are you sure you want to upgrade these packages? (Y/N) [Default: $defaultResponse] " -NoNewLine | |
While ((-not $Host.UI.RawUI.KeyAvailable) -and ($timeoutSeconds -gt 0)) { | |
Start-Sleep -Seconds 1 | |
$timeoutSeconds--; | |
} | |
if ($Host.UI.RawUI.KeyAvailable) { | |
$response = ($Host.UI.RawUI.ReadKey()).Character # Read-Host | |
} | |
Write-Host "" | |
if ($response -eq "Y") { | |
# Loop through the list, compare with the skip list and execute the upgrade (could be done in the upper foreach as well) | |
$upgrades | ForEach-Object -Process { | |
if ($skipUpdate -contains $_.Id) { | |
Write-Host "Skipped upgrade to package $($_.id)" | |
return | |
} | |
winget upgrade --include-unknown --source $($_.Source) $($_.Id) | |
} | |
} | |
else { | |
# Loop through the list, compare with the skip list and execute the upgrade (could be done in the upper foreach as well) | |
$upgrades | ForEach-Object -Process { | |
if ($skipUpdate -contains $_.Id) { | |
Write-Host "Skipped upgrade to package $($_.id)" | |
return | |
} | |
Write-Host "To upgrade $($_.Id), type : " -NoNewLine | |
'winget upgrade --include-unknown --source {0} {1}' -f $($_.Source), $_.Id | |
} | |
Write-Host "To force a re-run of this profile script, type : " -NoNewLine | |
'"Set-Item Env:\__ForceUpdateCheck $true; Start-Process pwsh"' | |
} | |
} | |
} | |
# Useful functions | |
function which($command) { | |
Get-Command -Name $command -ErrorAction SilentlyContinue | | |
Select-Object -ExpandProperty Path -ErrorAction SilentlyContinue | |
} | |
function Set-Location-Directory-Opus([string] $path = $(Get-Location)) { | |
& "${Env:ProgramFiles}\GPSoftware\Directory Opus\dopus.exe" $path | |
} | |
function ForceUpdateCheck() { | |
try { | |
$Env:__ForceUpdateCheck = $True ; pwsh -Command "exit" ; Remove-Item Env:__ForceUpdateCheck | |
} | |
catch { | |
Write-Host "An error occurred:" | |
Write-Host $_ | |
} | |
} | |
# Useful aliases | |
Set-Alias grep findstr | |
Set-Alias touch New-Item | |
Set-Alias cat Get-Content | |
Set-Alias make mingw32-make | |
Set-Alias dopus Set-Location-Directory-Opus | |
Set-Alias pbpaste Get-Clipboard | |
if ($host.Name -eq 'ConsoleHost') { | |
Import-Module PSReadLine | |
# Set options for PSReadLine to show the history of our typed commands | |
Set-PSReadLineOption -PredictionSource History | |
Set-PSReadLineOption -PredictionViewStyle ListView | |
Set-PSReadLineOption -EditMode Windows | |
# Enable CTRL-D to close session | |
Set-PSReadlineKeyHandler -Key Ctrl+d -Function DeleteCharOrExit | |
# With these bindings, up arrow/down arrow will work like PowerShell/cmd if the current command line is blank. | |
# If you've entered some text though, it will search the history for commands that start with the currently entered text. | |
Set-PSReadLineOption -HistorySearchCursorMovesToEnd | |
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward | |
Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward | |
#region Smart Insert/Delete | |
# Edit: Disabled because copy/pasting content with quotes, braces, etc does not quite work | |
# # 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) | |
# } | |
# } | |
# } | |
#endregion Smart Insert/Delete | |
# 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")) | |
} | |
} | |
} | |
# Path to the patterns directory | |
$patternsPath = Join-Path $HOME ".config/fabric/patterns" | |
if (Test-Path -Path $patternsPath) { | |
foreach ($patternDir in Get-ChildItem -Path $patternsPath -Directory) { | |
$patternName = $patternDir.Name | |
# Dynamically define a function for each pattern | |
$functionDefinition = @" | |
function $patternName { | |
[CmdletBinding()] | |
param( | |
[Parameter(ValueFromPipeline = `$true)] | |
[string] `$InputObject, | |
[Parameter(ValueFromRemainingArguments = `$true)] | |
[String[]] `$patternArgs | |
) | |
begin { | |
# Initialize an array to collect pipeline input | |
`$collector = @() | |
} | |
process { | |
# Collect pipeline input objects | |
if (`$InputObject) { | |
`$collector += `$InputObject | |
} | |
} | |
end { | |
# Join all pipeline input into a single string, separated by newlines | |
`$pipelineContent = `$collector -join "`n" | |
# If there's pipeline input, include it in the call to fabric | |
if (`$pipelineContent) { | |
`$pipelineContent | fabric --pattern $patternName `$patternArgs | |
} else { | |
# No pipeline input; just call fabric with the additional args | |
fabric --pattern $patternName `$patternArgs | |
} | |
} | |
} | |
"@ | |
# Add the function to the current session | |
Invoke-Expression $functionDefinition | |
} | |
} | |
# Define the 'yt' function as well | |
function yt { | |
[CmdletBinding()] | |
param( | |
[Parameter()] | |
[Alias("timestamps")] | |
[switch]$t, | |
[Parameter(Position = 0, ValueFromPipeline = $true)] | |
[string]$videoLink | |
) | |
begin { | |
$transcriptFlag = "--transcript" | |
if ($t) { | |
$transcriptFlag = "--transcript-with-timestamps" | |
} | |
} | |
process { | |
if (-not $videoLink) { | |
Write-Error "Usage: yt [-t | --timestamps] youtube-link" | |
return | |
} | |
} | |
end { | |
if ($videoLink) { | |
# Execute and allow output to flow through the pipeline | |
fabric -y $videoLink $transcriptFlag | |
} | |
} | |
} | |
# Oh My Posh | |
if ($env:USE_OH_MY_POSH -eq 'true' -and $Env:TERM_PROGRAM -ne 'vscode') { | |
oh-my-posh init pwsh --config "$env:POSH_THEMES_PATH/nordtron.omp.json" | Invoke-Expression | |
} | |
else { | |
# Vanilla PowerShell | |
Write-Host "Using vanilla PowerShell without oh-my-posh." | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To download to
%USERPROFILE%\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
:Note: This is a Base64 encoded command - the decoded command is below. Use base64decode.org to verify (UTF-16LE encoding)
Input
To get the encoded command I used the following code:
Output