- 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 RemoteSignednote: 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:
bashusually launches the bash binary that ships with wsl 2 that is installed as part of the docker desktop installation.powershelllaunches...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 fooBarWrapperFunctionuseful 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 Pathto 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
}
mainpowershell 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.ps1on 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