- install:
brew cask install powershell
- start:
pwsh
- typical profile location:
$HOME/.config/powershell/Microsoft.PowerShell_profile.ps1
to run scripts written locally, but verify signatures on scripts pulled from remote locations:
Set-ExecutionPolicy RemoteSigned
note: powershell has six possible profile locations; let the shell tell you what it's using.
- check if profile exists:
Test-Path $profile
- create a new profile if one doesn't exist:
New-Item -Path $profile -Type File -Force
- list all profile locations:
$profile | Format-List -Force
- open current profile in default editor:
ii $profile
powershell terminal and readline colors may conflict with other terminal colorschemes, such as zenburn, solarized, etc. the below snippet should be zenburn-compatible, but at least provides example code for customizing a powershell profile.
#!/usr/bin/env pwsh
Set-PSReadlineOption -Colors @{
Command = "`e[37m";
Comment = "`e[37m";
ContinuationPrompt = "`e[37m";
DefaultToken = "`e[37m";
Emphasis = "`e[37m";
Error = "`e[37m";
Keyword = "`e[37m";
Member = "`e[37m";
Number = "`e[37m";
Operator = "`e[37m";
Parameter = "`e[37m";
Selection = "`e[37m";
String = "`e[37m";
Type = "`e[37m";
Variable = "`e[37m"
}
$Host.PrivateData.ErrorForegroundColor = "DarkRed"
$Host.PrivateData.WarningForegroundColor = "DarkYellow"
$Host.PrivateData.DebugForegroundColor = "DarkCyan"
$Host.PrivateData.VerboseForegroundColor = "Gray"
$Host.PrivateData.ProgressForegroundColor = "DarkCyan"
most terminal emulators that aren't powershell will default to cmd.exe
, which can be used to launch various tui shells that are installed:
bash
usually launches the bash binary that ships with wsl 2 that is installed as part of the docker desktop installation.powershell
launches...powershell.'C:\Program Files\Git\bin\bash.exe'
will launch the bash binary that ships with Git for Windows.
# open git bash in powershell session (v. a new window).
Set-Alias -Name git-bash -Value "C:\Program Files\Git\bin\bash.exe"
note: the location of bash.exe
may be be different; salt to taste.
this is...interesting, but how it seems to work. say you'd like to alias to a command with arguments in your profile. a wrapper function is a way to handle this:
function fooBarWrapperFunction {
foo -myArg bar
}
Set-Alias -Name foo-bar -Value fooBarWrapperFunction
useful when there's a steady reuse of long arguments for a particular shell call.
- linting: psscriptanalyzer
- testing: pester
version check: $PSVersionTable.PSVersion
or $host.Version
.
bash | powershell |
---|---|
clear |
cls |
ls |
Get-ChildItem |
whoami |
$env:UserName |
pwd |
$pwd |
cd your/path |
Set-Location your\path |
history |
Get-History |
sha , shasum , etc. |
Get-FileHash |
rm |
Remove-Item |
mv |
Move-Item |
man |
Get-Help |
cp |
Copy-Item |
less , more |
Out-Host -paging |
cat |
Get-Content |
mkdir |
New-Item -Path . -Name "foo" -ItemType "directory" |
touch |
New-Item -Path . -Name "foo" -ItemType "file" |
wget , curl , etc. |
Invoke-WebRequest |
which |
(Get-Command foo -ErrorAction “SilentlyContinue”).Path |
"grepping" in powershell is a little more interesting. for example, to get results similar to grep -Rn foo ./
, run:
Get-ChildItem -Recurse *.* `
| Select-String -Pattern 'foo' `
| Select-Object -Unique Path
to import functions, etc. from another script, use the dot operator at the top of target script. for example, add . path\to\source\script.ps1
to the top of the target script to import the script located at path\to\source\script.ps1.
sourcing .bashrc
(and friends), declaring variables, and calling unset
is typically how the environment is reloaded in bash. powershell has refreshenv
to handle all that, which is an alias to Update-SessionEnvironment
.
to elevate to an interactive admin shell, which will open in a new window (...), use Start-Process powershell -Verb RunAs
.
to run a command with admin rights as part of a script, use the -ArgumentList
parameter to force a confimation dialogue, then run the list of arguments in a new subshell (which will exit on completion):
function install_psscriptanalyzer {
Start-Process `
-FilePath "powershell" `
-Verb runAs `
-ArgumentList "Install-Module -Name PSScriptAnalyzer -Force"
}
For reference, the $_
is the same as $PSItem
, which is a reference to the current item in a powershell pipeline. in addition to the below debugging example, you can access the current item in an iterator in a functional way like so: 1,2,3 | %{ write-host $_ }
or 1,2,3 | %{ write-host $PSItem }
.
to manage functions as background processes, the following snipped might be useful:
$functions = {
# notice that -Bar is the second argument.
function wrapper {
Param(
[string[]] $Foo,
[string[]] $Bar
)
Write-Host "${Bar}" # heads up, Write-Host might not be the best call here.
}
}
function main {
# notice that -Bar is the first argument.
$job = Start-Job `
-InitializationScript $functions `
-ScriptBlock { wrapper -Bar "oow" -Foo "woo" }
# wait on all jobs.
Get-Job | Wait-Job
# get output from specific job
Receive-Job -Id $job.Id | Write-Host
# remove all jobs in session.
Get-Job | Remove-Job
}
main
powershell supports terminating and nonterminating errors. the key difference is that a terminating error will halt execution, where a nonterminating error will simply print an error message and allow execution to continue. use flags such as -ErrorAction
in order to achieve desired behavior.
powershell uses the Set-PSBreakpoint
cmdlet:
$ pwsh
PS /Users/username> Set-PSBreakpoint -Line 221 ./your_script.ps1
on the next run of your_script.ps1
from the interpreter, execution will pause at the specified line. To list all breakpoints, use Get-PSBreakpoint
. To clear a specific breakpoint, use Remove-PSBreakpoint
. To clear all breakpoints, chain the two: Get-PSBreakpoint | Remove-PSBreakpoint
.
also, inspecting an object can be done the following way, demonstrated using an Exception
object found inside a try/catch block: $_.Exception | Select -Property *
.
powershell supports using anonymous functions as well as strings via New-Item
and the function:
drive for some light reflection:
function dynamicFunction {
$name = 'foo'
# can't pass in parameter to anonymous function; outputs empty string.
$parametrizedMessage = 'bar'
$code = { param($pm) Write-Host -ForegroundColor Yellow $pm }
$null = New-Item `
-Force
-Path function: `
-Name "script:anonymous-$name" `
-Value $code
# can *set* parameter via string interpolation; outputs "baz."
$interpolatedMessage = 'baz'
$null = New-Item `
-Force `
-Path function: `
-Name "script:interpolated-$name" `
-Value "Write-Host -ForegroundColor Yellow '$interpolatedMessage`"
}
- install:
wsl --install
- help:
wsl --help