PowerShell Remoting: Execute Remote Commands Like A Pro

Published:1 January 2025 - 5 min. read

Suppose you’ve learned to execute commands locally; that is already a stepping stone toward mastering remote execution. PowerShell Remoting allows administrators to execute commands and scripts on remote systems.

This guide demonstrates setting up and using PowerShell Remoting in an Active Directory (AD) environment. Imagine creating files, running scripts, or checking configurations remotely without leaving your desk.

Set up and use PowerShell Remoting to confidently execute scripts on remote systems!

Setting Up PowerShell Remoting for a Standard User

Before taking full advantage of PowerShell Remoting, you must ensure the necessary permissions are in place. Running commands or scripts remotely depends on proper configuration, especially in Active Directory environments where security is a priority.

Start by attempting to connect to a remote server (SRV2) using Invoke-Command. The following command runs a scriptblock on the remote computer:

Invoke-Command -ComputerName SRV2 -ScriptBlock {Write-Host "Hi, I'm running code on the $(hostname) remote computer!"}

If authentication fails, it typically means the user lacks the necessary permissions.

By default, non-administrative users must be members of the remote computer’s local Remote Management Users group.

Check the group membership:

Get-LocalGroupMember -Group 'Remote Management Users'

If the user isn’t listed, add them:

Add-LocalGroupMember -Group 'Remote Management Users' -Member user
Get-LocalGroupMember -Group 'Remote Management Users'

Now, retry the Invoke-Command command to confirm connectivity.

Invoke-Command -ComputerName SRV2 -ScriptBlock {Write-Host "Hi, I'm running code on the $(hostname) remote computer!"}

Running a Basic Script Remotely

Once PowerShell Remoting is configured, you can run commands on the remote computer. This capability unlocks the potential to automate tasks, gather data, and troubleshoot issues remotely.

To see how PowerShell remoting works, create a text file to the remote machine, then verify the action is successful.

Define and execute the scriptblock:

$scriptblock = { Set-Content -Path 'somefile.txt' -Value '' }
Invoke-Command -Scriptblock $scriptblock -ComputerName SRV2

Verify the file was created with the following command:

This command connects to the remote computer SRV2, retrieves information about the file somefile.txt, and outputs only its name and creation time.

icm -ComputerName SRV2 -ScriptBlock {Get-Item somefile.txt} | Select-Object Name, CreationTime

Running Local Scripts on Remote Computers

Perhaps a single command isn’t enough, and you might need to run a complete script stored locally on your machine. If so, PowerShell Remoting lets you quickly send a local script to a remote computer and execute it as if you were physically there.

To demonstrate running scripts on a remote computer, create a short script locally and run it on a remote machine to automate actions or cleanup tasks.

Create a script locally with this command where:

  • $scriptContents stores the script in a multi-line string using a here-string (@' ... '@), which is useful for keeping the script readable and organized.
  • Set-Content writes the contents of $scriptContents to a file called *RunThisRemotely.ps1* in the current directory.
$scriptContents =
@'
Write-Host "Deleting the file just created..."
Remove-Item -Path somefile.txt
'@
Set-Content -Path 'RunThisRemotely.ps1' -Value $scriptContents

Confirm the script contents:

Get-Content RunThisRemotely.ps1

Run the script remotely:

Invoke-Command -ComputerName SRV2 -FilePath RunThisRemotely.ps1

Now, verify the test file was deleted:

icm -ComputerName SRV2 -ScriptBlock {Test-Path somefile.txt}

Verifying Local Registry Keys with a Scripblock

PowerShell Remoting supports passing variables between local and remote sessions, enabling flexible and reusable scripts. But to start with, let’s focus on checking registry keys locally.

Store multiple registry paths that can be checked later to see if they exist on the system:

# Define an array of registry paths to check
$registryKeyPaths = @(
    'HKLM:\SOFTWARE\Microsoft\AppV\', 
    'HKLM:\SOFTWARE\Microsoft\AccountsControl\'
)

Add this to the script to define a script block ****($localScriptBlock) that executes locally on the computer. The script block checks whether specific registry paths exist on the local machine and provides feedback for each path.

# Define the script block that will run locally on the computer
$localScriptBlock = {
    ## Iterate through each registry path in the $registryKeyPaths array
    foreach ($path in $registryKeyPaths) {
        # Check if the current registry path exists on the local machine
        if (Test-Path -Path $path) {
            # If the path exists, output a message confirming its existence
            Write-Host -Object "The registry path [$path] exists on the computer $(hostname)."
        } else {
            # If the path does not exist, output a message stating its absence
            Write-Host -Object "The registry path [$path] does not exist on the computer $(hostname)."
        }
    }
}

Execute the scriptblock and see what happens.

Invoke-Command -ScriptBlock $localScriptBlock

Passing Local Variables to Remote Sessions

Whether you’re working with arrays, strings, or objects, you can pass data to remote commands in two ways:

  • $using – Integrates local variables into the script block directly.
  • ArgumentList – Explicitly passes variables to the block for use.

Read on to explore the two methods ($using or ArgumentList) to achieve this goal.

Using the $using Keyword (Preferred Approach)

After confirming the registry keys exist, the next step is to read that array locally and use it in the script on a remote computer. One way to achieve this feat is by using the $using keyword to reference local variables in remote sessions.

Create this script to run on the remote computer and check the specified registry paths. This script provides feedback about whether each path exists or not.

With this approach, you simply add the $using prefix to a local variable. This action tells PowerShell to reference the local variable registryKeyPaths before executing the code on the remote computer.

$remoteScriptBlock = {
    ## Check to see if the registry keys exist on the computer
    foreach ($path in $using:registryKeyPaths) {
        if (Test-Path -Path $path) {
            Write-Host -Object "The registry path [$path] exists on the computer $(hostname)."
        } else {
            Write-Host -Object "The registry path [$path] does not exist on the computer $(hostname)."
        }
    }
}

You can then invoke the remote command to execute the code on the remote machine:

Invoke-Command -ScriptBlock $remoteScriptBlock -ComputerName SRV2

Looks like the registry keys exist there as well.

Using the ArgumentList Parameter

Besides the $user keyword, another option is the ArgumentList parameter to send variables to the remote session.

Create a script (similar to one with the $using keyword) that uses the $args array to access the values passed via the ArgumentList parameter.

In this method, you specify one or more variables to be sent to the remote session through the ArgumentList parameter. Inside the script block, replace the local variable with $args, which PowerShell will automatically populate with the values passed through ArgumentList.

$remoteScriptBlock = {
    ## Check to see if the registry keys exist on the computer
    foreach ($path in $args) {
        if (Test-Path -Path $path) {
            Write-Host -Object "The registry path [$path] exists on the computer $(hostname)."
        } else {
            Write-Host -Object "The registry path [$path] does not exist on the computer $(hostname)."
        }
    }
}

Now, execute the script with the following command:

Invoke-Command -ScriptBlock $remoteScriptBlock -ComputerName SRV2 -ArgumentList $registryKeyPaths

Both methods will produce the same output, confirming that the registry keys exist on the remote computer.

By following these steps, you can effectively set up and use PowerShell Remoting to run commands and scripts on remote systems.

Conclusion

In this tutorial, you learned how to set up PowerShell Remoting in an Active Directory environment, run commands and scripts on remote systems, and pass variables effectively. These foundational skills are essential for automating administrative tasks and managing systems efficiently.

Now that you have the basics covered, consider exploring more advanced topics. Look into persistent PowerShell sessions, handling remote errors, or creating reusable scripts to handle bulk operations.

The possibilities with PowerShell Remoting are endless—so start experimenting and make your workflows more efficient!

Hate ads? Want to support the writer? Get many of our tutorials packaged as an ATA Guidebook.

Explore ATA Guidebooks

Looks like you're offline!