psexec on steroids, enabled by default from Server 2012
Might need to enable it on Desktop, admin privs required -> Enable-PSRemoting
Opens elevated shell on target if admin creds used
Two types:
One-to-one
One-to-many
One-to-One - PSSession
Interactive
Runs in new process (wsmprovhost)
Stateful
# Enter interactive prompt on remote system for one-time useEnter-PSSession-ComputerName ws01.lab.local# Enter previously created session$Sess =New-PSSession-ComputerName ws01.lab.localEnter-PSSession-Session $Sess# With credentials# With GUI access$cred =Get-CredentialEnter-PSSession-ComputerName ws01.lab.local -Credential $cred# Without GUI access$password =ConvertTo-SecureString"MyPlainTextPassword"-AsPlainText -Force$cred =New-Object System.Management.Automation.PSCredential ("username", $password)Enter-PSSession-ComputerName ws01.lab.local -Credential $cred# Create persistent environment on remote system to be used in subsequest Invoke-Command calls or entered later with Enter-PSSession. Useful for scripts
New-PSSession-ComputerName ws01.lab.local
One-to-Many - Fan-out Remoting
Non-interactive
Executes commands in parallel
Run commands and scripts on
multiple remote computers
in disconected sessions
as background jobs
Good for pass-the-hash attacks and password spraying
# Execute command or scriptblockInvoke-Command-Scriptblock {$ExecutionContext.SessionState.LanguageMode} -ComputerName (Get-Content hosts.txt)# Execute scripts from filesInvoke-Command-FilePath C:\scripts\Get-PassHashes.ps1-ComputerName (Get-Content hosts.txt)# Execute locally loaded function on remote machinesInvoke-Command-Scriptblock ${function:Get-PassHashes} -ComputerName (Get-Content hosts.txt)# Pass arguments. Can only be used for positional argumentsInvoke-Command-Scriptblock ${function:Get-PassHashes} -ComputerName (Get-Content hosts.txt) -ArgumentList# Execute "stateful" commands using Invoke-Command$Sess =New-PSSession-ComputerName ws01.lab.localInvoke-Command-Session $Sess -ScriptBlock {$Proc =Get-Process}Invoke-Command-Session $Sess -ScriptBlock {$Proc.Name}