Windows OS Hub
  • Windows
    • Windows 11
    • Windows Server 2022
    • Windows 10
    • Windows Server 2019
    • Windows Server 2016
  • Microsoft
    • Active Directory (AD DS)
    • Group Policies (GPOs)
    • Exchange Server
    • Azure and Microsoft 365
    • Microsoft Office
  • Virtualization
    • VMware
    • Hyper-V
  • PowerShell
  • Linux
  • Home
  • About

Windows OS Hub

  • Windows
    • Windows 11
    • Windows Server 2022
    • Windows 10
    • Windows Server 2019
    • Windows Server 2016
  • Microsoft
    • Active Directory (AD DS)
    • Group Policies (GPOs)
    • Exchange Server
    • Azure and Microsoft 365
    • Microsoft Office
  • Virtualization
    • VMware
    • Hyper-V
  • PowerShell
  • Linux

 Windows OS Hub / PowerShell / Invoke-Command: Run Commands or PowerShell Scripts on Remote Computers

May 15, 2025

Invoke-Command: Run Commands or PowerShell Scripts on Remote Computers

The Invoke-Command cmdlet allows you to execute commands or PowerShell scripts remotely on one or more remote computers

Contents:
  • How to Enable PowerShell Remoting (WinRM) on Windows
  • Using Invoke-Commands to Run Commands on Remote Computers
  • Running Commands on Multiple Computers with Invoke-Command
  • PowerShell Remoting Persistent Connections

How to Enable PowerShell Remoting (WinRM) on Windows

The Invoke-Command cmdlet relies on PowerShell Remoting sessions to execute commands on remote computers. PowerShell Remoting is used to remotely control and execute commands and is based on the WS-Management protocol (implemented by WinRM, Windows Remote Management service). The HTTP (TCP/5985 port) or HTTPS (TCP/5986 port) protocol is used for communication with remote computers. By default, the HTTP protocol is used, but even this traffic is encrypted using an AES-256 key (although there is a risk of man-in-the-middle attacks).  Authentication for PowerShell Remoting over WinRM can use Kerberos (for domain-joined systems), NTLM, or certificate-based (WinRM over HTTPS) auth.

To establish a PSSession with a remote computer, you must enable the WinRM service on that computer and allow remote connections:

Ensure that the WinRM service is running and a listener is properly configured on the target (client) computer:

Get-Service -Name "*WinRM*" | fl
WinRM enumerate winrm/config/listener

WinRM quickconfig, enumerate winrm/config/listener

The WinRM service is not configured in this case. To enable it and allow remote connections through WinRM, run the following command:

winrm quickconfig
or
Enable-PSRemoting -Force

WinRM has been updated to receive requests.
WinRM service started.
WinRM is already set up for remote management on this computer.

Enable-PSRemoting

This command starts the WinRM service (sets its startup type to Automatic), configures the default WinRM settings, and creates the necessary Windows Firewall exceptions.

You can also enable and configure WinRM on a computer using Group Policies.

Now, check if it is possible to remotely connect to the computer via PSRemoting:

Test-WsMan - testing wirm connectivity using powershell

By default, PowerShell Remoting doesn’t work for Public network connections.  It is recommended to change the network location in Windows to Private or Domain. If this is not possible, you can allow WinRM for public networks and enable the appropriate firewall rule:

Enable-PSRemoting -SkipNetworkProfileCheck
Set-NetFirewallRule -Name WINRM-HTTP-In-TCP -RemoteAddress Any

If the remote hosts are not joined to the AD domain (i.e., when using a workgroup) or if the computers are accessed via IP addresses, NTLM authentication is used instead of Kerberos.  To enable NTLM authentication through WimRM, add the name (or IP address) of the remote host to the trusted list on the administrator’s computer:

Set-Item wsman:\localhost\Client\TrustedHosts -value 192.168.1.201

winrm: wsman add trusted hosts

Or you can allow PSRemote connection to all computers (not recommended, because one of the drawbacks of NTLM is that it doesn’t support mutual authentication).

Set-Item wsman:\localhost\Client\TrustedHosts -value *

The same settings must be applied to remote hosts.
List trusted hosts using the command:
Get-Item WSMan:\localhost\Client\TrustedHosts

Restart the WinRM service to apply the changes:

Restart-Service WinRM

Using Invoke-Commands to Run Commands on Remote Computers

To execute a single command on a remote computer, specify the computer name (-ComputerName) and the command itself in the -ScriptBlock {[command]}.

Invoke-Command -ComputerName dc01 -ScriptBlock {Get-Service wuauclt}

The cmdlet sends the specified command to the remote computer and prints the result to the console (the result is returned as a PowerShell object). In this case, we received the Windows Update service status on a remote computer.

Invoke-Command: run command on remote machine

To interrupt a remotely executed command in Invoke-Command, press CTRL+C in the console.

The Invoke-Command cmdlet runs commands on behalf of the user who is running the PowerShell console. Use the -Credential parameter to run a command as a different user:

$cred = Get-Credential
Invoke-Command -ComputerName dc01 -Credential $cred -ScriptBlock {Get-NetAdapter}

This PowerShell command lists the network interfaces on a remote computer:

run powershell command Get-NetAdapter remotely

  • By default, only the members of the local ‘Administrators‘ and ‘Remote Management Users‘ groups have permission to connect remotely via PSRemoting.
  • If the command sent to the remote computer includes a request to access a remote resource (for example, a shared network folder), authentication to the second resource will fail. This problem is called Double-Hop and is related to Windows security restrictions that prevent credentials from being passed to a third party.

To run multiple commands sequentially on a remote computer, separate them with semicolons within the ScriptBlock. For example, the following command will display the current time zone and change it to another one:

Invoke-Command -Computername dc01 -ScriptBlock {Get-TimeZone| select DisplayName;Set-TimeZone -Name "Central Europe Standard Time"}

invoke-commapn - multiple lines in script block

The Invoke-Command cmdlet allows you to run not only individual commands but also PowerShell scripts. To do this, specify the path to the local PS1 file with the script in the -FilePath parameter:

Invoke-Command -ComputerName DC01 -FilePath C:\PS\Scripts\CheckSMBversion.ps1

  • This method of running remote scripts eliminates the need to manually copy the PowerShell script file to remote computers
  • The PowerShell execution policy settings are ignored in this case.

Use the $using construct when you need to pass the value of a local variable from a script to an Invoke-Command block:

$localVar = Get-Date
Invoke-Command -ComputerName Server01 -ScriptBlock {
"Date = $using:localVar"
}

Running Commands on Multiple Computers with Invoke-Command

The Invoke-Command cmdlet allows you to run commands simultaneously (in parallel) on multiple remote computers. The simplest way is to use commas to separate the names of the computers on which the PowerShell commands will be executed:

Invoke-Command server1, server2, server3 -ScriptBlock {get-date}

invoke-command: running commands on multiple remote computers in parallel

You can save the list of remote hosts in a variable (array):

$servers = @("server1","server2","server3")
Invoke-Command -ScriptBlock { get-date} -ComputerName $servers

Or get from a text file:

Invoke-Command -ScriptBlock {Restart-Service spooler} -ComputerName(Get-Content c:\ps\servers.txt)

You can also retrieve a list of computers from Active Directory using the Get-ADComputer cmdlet from the AD PowerShell module. For example, to run a command on all Windows Server hosts in a domain, use this code:

$computers = (Get-ADComputer -Filter 'OperatingSystem -like "*Windows server*" -and Enabled -eq "true"').Name
Invoke-Command -ComputerName $computers -ScriptBlock {Get-Date} -ErrorAction SilentlyContinue

If the computer is powered off or unavailable, the SilentlyContinue parameter will prevent the script from halting, allowing it to continue running on other computers.

To understand from which computer the results were received, you need to use a special environment variable, PSComputerName.

$results = Invoke-Command server1, server2, server3 -ScriptBlock {get-date}
$results | Select-Object PSComputerName, DateTime

powershell invoke-command return pscomputername

Invoke-Command has a limit on the maximum number of simultaneous sessions with remote computers. The default is 32 (determined by the ThrottleLimit parameter). If you need to run the command on more than 32 computers simultaneously (for example, 128), use the -ThrottleLimit 128 parameter.

To run commands on a remote computer in the background using Invoke-Command, a special –AsJob option is used. The result of remote command execution is not returned to the console in this case. Use the Receive-Job cmdlet to get the results of the remote command.

PowerShell Remoting Persistent Connections

If you frequently need to run commands on a remote computer, you can establish a persistent PSRemoting session with that computer. This prevents the Invoke-Command cmdlet from initiating a new remote connection each time.

Let’s create a persistent session with one or more remote computers:

$s = New-PSSession -ComputerName Server01, Server02

Now use the -Session parameter to run a command in the PSSession that you created:

Invoke-Command -Session $s -ScriptBlock { Get-ComputerInfo|select OsLastBootUpTime }

Invoke-Command using with persistent PS sessions

To close the remote persistent session, close the PowerShell console or run:

Remove-PSSession $s

1 comment
6
Facebook Twitter Google + Pinterest
PowerShellWindows 10Windows 11Windows Server 2022
previous post
Remote Session Disconnected: No Remote Desktop License Servers/Client Access Licenses Available
next post
How to Cleanup, Truncate or Move Log Files in Exchange Server 2013/2016/2019?

Related Reading

PowerShell: Get Folder Size on Windows

April 2, 2024

How to Download Offline Installer (APPX/MSIX) for Microsoft...

March 12, 2024

Protecting Remote Desktop (RDP) Host from Brute Force...

February 5, 2024

How to Refresh (Update) Group Policy Settings on...

August 13, 2024

Install and Manage Windows Updates with PowerShell (PSWindowsUpdate)

March 17, 2024

How to Backup and Restore Websites and IIS...

June 8, 2023

Slow Access to Shared Folders and Network Drives...

March 11, 2024

Using Credential Manager on Windows: Ultimate Guide

March 15, 2024

1 comment

Tomi March 15, 2021 - 10:38 am

great job. thx a lot

Reply

Leave a Comment Cancel Reply

join us telegram channel https://t.me/woshub
Join WindowsHub Telegram channel to get the latest updates!

Recent Posts

  • Map a Network Drive over SSH (SSHFS) in Windows

    May 13, 2025
  • Configure NTP Time Source for Active Directory Domain

    May 6, 2025
  • Cannot Install Network Adapter Drivers on Windows Server

    April 29, 2025
  • Change BIOS from Legacy to UEFI without Reinstalling Windows

    April 21, 2025
  • How to Prefer IPv4 over IPv6 in Windows Networks

    April 9, 2025
  • Load Drivers from WinPE or Recovery CMD

    March 26, 2025
  • How to Block Common (Weak) Passwords in Active Directory

    March 25, 2025
  • Fix: The referenced assembly could not be found error (0x80073701) on Windows

    March 17, 2025
  • Exclude a Specific User or Computer from Group Policy

    March 12, 2025
  • AD Domain Join: Computer Account Re-use Blocked

    March 11, 2025

Follow us

  • Facebook
  • Twitter
  • Telegram
Popular Posts
  • Install and Manage Windows Updates with PowerShell (PSWindowsUpdate)
  • How to Download Offline Installer (APPX/MSIX) for Microsoft Store App
  • Configuring Port Forwarding in Windows
  • Start Menu or Taskbar Search Not Working in Windows 10/11
  • Get-ADUser: Find Active Directory User Info with PowerShell
  • Adding Drivers into VMWare ESXi Installation Image
  • Tracking and Analyzing Remote Desktop Connection Logs in Windows
Footer Logo

@2014 - 2024 - Windows OS Hub. All about operating systems for sysadmins


Back To Top