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.

Alias
Cmdlet

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