The Object-Oriented Command Shell
Script Compatibility
Code written for PowerShell Core should usually (hopefully) run as is on Windows PowerShell too, but the reverse is often not true.
In your scripts, you can test for which edition of PowerShell is being used:
$PSVersionTable.PSEdition # Will be "Core" or "Desktop"

There are five main Windows PowerShell "hosts" from Microsoft:
PowerShell Console
PowerShell ISE
Visual Studio Code
Windows Admin Center
Powershell Web Access
Information about the hosting process for the PowerShell engine in front of you right now can be displayed by using the built-in $host variable:
$host

PowerShell Core Host Processes
PowerShell Console
Visual Studio Code
To see what version of PowerShell you are running now:
$psversiontable # See the PSVersion property.

To see which versions of PowerShell the current running shell is compatible with:
$PSVersionTable.PSCompatibleVersions

64-bit (x64) versus 32-bit (x86)
To test whether the OS and/or PowerShell are running the 64-bit versions:
[Environment]::Is64BitOperatingSystem
[Environment]::Is64BitProcess

Tips for Executing Commands
Here are some tips for executing commands in PowerShell.
Your New Best Friend: Tab Completion
The key habit to learn in PowerShell is using tab completion. By typing a few letters of a cmdlet, function, parameter, or file, you can press the Tab key to auto-complete the name. This speeds up typing, reduces errors, and prevents fatigue from typing long names.
Tip: If you accidentally hit the Tab key too fast and go past what you wanted, hit Shift-Tab to go backward to the prior options

Put "." in Front of Scripts or Executables in the Current Directory
.\HelloWorld.ps1

Script Execution Policy
If you cannot run any scripts at all, run the following command (you only have to do it once):
Set-ExecutionPolicy -ExecutionPolicy Bypass -Force
Open Script in New Tab
A fast way to open a text file in a new tab in PowerShell ISE is from the command line:
ise .\HelloWorld.ps1
psedit .\HelloWorld.ps1

Run Selection in PowerShell ISE
In PowerShell ISE, if you open a script for editing, you can highlight one or more lines from that script and execute just those highlighted lines.

Running Native Commands
All of the following commands work in PowerShell just like they do in CMD:
ipconfig.exe | findstr.exe /i "gateway"
netsh.exe firewall show config > outfile.txt
notepad.exe boot.ini
.\boot.ini
.\myvbscript.vbs >> outfile.txt
wscript.exe \\server\share\script.vbs -x -y -z
cmd.exe /c mybatchscript.bat
.\mybatchscript.bat
To see what native commands must be run in powershell.exe, not ISE, run:
$psUnsupportedConsoleApplications

Piping ( | ) and Redirection Operators ( >, >>)
When you want to feed the output of one command into a second command as input, use the pipe ("|") operator.
Get-Process | Format-List *

If you want to redirect (">" or ">>") the output of a command to a file, it'll usually work as expected, but it is better to use cmdlets like Out-File and Export-Csv instead.
Get-Service | Export-Csv -Path services.csv

Get-Process | Out-File -FilePath processes.txt -Append

Separate Multiple Commands on One Line with Semicolons
If you want to run multiple commands with a single line, just separate each command with a semicolon. A semicolon at the very end of a line or command is not required.
Getting Help in PowerShell
To get help about the get-help cmdlet itself:
Get-Help

To see a list of all cmdlets, aliases, providers, and help files:
Get-Help *

To see a listing of cmdlets that match a particular pattern:
Get-Help Set-*

Get-Help *loc*

To get more detailed help for a cmdlet, including parameter syntax and examples:
Get-Help -Full Get-Process

To pop up a searchable graphical window to display the help text:
Get-Help Get-Process -showwindow

Update Help
To update the local help files from Microsoft, if you have internet access:
Update-Help -Verbose
HELP and MAN
help about_Aliases
man about_Aliases

Get-Help About_Help Topic
To see a listing of all help files:
Get-Help about*

The following command will open a separate graphical window with the help text, and it includes a search box too:
Get-Help about_Functions

The following command will open a separate graphical window with the help text, and it includes a search box too:
Get-Help about_WMI -ShowWindow

Aliases
An "alias" is an alternative name for a frequently-used cmdlet, function, script, file, or executable.
dir
Get-ChildItem
ls
Get-ChildItem
cls
Clear-Host
echo
Write-Output
type
Get-Content
del
Remove-Item
ps
Get-process
cd
Set-Location
pwd
Get-Location
sort
Sort-Object
cp
Copy-Item
where
Where-Object
?
Where-Object
%
ForEach-Object
kill
Stop-Process
gm
Get-Member
select
Select-Object
To see all the aliases defined in the current shell:
Get-Alias *
To see how a particular alias, like "cd", is mapped:
Get-Alias cd
To create a new alias for notepad.exe named "nn":
New-Alias nn notepad.exe
To change an existing alias to point toward some other target:
Set-Alias nn netsh.exe
To read more about aliases and how to manage them:
help about_Aliases
Objects, Properties, and Methods
Let's get an object that represents the LSASS.EXE process:
$procsses = Get-Process -Name powershell_ise
$Process.Name
$Process.Id
$Process.Company
$Process.Description
$Process.StartTime
$Process.VirtualMemorySize
$Process.Modules #This property has lots of objects inside it!

And a process object also has an interesting and dangerous method:
$Process.Kill() # But don't do it
Get-Member (Alias: gm)
To show properties, methods, and class type:
Get-Process | Get-Member

If you have captured the output of a command to a variable, but you don't know what kind of data it is or what its members are, pipe that variable into get-member:
$x = Get-Item hklm:\
$x | Get-Member

To see the members of the first item in an array and then see the members of the array itself (an array of objects is of type "System.Object[]"):
$output = dir c:\
$output | Get-Member # Members of the first item in array

Get-Member -InputObject $output

Drives and Environment Variables
"Drives" are more than just disk volumes. To see your currently available drives:
Get-PSDrive

dir hkcu:\

dir env:\

$env:PATH
$env:COMPUTERNAME
$env:SYSTEMROOT

To see your currently installed providers and their corresponding drive names:
Get-PSProvider

Cmdlets for moving around in drives of any type, from any provider, with full support for relative path addressing (using "." and "..") and tab completion:
get-location (aliases: gl, $pwd)
set-location (aliases: sl, cd, chdir)
Get-Location
$pwd
Set-Location hkcu:\software\microsoft\windows\
cd env:\
C:

Cmdlets for manipulating items in drive containers:
new-item (alias: ni, but see also mkdir)
remove-item (aliases: ri, del, rm, rd, rmdir)
move-item (aliases: mi, move, mv)
copy-item (aliases: cpi, copy, cp)
rename-item (aliases: rni, rn, ren)
New-Item $HOME\file.txt -Type File

New-Item $HOME\Testfolder -Type Directory

New-Item HKCU:\Software\somekey -Type key

New-Item HKCU:\Software\somekey\somevalue -Type value

del HKCU:\Software\somekey\somevalue # Delete
ren hkcu:\software\somekey otherkey # Rename
Cmdlets for accessing the properties of an item or multiple items:
get-item (alias: gi)
get-childitem (aliases: gci, dir, ls)
set-item (alias: si)
clear-item (alias: ci)
Get-Item Env:\SystemRoot

Get-Item function:\more

Get-Item C:\Windows | Get-Member

Get-ChildItem C:\Windows\*.exe

Get-ChildItem \\localhost\C$

dir Cert:\CurrentUser\Root

Set-Item Variable:\fishtype -Value "Trout!"
Clear-Item Variable:\fishtype

Cmdlets for accessing an individual property of an item:
get-itemproperty (alias: gp)
set-itemproperty (alias: sp)
clear-itemproperty (alias: clp)
rename-itemproperty (alias: rnp)
move-itemproperty (alias: mp)
remove-itemproperty (alias: rp)
copy-itemproperty (alias: cpp)
Get-ItemProperty $HOME | Format-List *

Get-ItemProperty $HOME -Name CreationTime

Cmdlets specifically for working with strings and the contents of files:
get-content (aliases: gc, type, cat)
set-content (alias: sc)
add-content (alias: ac)
clear-content (alias: clc)
Get-Content $env:windir\inf\volsnap.inf

Get-Content Variable:\HOME

Get-Content .\somefile.txt -wait # Similar to 'TAIL.EXE -F'
Get-Service | Set-Content c:\services.txt

Creating New PowerShell Drives
To map the "share:" drive to the "\localhost\c$" UNC network path:
New-PSDrive -Name share -PSProvider FileSystem -Root \\localhost\C$
cd share:

Environment Variables
In Powershell to see all enviroment variables:
Get-ChildItem env:\
dir env:\

$env:PATH
$env:SYSTEMROOT

To create a new environment variable:
New-Item env:\VERYABLE -value "Flash Gordon"

Set-Item env:\VERYABLE -Value "Wonder Woman" # To change an environment variable that already exists
Remove-Item Env:\VERYABLE # To delete an environment variable

To use an environment variable in a string you are constructing:
$x = "My user name is $env:USERNAME, and I'm free!"

Built-In PowerShell Variables
There are other variables built into Powershell that we see very frequently.
help about_Automatic_Variables

Some of the more commonly used automatic variables are the following:
$? -> Contains $true if last operation succeeded, $false otherwise.
$_ -> Contains the current object in a pipeline.
$args -> Contains an array of the parameters passed to a function or script.
$false -> Contains the Boolean value of False ([Int] 0, or $null).
$home -> Contains the user's home directory path.
$input -> Contains objects piped into a function, filter, or script.
$lastexitcode -> Contains the error code of the last Win32 executable execution.
$matches -> Contains matches to a regular expression search.
$null -> Contains nothing and cannot have contents.
$pshome -> Contains the directory path where PowerShell is installed.
$profile -> Full path to your profile script.
$OFS -> Output Field Separator, used as the default delimiter when converting arrays to strings, and is a single space character by default.
$true -> Contains the Boolean value of True ([Int] 1, or -not $null).
Your Profile Script(s)
Your own functions, aliases, variables in memory will exist only in the current session; hence, if you close PowerShell and open it again, these items are lost. By adding them to your profile, however, they can be reloaded every time you open PowerShell.
$PROFILE | Format-List * -Force

$PROFILE.AllUsersAllHosts
$PROFILE.AllUsersCurrentHost
$PROFILE.CurrentUserAllHosts
$PROFILE.CurrentUserCurrentHost

Note that the CurrentUserCurrentHost property is the default for the $profile variable, so these two commands will produce the same output:
$PROFILE.CurrentUserCurrentHost
$PROFILE
"AllUsers" scripts run for anyone using PowerShell on the computer. "CurrentUser" scripts only run for the currently logged-in user and have unique paths for each user. But what do "CurrentHost" and "AllHosts" mean? And what is a PowerShell "host"?
In PowerShell, a host is the environment where PowerShell runs, like the PowerShell console, ISE, or any app using PowerShell. It acts as a bridge between the user and PowerShell.
CurrentHost: Affects only the current PowerShell session you're using, like the console or ISE.
AllHosts: Affects all PowerShell sessions on the machine, no matter which one you're using.
Use the $host
variable to see details about the current PowerShell engine.
$host
$host.UI.RawUI

Later scripts can change earlier ones since they run in order. This lets admins set global settings and users adjust them if needed. Group Policy can still manage these scripts.
Functions, Cmdlets, and Modules
Functions and cmdlets are code blocks with specific names. They usually come from modules and can be run in the command shell or scripts by using their names.
Functions
To see a list of the functions available in the current shell:
Get-ChildItem Function:\

As you can see from the list of functions, "help", "more", and even "C:" are all functions. What does the "C:" function do? It simply executes "Set-Location C:".
To see the contents of a function, such as the mkdir function:
Get-Content Function:\mkdir

Cmdlets
A cmdlet is a type of command in PowerShell, like Get-Process. Cmdlets are often compiled into .NET binary DLLs. You can think of a cmdlet as a compiled function, but it’s not stored in the Function:\ drive; it’s usually part of a module as a DLL.
Modules
A "module" is a group of files that includes cmdlets, functions, and other related resources. They are usually stored in folders named after the module. Modules help organize code into easy-to-manage parts.
A module's main file can be a PowerShell script (.psm1), a compiled binary (.dll), or a manifest file (.psd1).
To see the default folders where PowerShell searches for modules:
$env:PSModulePath -split ";"

PowerShell first checks the user's local profile for a module, then looks in system-wide locations. Users can create and use their own modules without being local Administrators, but changing system-wide modules needs admin rights.
Using Modules
When a module is loaded, its cmdlets, functions, aliases, drives, and variables can be used. A module can load another module, forming a parent-child relationship. The first module loaded is the "root module," and any modules it loads are "nested modules."
To see which parent or "root" modules are currently loaded:
Get-Module

To see all currently loaded modules, including the nested modules:
Get-Module -All

To see which root modules are available for use, loaded or otherwise:
Get-Module -ListAvailable

To see all available root and nested modules, including their folder paths:
Get-Module -ListAvailable -All

To load or import a module to make its cmdlets and functions available for use:
Import-Module AppLocker
A module can also be loaded by providing the full path to it:
Import-Module .\MyScriptModule.psm1

To see the commands made available by a particular module:
Get-Command -Module AppLocker

Dot-Sourcing Function Libraries (Deprecated Technique)
Dot-sourcing loads a function into PowerShell but is outdated. Using modules is now recommended.
Dot-sourcing a script runs it in the current scope, like typing each line manually. If the script only has functions, they're added to memory without running. It's an alternative to importing a .PSM1 module.
To dot-source a script containing functions you want to load into the function:\ drive:
. c:\folder\library.ps1
. .\libraryscript.ps1
. \\server\share\script.ps1
The PowerShell Gallery
The PowerShell Gallery (www.PowerShellGallery.com) is the main site for PowerShell modules and scripts. It has code from Microsoft, third parties, and community members, and is supported by Microsoft.
You can quickly search the PowerShell Gallery directly in PowerShell, similar to using "apt-cache search" on Linux.
To list the available modules and scripts from the Gallery (requires internet access):
Find-Module
Find-Script
To download and save a module or script for testing (including DSC modules):
Save-Module -Name SomeModule -Path C:\SomeLocalFolder
Save-Script -Name SomeScript -Path C:\SomeLocalFolder
To install a script or module for all users, you need admin rights or the right permissions to access certain system folders.
To download and save a module to your personal folder ($env:USERPROFILE\Documents\WindowsPowerShell\Modules
) without needing admin rights:
Install-Module -Scope CurrentUser -Name SomeModule
To download and save a script for your own personal use into ($env:USERPROFILE\Documents\WindowsPowerShell\scripts
), without needing admin rights:
Install-Script -Scope CurrentUser -Name SomeScript
To download and save a module for all users in $env:ProgramFiles\WindowsPowerShell\Modules
, you need to be an Admin.
Install-Module -Scope AllUsers -Name SomeModule
Install-Module -Name SomeModule
To download and save a script for all users in $env:ProgramFiles\WindowsPowerShell\Scripts
, you need to be an Admin.
Install-Script -Scope AllUsers -Name SomeScript
Install-Script -Name SomeScript
To list all modules and scripts installed from the PowerShell Gallery using Install-Module or Install-Script:
Get-InstalledModule
Get-InstalledScript
To update all modules and scripts installed from the PowerShell Gallery using Install-Module or Install-Script in the past:
Update-Module
Update-Script
To update a specific module or script:
Update-Module -Name SomeModule
Update-Script -Name SomeScript
To uninstall a module or script that was installed from the PSGallery:
Uninstall-Module -Name SomeModule
Uninstall-Script -Name SomeScript
Last updated