<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!

PS1 (ch 1-4)

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 |

PS2 (ch 5-7)

| 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. |

PS3 (ch 8-10)

| 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 ServiceControllerobject, 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 |

PS4 (ch 11-15)

| 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. |

PS5 (ch 17-19)

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 aString`.

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 Strings, 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. |

Scripting (ch 21)

| 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 |