# PowerShell Remoting (PS Remote)

## Overview&#x20;

Windows PowerShell Remoting. Using the WS-Management protocol, Windows PowerShell remoting lets you run any Windows PowerShell command on one or more remote computers.

## Authentication

{% embed url="https://learn.microsoft.com/en-us/windows/win32/winrm/authentication-for-remote-connections" %}

{% hint style="info" %}
The following list contains a list of what occurs when a script or application runs under the default credentials:

* [_Kerberos_](https://docs.microsoft.com/en-us/windows/win32/winrm/windows-remote-management-glossary) is the default method of authentication when the client is in a domain and the remote destination string is not one of the following: localhost, 127.0.0.1, or \[::1].
* [_Negotiate_](https://docs.microsoft.com/en-us/windows/win32/winrm/windows-remote-management-glossary) is the default method when the client is not in a domain, but the remote destination string is one of the following: localhost, 127.0.0.1, or \[::1].
{% endhint %}

### Specifying credentials

#### Credentials through PowerShell

{% code overflow="wrap" %}
```powershell
$passwd = ConvertTo-SecureString "Password123" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ("lab\logagent", $passwd)
```
{% endcode %}

#### Get-Credentials

Will popup a promtp to enter user credentials

```powershell
$creds = Get-Credential
```

### Trusted hosts

Windows by default has an empty **TrustedHosts** list, a list that contains those remote computers (hosts) that you can remotely manage from a client without authentication.

{% hint style="info" %}
To run PowerShell commands on a device from a remote computer, we have to add the remote machine to the trusted hosts list of the host machine.
{% endhint %}

#### Lazy: Allow all

```powershell
Set-Item WSMan:\localhost\Client\TrustedHosts * -Force
```

#### Specify a host

```powershell
Set-Item WSMan:localhost\client\trustedhosts -value ServerDC -Force
```

## Enumerating for WinRM administrator access

#### Get all AD computers

```powershell
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher.Filter = "(&(sAMAccountType=805306369))"
$Computers = $objSearcher.FindAll() | %{$_.properties.dnshostname}
```

#### Check for administrator access

{% code overflow="wrap" %}
```powershell
Invoke-Command -ScriptBlock {hostname} -ComputerName $Computers -ErrorAction SilentlyContinue
```
{% endcode %}

## Command examples&#x20;

### Connecting to remote host

#### One-to-one remoting

> If you want your remote session to be interactive, then one-to-one remoting is what you want. This type of remoting is provided via the `Enter-PSSession` cmdlet.

```powershell
$creds = Get-Credential
Enter-PSSession -ComputerName dc01 -Credential $creds
```

#### One-to-many remoting <a href="#one-to-many-remoting" id="one-to-many-remoting"></a>

> Sometimes you may need to perform a task interactively on a remote computer. But remoting is much more powerful when performing a task on multiple remote computers at the same time. Use the `Invoke-Command` cmdlet to run a command against one or more remote computers at the same time.

{% code overflow="wrap" %}
```powershell
Invoke-Command -ComputerName dc01, sql02, web01 {Get-Service -Name W32time} -Credential $Cred
```
{% endcode %}

#### PowerShell Sessions <a href="#powershell-sessions" id="powershell-sessions"></a>

> Similar to the CIM sessions, a PowerShell session to a remote computer can be used to run multiple commands against the remote computer without the overhead of a new session for each individual command.

```powershell
$session = New-PSSession -ComputerName dc01, sql02, web01 -Credential $Cred
```

Now we can the variable `$session` to run persist commands.&#x20;

```powershell
Invoke-Command -Session $Session {(Get-Service -Name W32time).Start()}
Invoke-Command -Session $Session {Get-Service -Name W32time}
```

#### When you finish remove the sessions

```powershell
Get-PSSession | Remove-PSSession
```

### Executing script on remote host/s

```powershell
Invoke-Command -ComputerName Server01, Server02 -FilePath c:\Scripts\DiskCollect.ps1
```

### File transfer

#### Downloading a file over PS Remote from remote machine

{% code overflow="wrap" %}
```powershell
$sess = New-PSSession IT-APPSRV01
Copy-Item -FromSession $sess C:\{file} -Destination C:\Windows\Temp\{file}
```
{% endcode %}

#### Upload a file over PS Remote to remote machine

{% code overflow="wrap" %}
```powershell
$sess = New-PSSession IT-APPSRV01
Copy-Item -ToSession $sess C:\Windows\Temp\{file} -Destination C:\{file} 
```
{% endcode %}

## Using WinRM on Kali PowerShell

#### Installing PowerShell on Kali

```bash
sudo apt install powershell
```

#### Enter into PowerShell and install PSWSMan&#x20;

```powershell
pwsh
Install-Module PSWSMan -Force
Install-WSMan
```

#### Common problems&#x20;

Problem: Error message about unspecified GSS failure

> Enter-PSSession : Connecting to remote server xxx.xxx.xxx.xxx failed with the following error message : acquiring creds with username only failed Unspecified GSS failure. Minor code may provide more information SPNEGO cannot find mechanisms to negotiate For more information, see the about\_Remote\_Troubleshooting Help topic.

```bash
sudo apt install gss-ntlmssp
```

Problem: Error message about access denied connecting with NTLM

> Enter-PSSession : MI\_RESULT\_ACCESS\_DENIED

Solution: Make sure to use -Authentication Negotiate even if this isn’t necessary when remoting from a Windows client.



## References

{% embed url="https://learn.microsoft.com/en-us/powershell/scripting/learn/ps101/08-powershell-remoting?view=powershell-7.3" %}

{% embed url="https://thomask.sdf.org/blog/2019/12/15/linux-windows-powershell-remoting-troubleshooting.html" %}
