PowerShell Notes/Cheatsheet

This is a collection of notes and code fragements I have been collecting for years. The info is grouped as follows:

Function Prototype

Param([Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)][string]$width,
	[Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)][string]$height)
	<#
		.Synopsis
			Does Something
		.Description
			Does Something in more detail
		.Parameter width
			width of window
		.Parameter height
			height of window
		.NOTES
			Author: Tom Willett
			Date: 3/2/2022
	#>
	begin {
	}
	process {
		Code
	}
	end {
	}
}

Variables

# get current execution environment info
$ScriptPath = $MyInvocation.MyCommand.Path
$ScriptDir = split-path -parent $ScriptPath
$ScriptName = [system.io.path]::GetFilenameWithoutExtension($ScriptPath)

# Use [System.IO.Path] to get parts of path
[System.IO.Path]::GetFilename("")
[System.IO.Path]::GetFilenamewithoutextension("")
[System.IO.Path]::GetDirectoryName("")
[System.IO.Path]::GetExtension("")

# environment variables
$env:computername 
#Profile Path
$Profile 
#PowerShell Version
$PSVersionTable
# To require Administrator
Requires -RunAsAdministrator
# Windows Terminal config JSON
$env:LocalAppData\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json

Error Handling

# -ErrorAction SilentlyContinue
$ErrorActionPreference = "SilentlyContinue"
"continue"
"stop"
"inquire"

#try catch blocks
ry {
   $wc = new-object System.Net.WebClient
   $wc.DownloadFile("http://www.contoso.com/MyDoc.doc","c:\temp\MyDoc.doc")
}
catch [System.Net.WebException],[System.IO.IOException] {
    "Unable to download MyDoc.doc from http://www.contoso.com."
}
catch {
    "An error occurred that could not be resolved."
	Write-Host $_.ScriptStackTrace
}

#trap
function TrapTest {
    trap {"Error found: $_"}
    nonsenseString
}

TrapTest

#trap specific error
trap [System.Management.Automation.CommandNotFoundException] {
  "Command error trapped"
}
nonsenseString

#trap with continue (break can also be used)

function continue_example {
    trap {
        "Error trapped"
        continue
    }
    1/$null
    "Function completed."
}

continue_example

Object Creation

$report = @()
$temp = "" | Select Computer, Username

$temp = [pscustomobject]@{
	UserName = "Tom"
	Computer= "Computername"
}

$data = new-object -typename psobject
$data | add-member -notepropertyname 'Time' -NotePropertyValue $_._time
$data | add-member -notepropertyname 'Connecting IP' -notepropertyvalue $_.'Connecting IP'
$data | add-member -notepropertyname 'Status Code' -notepropertyvalue $_.'Status Code'

#convert multi-line string to an array
$s = 'Line 1
Line 2
Line 3'

$t=$s.split("`r`n") -replace "`r`n",""

File operations

# To read a whole file in as one string
[Io.File]::ReadAllText($path)
# get-content reads it in as an array of strings.
#
# To write byte code to file
$var_code | Set-Content am-malware.bin -Encoding Byte
# To read a file as a stream of bytes
$bytes = [byte[]]$byte = get-content -Encoding byte -Path $filename

Add-Type -assembly "System.IO.Compression"

$wor = [IO.MemoryStream][Convert]::FromBase64String('')
$boo = New-Object System.IO.Compression.DeflateStream($wor,[IO.Compression.CompressionMode]::Decompress)
$UnFiBy = New-Object Byte[](587776)
$boo.Read($UnFiBy, 0, 587776) | Out-Null
$UnFiBy| set-content E:\malware\oln\adsfmalware.bin -encoding byte 

#To remove beginning and trailing space use .trim()
#to remove first line of file  | select -skip 1
#to remove any line(s) (cat .\histo.txt)[(1..1)+(3..595)] remove line 1 and 3 - lines are zero based

URI Manipulation

#Execute from web $url
iex ((new-object net.webclient).DownloadString($url))

#host name
([system.uri]'http://something.net').host
#tld 
((([system.uri]'http://something.net').host.split('.'))[-2,-1]) -join '.' 

Data Manipulation

#histogram
$m | select "File Name" | group-object "File Name" | select count, name | sort count -descending | select -first 25
#
# unique items in array
$m | select -uniq
#
# Return only match from sls
| select -exp matches | select value
# or for cleaner output
(gc test.txt | sls 'something' | select -exp matches).value
# Using -match in place of sls
gc $fl | %{if($_ -match '[0-9a-f]{40}'){$matches[0]}} | out-utf8 tmp.txt
# return captures from sls
| %{$r = $_.matches.groups.captures[1].value + ' - ' + $_.matches.groups.captures[2].value;$r}
# return only line from sls
| select line
# Get only files
gci . *.* -rec -file
#Get NoteProperty names from an object
[system.collections.arraylist]$g = ($s | get-member -membertype 'NoteProperty').name

Encoding/Decoding

#Encode in Base64
[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes(‘This is a secret’))
#Decode Base64
[System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String("VABoAGkAcwAgAGkAcwAgAGEAIABzAGUAYwByAGUAdAA="))
# 'MD5:'
[System.Security.Cryptography.HashAlgorithm]::Create('MD5').ComputeHash([System.Text.Encoding]::UTF8.GetBytes($StringToHash))|%{"{0:X2}" -f $_}
# 'SHA1:'
[System.Security.Cryptography.HashAlgorithm]::Create('SHA1').ComputeHash([System.Text.Encoding]::UTF8.GetBytes($StringToHash))|%{"{0:X2}" -f $_}
# 'RIPEMD160:'
[System.Security.Cryptography.HashAlgorithm]::Create('RIPEMD160').ComputeHash([System.Text.Encoding]::UTF8.GetBytes($StringToHash))|%{"{0:X2}" -f $_}
# 'SHA256:'
[System.Security.Cryptography.HashAlgorithm]::Create('SHA256').ComputeHash([System.Text.Encoding]::UTF8.GetBytes($StringToHash))|%{"{0:X2}" -f $_}
# 'SHA384:'
[System.Security.Cryptography.HashAlgorithm]::Create('SHA384').ComputeHash([System.Text.Encoding]::UTF8.GetBytes($StringToHash))|%{"{0:X2}" -f $_}
# 'SHA512:'
[System.Security.Cryptography.HashAlgorithm]::Create('SHA512').ComputeHash([System.Text.Encoding]::UTF8.GetBytes($StringToHash))|%{"{0:X2}" -f $_}
# 'BCrypt:'
[System.Security.Cryptography.HashAlgorithm]::Create('Bcrypt').ComputeHash([System.Text.Encoding]::UTF8.GetBytes($StringToHash))|%{"{0:X2}" -f $_}

#Time Zone Conversion
$dt = "2020-12-19 23:33"
[System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId($dt,'Eastern Standard Time','UTC')
#Convert Unix Filetime
(([datetime] '1970-01-01Z').ToUniversalTime()).addseconds($unixfiletime)
#Normalize date format
[datetime]::parse($date).tostring('yyyy-MM-dd HH:mm:ss')

#To encode a command for execution
$cmd = "cmd.exe" // whatever
$bytes=[system.text.encoding]::unicode.getbytes($cmd)
$enc = [convert]::tobase64string($bytes)

url encode/decode
Add-Type -AssemblyName System.Web
$Encode = [System.Web.HttpUtility]::UrlEncode($URL) 
$Decode = [System.Web.HttpUtility]::UrlDecode($Encode) 

#hex-to-ascii
[char][byte][convert]::toint16($hex,16)
#dec-to-ascii
[char][byte][convert]::toint16($dec)
#ascii-to-hex
[convert]::tostring([byte][char]$chr,16)
#ascii-to-dec
[byte][char]$chr

#to convert hex in the format 0x34 0x2e
[byte[]]$bytes = ($hex -split ' ')

#convert string to hex
[System.BitConverter]::ToString([System.Text.Encoding]::Default.GetBytes($mystr))

#convert to base64
[System.Convert]::ToBase64String([System.Text.Encoding]::Default.GetBytes($str))
'utf8'
[System.Text.Encoding]::utf8.GetString([System.Convert]::FromBase64String($data))
'unicode'
[System.Text.Encoding]::unicode.GetString([System.Convert]::FromBase64String($data))
'ascii'
[System.Text.Encoding]::ascii.GetString([System.Convert]::FromBase64String($data))

Regex Help

Bitcoin - '(?i)^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$'
Email - '(?i)\b[\w._%+-]+@[\w.-]+\.\w{2,}\b'
Email - ^[a-zA-Z0-9_\-.]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-.]+$
CCregex - (\b3611\d{10}|3[47]\d{13}\b|\b6011[ -]?\d{4}[ -]?\d{4}[ -]?\d{4}\b|\b35\d{2}[ -]?\d{4}[ -]?\d{4}[ -]?\d{4}\b|\b5[1-5]\d{2}[ -]?\d{4}[ -]?\d{4}[ -]?\d{4}\b|\b4\d{3}[ -]?\d{4}[ -]?\d{4}[ -]?\d{4}\b|\b3[0-8]\d{12}\b)')
url - '^((http[s]?|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)(.*)?(#[\w\-]+)?$'
IP - '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
ip - '(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])'
IPv6_regex="^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$"
md5 (?i)[0-9a-f]{32}
sha1 (?i)[0-9a-f]{40}
sha256 (?i)[0-9a-f]{64}
Base64 (?:[A-Za-z0-9+\/]{4}\\n?)*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)
Private Address Filtering
'10\.\d{1,3}\.\d{1,3}\.\d{1,3}'
'192\.168\.\d{1,3}\.\d{1,3}'
'172\.1[6-9]\.\d{1,3}\.\d{1,3}'
'172\.2[0-9]\.\d{1,3}\.\d{1,3}'
'172\.3[0-1]\.\d{1,3}\.\d{1,3}'
mimikatz "eo\.oe\.kiwi|\<3 eo\.oe|mimilib|mimikatz|privilege::debug|sekurlsa::LogonPasswords"

hex digit (?i)[0-9a-f]+
regex options
case insensitive (?i)
multiline (?m)
single line (?s)

#Character classes
.	any character except newline
\w\d\s	word, digit, whitespace
\W\D\S	not word, digit, whitespace
[abc]	any of a, b, or c
[^abc]	not a, b, or c
[a-g]	character between a & g
#Anchors
^abc$	start / end of the string
\b\B	word, not-word boundary
#Escaped characters
\.\*\\	escaped special characters
\t\n\r	tab, linefeed, carriage return
#Groups & Lookaround
(abc)	capture group
\1	backreference to group #1
(?:abc)	non-capturing group
(?=abc)	positive lookahead
(?!abc)	negative lookahead
#Quantifiers & Alternation
a* a+ a?	0 or more, 1 or more, 0 or 1
a{5} a{2,}	exactly five, two or more
a{1,3}	between one & three
a+? a{2,}?	match as few as possible
ab|cd	match ab or cd

.*? match as few as possible

PowerShell Equivilents

ipconfig get-netipconfiguration or get-netipaddress
ping test-netconnection
tracert test-netconnection -traceroute
nslookup resolve-dnsname
route get-netroute
netstat get-nettcpconnection
arp -a get-netneighbor

Add Field to CSV

$s = Import-Csv file.csv
$s | Select-Object *,@{Name='column3';Expression={'setvalue'}} | Export-Csv file.csv -NoTypeInformation

Passwords

$password = ConvertTo-SecureString "MyPlainTextPassword" -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ("username", $password)
or
get-credential