<aside> <img src="/icons/info-alternate_yellow.svg" alt="/icons/info-alternate_yellow.svg" width="40px" /> PowerShell is a powerful and versatile scripting language and automation framework developed by Microsoft. It was designed specifically for managing and automating tasks within the Windows operating system environment. With a combination of command-line shell capabilities and a scripting language, PowerShell provides administrators and developers with a robust tool for managing system configurations, executing administrative tasks, and interacting with various components of the Windows ecosystem.
</aside>
Here is a quick-reference of some of the useful commands we’ve learned. A few particularly important ones are highlighted.
💡 While PS is generally case-insensitive, I’ve included capitalization for improved readability. Remember that you don’t need to always type the full parameter name either: you can type just enough letters to unique identify the parameter you want. (Tip: if you hit tab
to auto-complete and there’s only one option that finishes the parameter name, you have typed enough letters!)
✉️ If you notice a gap or error, please let me know!
check what version of PowerShell you’re running | $PSVersionTable |
---|---|
access help to learn more about commands | help abc where abc can be replaced with any name (or partial name: use the * wildcard!). |
help
is technically an alias: the actual command is Get-Help
.
Useful parameters to add on: -detailed
, -examples
, -full
, -online
, or -ShowWindow
to get the results in a separate window.
We can also zoom in on a specific parameter:
e.g. to learn more about the recurse
parameter used in the Get-ChildItem
command, we can type help Get-ChildItem -parameter recurse
. |
| update the help to make sure you’ve got the latest info | Update-Help
|
| find a specific command, or discover commands related to a specific object or action | Get-Command abc
where abc
is the name (or partial name) of a command.
We can also add parameters like -noun abc
or verb -xyz
to be a bit more specific in our search.
*
is a wildcard for zero or more characters.
?
is a wildcard for exactly one character. |
| see aliases, which are nicknames for PowerShell commands | gal
or Get-Alias
|
| get a helpful GUI that will assist in building a complex command | Show-Command abc
where abc
is the command we want to build; or run the command with no parameter to see a list of all commands. |
| change drives | cd hklm:
where hklm
can be replaced with any drive name. (Type in Get-PSDrive
to see a list of all drives in your current session, like your file system and Windows registry.) |
| list the contents of the specified item (e.g. view the contents of a file) | Get-Content filename.txt
where filename.txt
can be replaced with the actual item name. |
| launch the Integrated Scripting Environment, which has Intellisense and a command explorer | ise
|
| see a list of running processes | Get-Process
A related command is Stop-Process
. Be very careful with Stop-Process
! |
| --- | --- |
| convert output into a CSV file | commandXYZ | Export-CSV filename.csv
where commandXYZ
is a command or a string of commands and filename.csv
is a name of your choosing.
Export-CSV filename.csv
is doing roughly the same thing as the combination ConvertTo-CSV | Out-File filename.csv
.
We can “read” existing CSV files with Import-CSV filename.csv
. |
| compare two items to see if there are differences | diff
|
| find out what a cmdlet will do, without actually running it | Add the -WhatIf
parameter. (Not all cmdlets support this parameter.) |
| force the shell to ask you to confirm before executing a cmdlet | Add the -confirm
parameter. (Not all cmdlets support this parameter.) |
| add new cmdlets to the shell using snapins | Find modules usingGet-PSSnapin -registered
.
Load them using Add-PSSnapin -name abc
where abc
is the name of the snapin.
Discover what’s in a snapin using Get-Command -PSSnapin abc
where abc
is the name of the snapin. |
| add new cmdlets using modules | Find modules using Get-Module -ListAvailable
.
Load them using Import-Module -Name abc
where abc
is the name of the module.
Discover what’s in a module using Get-Command -Module abc
whereabc
is the name of the module. |
| figure out what type of object a command returns, and what properties it has | some-command | Get-Member
where some-command
is a command (or a chain of piped commands).
gm
is an alias for Get-Member
. |
| --- | --- |
| sort the output by a specific property (or multiple comma-separated properties) | Sort-Object property1,property2
A useful parameter to add is -descending
if you want to sort in biggest-to-smallest order instead. |
| list which properties an object we want to see | Select-Object
, or just Select
e.g. Get-Process | Select Name,ID,VM,PM
We can list existing properties, or include hash tables to select custom properties.
An interesting parameter is -expand
, which effectively lets us choose what type of object is returned. For example, the command Get-Service | Select -expand name
.
Get-Service
normally returns a ServiceController
object, but by adding this parameter, we’re asking it to just output the name
property instead, which is a String
. This is really useful when we’re chaining commands together, and the receiving command only accepts certain types of objects. |
| show the results in a table | some-command | Format-Table *
Instead of the *
, which shows all properties, we can list specific property names separated by commas, or drop the parameter completely to show the default properties.
We can add-GroupBy
to show the results organized into groups containing objects with the same value for a specific property (e.g. -GroupBy Status
). Remember this only works cleanly if the results are also sorted by the same property.
We can add -wrap
to wrap long-values onto the next line, instead of truncating them. |
| show the results in a list | some-command | Format-List *
The *
will show every property: we can add hash tables, and/or list specific property names instead. |
| show results in a wide table displaying just one property | Format-Wide
e.g. Get-Process | Format-Wide name -col 4
takes the results of Get-Process
, and shows us only the name
property, organized into 4 columns.
-col
is a truncated version of the parameter named -column
. This is allowed because no other parameters start with the letters col
. |
| see the results in a separate window, with interactivity like sorting | some-command | Out-GridView
|
| filter results of a command | one way is to use the -filter
parameter, if a command supports it:
Get-ADComputer -filter "Name -like '*DC*'"
Alternatively, we can pipe into the Where-Object
command:
Get-Service | Where-Object -filter {$_.Status -eq 'Running'}
which is the same as:
Get-Service | Where {$_.Status -eq 'Running'}
or even:
`Get-Service | Where Status -eq 'Running’` |
---|---|
learn more about -eq and other useful comparison operators |
help about_comparison_operators |
set up a WinRM listener | Enable-PSRemoting |
start a 1:1 remoting session | Enter-PSSession -computerName computerABC where computerABC is the name of the computer you’re connecting to. |
When you’re done, run Exit-PSSession
. |
| start a 1:many remoting session | Invoke-Command
e.g.
Invoke-Command -computerName server1,server2 -command { Get-EventLog Security -newest 200 }
|
| see the classes within a specific namespace | Get-WMIObject
e.g.
Get-WmiObject -namespace root\\CIMv2 -list | where name -like '*desk*'
|
| learn more about a specific class | Get-WmiObject -class win32_desktop
where win32_desktop
can be replaced with any class name.
(-namespace
is optional: root\\CIMv2
is the default.)
or
Get-CimInstance -ClassName win32_desktop
|
| create a local job | start-job -scriptblock { dir }
where dir
can be replaced with ANY valid command!
or, add -asJob
to any command that supports it, like Get-WMIObject
and Invoke-Command
. |
| view jobs and their status | Get-Job
|
| view the results of a job | Receive-Job -id 42
where 42
is the Job ID.
We can add -keep
to this command if we want to be able to review the results again in the future. |
check my execution policy | Get-ExecutionPolicy |
---|---|
learn more about security | Help about_signing |
change your execution policy | Set-ExecutionPolicy |
create a variable and give it a value | $xyz = "SERVER-ABC" where xyz is the variable name and SERVER-ABC is the value of that variable. |
Remember, a single quote ('
) treats the string within literally, but a double quote ("
) does not: which means we can include references to other variables!
e.g. execute the following commands and note the difference between $literal
and $double
:
`$test = 'abc'
$literal = 'the contents are $test' $literal
$double = "the contents are $test"
$double| | include a PS command within a string | We can create a subexpression using the
$()syntax. Anything within the parentheses will be run as a PowerShell command, instead of treated like a
String`.
e.g. $firstname = "The first name is $($services[0])"
|
| create a variable of a specific type | [int]$number = Read-Host "enter a number"
where int
is the data type we want the variable to hold. |
| access the contents of a variable | $xyz
where xyz
is the name of the variable
There are lots of other properties and methods that we can use with variables containing String
s, including:
.length
.toUpper()
.toLower()
.replace()
|
| save multiple objects to a single variable | Simply include commas between each object.
e.g. $var = 'abc','def','ghi'
|
| access a specific element within a variable that contains multiple | Use square braces. Remember, we start counting at 0, so to access the first element:
$var[0]
And to access the 3rd element:
$var[2]
You can also use this trick to access elements starting at the end of the objects. e.g. to access the last element we’d type $var[-1]
and to access the 3rd last we’d type $var[-3]
.
AND: we can combine this with the methods of the contained objects, like this:
$var[0].toLower()
|
| see how many elements are contained within a variable | $variableName.count
|
| loop through the elements within a variable | To do this, we can use ForEach-Object
. For example
$varName | ForEach-Object { $_.ToLower() }
Another approach, if we’re interested in one specific property, is using Select-Object
.
$varName | Select-Object length
|
| get input from the user | Read-Host
|
| print a message to the console | Write-Host
We can use the -foregroundColor
and -backgroundColor
parameters to make this more colourful, too.
We shouldn’t use this for formatting, debugging messages, etc, so really this won’t be used much “in real life”. Some related commands you will use more often include Write-Warning
, Write-Verbose
, Write-Debug
, Write-Error
, and Write-Information
. |
| add a parameter block to a script | Add something in this format to the start of your script:
param ( $computername = 'localhost', $drivetype = 3 )
Default values are not required. |
| --- | --- |
| add a multi-line comment | <# comments here #>
|
| check the syntax for comments | help about_comment_based_help
|