# PS Remoting

## General

* `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

```powershell
# Enter interactive prompt on remote system for one-time use
Enter-PSSession -ComputerName ws01.lab.local

# Enter previously created session
$Sess = New-PSSession -ComputerName ws01.lab.local
Enter-PSSession -Session $Sess

# With credentials
# With GUI access
$cred = Get-Credential
Enter-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

```powershell
# Execute command or scriptblock
Invoke-Command -Scriptblock {$ExecutionContext.SessionState.LanguageMode} -ComputerName (Get-Content hosts.txt)

# Execute scripts from files
Invoke-Command -FilePath C:\scripts\Get-PassHashes.ps1 -ComputerName (Get-Content hosts.txt)

# Execute locally loaded function on remote machines
Invoke-Command -Scriptblock ${function:Get-PassHashes} -ComputerName (Get-Content hosts.txt)

# Pass arguments. Can only be used for positional arguments
Invoke-Command -Scriptblock ${function:Get-PassHashes} -ComputerName (Get-Content hosts.txt) -ArgumentList

# Execute "stateful" commands using Invoke-Command
$Sess = New-PSSession -ComputerName ws01.lab.local
Invoke-Command -Session $Sess -ScriptBlock {$Proc = Get-Process}
Invoke-Command -Session $Sess -ScriptBlock {$Proc.Name}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://wiki.bufu-sec.com/active-directory/lateral_movement/ps_remoting.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
