Managing PCs With Remote PowerShell

Powershell remoting (Traditional without SSH)

This is perfect for windows domains but irritating and MAYBE unsecure for workgroups

How to configure a PC from which you want to connect to other PCs (PS client)

# Start WinRM service (Windows Remote Management)
Get-Service -name winrm | start-service
Set-Service winrm -startuptype automatic
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*" -Force
# Test
Enter-pssession -computername 10.1.11.123 -credentials (Get-Credential)

How to configure a PC to accept remote connections (PS server)

Get-Service -name winrm | start-service; Set-Service winrm -startuptype automatic
Enable-PSRemoting -SkipNetworkProfileCheck -Force 
Set-NetFirewallRule -Name 'WINRM-HTTP-In-TCP' -RemoteAddress Any

Enable-PSRemoting, configures the computer to receive PowerShell remote commands. -Force just saves you from some confirmations. By default Enable-PSRemoting adds PASS firewall rules only for private and domain networks. -SkipNetworkProfileCheck also adds firewall rules to allow remote access from the same local subnet for public networks. To remove even the local subnet restriction, we use Set-NetFirewallRule with -RemoteAddress Any

If Enable-PSRemoting fails you may try:
  1. Get an overview of networks:
    gip -Detailed | %{ "$($_.NetProfile.NetworkCategory)`t.$($_.IPv4Address.IPAddress)`t'$($_.InterfaceAlias)'`t'$($_.InterfaceDescription)'"}
  2. Switch all networks that you can from Public to Private
  3. Disable any network adapters that don’t appear as neither Public nor Private
More info and other ways to enable it: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/enable-psremoting?view=powershell-7.2

Remotely enable powershell remoting smile

psexec.exe \\RemoteComputerName -s powershell Enable-PSRemoting -Force

To execute a few commands remotely

Invoke-Command -ComputerName $List-of-clients -ScriptBlock { COMMAND; ... }

To start a remote session and start working on the remote PC

Enter-PSSession -ComputerName COMPUTER 

Run a local function in parallel on one or more remote PCs

function Calc-SpeedOfLight(a,b)
{...}
Invoke-Command -ComputerName $List-of-clients -ScriptBlock ${Function:Calc-SpeedOfLight} ` -ArgumentList 1,2

Managing PCs With Remote PowerShell

# -----------------------------------
# Remote installation
# -----------------------------------

# copy file to the workstation
Invoke-WebRequest -Uri https://wiki.enlogic.gr/pub/KnowledgeBase/PublicFiles/mazars-prepare-laptop-code.zip -OutFile temp.zip

# run installation
invoke-command -ScriptBlock { $msiArgs = '/qn', '/norestart', '/log', 'c:\it\moffice_ppt_2.8.16_64bits_install.log', '/i', 'C:\it\bin\temp\moffice_ppt_2.8.16_64bits.msi'; $ps = Start-Process -PassThru -Wait msiexec -ArgumentList $msiArgs; echo $ps.ExitCode; gc 'c:\it\moffice_ppt_2.8.16_64bits_install.log' | select -last 6 } -ComputerName wx1-pc

# -----------------------------------
# Other helpful tips
# -----------------------------------

# ask every workstation to report its PC name back via remote-powershell
invoke-command -ScriptBlock {Hostname} -ComputerName @((Get-ADComputer -Filter 'Name -like "RPS*"').Name)

# -----------------------------------

# list of recently connected PCs with name starting with RPS
$today = Get-Date
$cutoffdate = $today.AddDays(-120)
Get-ADComputer -Properties * -Filter {LastLogonDate -gt $cutoffdate} | Select Name,OperatingSystem,OperatingSystemVersion,LastLogonDate,IPv4Address | Where-Object -filter { $_.Name -like 'RPS*' } | ogv

Powershell remoting with SSH

If you are on a domain then this is more complicated than the traditional way but if you are on a workgroup then it's good.

I have written a script that does everything below automaticaly, see C:\Users\user\enLogic\IT Support - Documents\scripts_and_SW_we_build\ps-ssh-remoting

#==================
# ON BOTH PCS
# Open powershell as ADMIN
#==================

# verify you are admin
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
if ($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {} else {Write-Host -fore red "`n`nYou are not running as Admin`n" }

# install PowerShell 7 Core
iex "& { $(irm https://aka.ms/install-powershell.ps1) } -UseMSI"

#==================
# ON BOTH PCS
# Close EXISTING powershell
# Open *FRESHLY INSTALLED* powershell 7 Core AS ADMIN
#==================

# verify you are admin
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
if ($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {} else {Write-Host -fore red "`n`nYou are not running as Admin`n" }

# verify you are running core
if ($PSVersionTable.PSEdition -ne "Core") {Write-Host -fore red "`n`nYou are not running powershell Core`n" } else {Write-Host -fore green "`nOK, running on powershell Core" }

# install SSH server and client
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Set-Service -Name sshd -StartupType 'Automatic'
Start-Service -Name sshd

Install-Module -Name Microsoft.PowerShell.RemotingTools -Force

Import-Module -Name Microsoft.PowerShell.RemotingTools

Enable-SSHRemoting -Verbose -Force

Restart-Service -Name sshd

#==================
# ON THE SSH CLIENT
#==================
# Test by trying this from the ssh client to the ssh server
# It should ask for the password and display the computer name of the client
Invoke-Command -HostName 10.1.11.231 -UserName user -ScriptBlock { hostname }


#========================================================================
# Public Key (passwordless) authentication
#========================================================================

#==================
# ON THE SSH CLIENT 
#==================

# ***NON ADMIN PS***
ssh-keygen
#- - - - - - - - - - - - - - - 
# Hit Enter for "Enter file in which to save the key"
# Hit Enter for passphrase twice
#-----------------------------

# run this command to print YOUR PUBLIC KEY
type C:\Users\LAB/.ssh/id_rsa.pub

# ***ADMIN PS***
Set-Service ssh-agent -StartupType Automatic
Start-Service ssh-agent
ssh-add $env:userprofile\.ssh\id_rsa 


#==============================================
# ON THE SSH-SERVER 
#==============================================
# ***ADMIN PS***
# If this commands prints nothing skip this section
if (sls '^ *PubkeyAuthentication  *yes' C:\ProgramData\ssh\sshd_config) {} else {Write-Host -fore red "Option for 'PubkeyAuthentication' is not enabled"}

# If the above complains then:
notepad C:\ProgramData\ssh\sshd_config
# and make sure you have this line AND IT IS NOT COMMENTED with #
#
# PubkeyAuthentication yes


#==============================================
# ON THE SSH-SERVER IF THE USER IS NOT AN ADMIN DO THIS:
#==============================================
$YOUR_PUBLIC_KEY="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCy6QllwckCZECUPYrXjl5IH3bL64iJhd5s4TlR0x1AJsTfdjxS4586DDw6AmNanBjJMnXrFvjE+j0cMYRXd/xajZqLnWxMUos1Mc86w232bY20hjEr6l2dC+4YB7qT7OEtcv6jbHCQTn0rwGr/Kfyb8z5kn0otNRyb9r6DbfAEVpRFtLxpTH0EpKUir2Hd8nfY98PZ5g2BqROBrpRWZoVc3VYxzuR3/zysCva6kvDoBXo91VCWYisHhb/intQxifOU5dgmdB4nqMjbFYRdJWqaKu5PFRw9jVboVHEVQ0tBWBl8Xt1YaeEGxlAEIYcAZPFfaqXbtESj1defAvkpAudt lab@Chris-PC" # > $env:userprofile\.ssh\authorized_keys
explorer $env:userprofile\.ssh
# open security tab for the file 'authorized_keys' and make sure only system and the SPECIFIC USER have full control

#==============================================
# ON THE SSH-SERVER IF THE USER IS AN ADMIN DO THIS:
#==============================================
# ***ADMIN PS***
$YOUR_PUBLIC_KEY="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCy6QllwckCZECUPYrXjl5IH3bL64iJhd5s4TlR0x1AJsTfdjxS4586DDw6AmNanBjJMnXrFvjE+j0cMYRXd/xajZqLnWxMUos1Mc86w232bY20hjEr6l2dC+4YB7qT7OEtcv6jbHCQTn0rwGr/Kfyb8z5kn0otNRyb9r6DbfAEVpRFtLxpTH0EpKUir2Hd8nfY98PZ5g2BqROBrpRWZoVc3VYxzuR3/zysCva6kvDoBXo91VCWYisHhb/intQxifOU5dgmdB4nqMjbFYRdJWqaKu5PFRw9jVboVHEVQ0tBWBl8Xt1YaeEGxlAEIYcAZPFfaqXbtESj1defAvkpAudt lab@Chris-PC" # > C:\ProgramData\ssh\administrators_authorized_keys

explorer C:\ProgramData\ssh
#####FIXME#####
# open security tab for the file 'administrators_authorized_keys' and make sure only system and the SPECIFIC USER have full control

#==============================================
# ON THE SSH-SERVER IF THE USER IS AN ADMIN DO THIS:
#==============================================
# ***ADMIN PS***
# If these commands print nothing skip this section
if (sls '^ *Match Group admin' C:\ProgramData\ssh\sshd_config) {} else {Write-Host -fore red "Didn't find option for 'Match Group admin'"}
if (sls '^ *AuthorizedKeysFile  *__PROGRAMDATA__' C:\ProgramData\ssh\sshd_config) {} else {Write-Host -fore red "Option for 'Match Group admin' is not OK"}
# If the above complains then:
notepad C:\ProgramData\ssh\sshd_config
# Make sure you have these lines AND THEY ARE NOT COMMENTED 
#
# Match Group administrators
#        AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys


#==================
# FINALY TEST by trying this from the client to the server
# It should NOT ask for a password 
#==================
Invoke-Command -HostName 10.1.11.231 -UserName user -ScriptBlock { hostname }


# for troubleshooting of public-key authentication check this:
# https://stackoverflow.com/questions/16212816/setting-up-openssh-for-windows-using-public-key-authentication


.
Topic revision: r11 - 08 Jun 2024, NickDemou
Copyright © enLogic