PowerShell – Run cmdlets without installing the modules – Implicit remoting in PowerShell

All the IT administrators they work with remote computers as part of their regular activities, and most of the time they use explicit remoting by mentioning the -Computername parameter to the cmdlets, and most commonly used cmdlet is Invoke-Commandalong with the other cmdlets like Get-Service, Get-Process, Get-WmiObject, Get-EventLog and etc…

Invoke-Command -ComputerName Server -ScriptBlock { $env:COMPUTERNAME }
Get-Service -ComputerName Server -Name servicename
Get-Process -ComputerName Server -Name processname
Get-WmiObject -Class Win32_OperatingSystem -ComputerName Server
Get-EventLog -ComputerName Server -LogName Application -Newest 5

What is Implicit Remoting in PowerShell?

Bring the modules installed on the remote computer and import them on your local computer to run the cmdlets natively as if they are installed on your local computer. But in fact, the cmdlets run against the remote computer from which the module is imported.

We need to establish a connection to the remote computer, then load the required modules into the remote session and then export the session modules to our local computer.

Establish the remote computer session

Open a PowerShell session with elevated privileges and create a new pssession to the remote computer from which you want to import the module…

$dcsession = New-PSSession -ComputerName DC2K16

The session output will be as below…

$dcsession

 Id Name            ComputerName    ComputerType    State         ConfigurationName     Availability
 -- ----            ------------    ------------    -----         -----------------     ------------
  1 WinRM1          DC2K16          RemoteMachine   Opened        Microsoft.PowerShell     Available

The above command to establish the connection to the remote computer works with the computer connected to the same domain, if it is not connected to the domain or from a different domain you need to add the remote computer name or IP to your local computer’s WinRM TrustedHosts list, and pass the credentials using -Credential parameter to the cmdlet.

Load the required module into the remote session

Basically, I want to connect to my DC server and export the ActiveDirectory module to my local session…

Invoke-Command -Session $dcsession -ScriptBlock {
Import-Module -Name ActiveDirectory
}

The module is loaded in the remote session and it is ready to export into the local PowerShell session.

Export the module from remote session to the local session

You can export the module with a different name altogether and also add a prefix to the cmdlets at the time of loading the module. When you export the module it will be created under $env:PSModulePath.

Export-PSSession -Session $dcsession -CommandName *-AD* -OutputModule RemoteDCModule -AllowClobber

    Directory: C:\Users\kiran\Documents\WindowsPowerShell\Modules\RemoteDCModule

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       05-02-2019  10:32 PM             99 RemoteDCModule.format.ps1xml
-a----       05-02-2019  10:32 PM            594 RemoteDCModule.psd1
-a----       05-02-2019  10:32 PM         396254 RemoteDCModule.psm1

Exporting the module is nothing but the PowerShell creates functions by default with the name same as the cmdlet name to execute on the remote computer where the module is exported from, and then wraps up all these functions into a proper script module(.psm1) ready to import.

Import the module and run the cmdlets

The exported module is ready to be copied and imported on any computer, provided the computer can be connected to the remote server. When you import the module and run the cmdlet for the first time within the session it will create a new pssession to the remote computer and then executes the command, and the same pssession will be used till the current session alive.

# Without prefix
Import-Module -Name RemoteDCModule

# With prefix
Import-Module -Name RemoteDCModule -Prefix FromDC

Adding prefix will help us to identify the cmdlets easily, it’s not mandatory though.

# On the remote computer
Import-Module ActiveDirectory
Get-Command -Module ActiveDirectory | Select-Object -First 4

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Cmdlet          Add-ADCentralAccessPolicyMember                    1.0.0.0    ActiveDirectory
Cmdlet          Add-ADComputerServiceAccount                       1.0.0.0    ActiveDirectory
Cmdlet          Add-ADDomainControllerPasswordReplicationPolicy    1.0.0.0    ActiveDirectory
Cmdlet          Add-ADFineGrainedPasswordPolicySubject             1.0.0.0    ActiveDirectory

Notice the CommandType is CmdLet on the remote computer when you actually import the module.

# On the local computer, import the exported module with prefix
Import-Module RemoteDCModule -Prefix FromDC
Get-Command -Module RemoteDCModule | Select-Object -First 4

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Add-FromDCADCentralAccessPolicyMember              1.0        RemoteDCModule
Function        Add-FromDCADComputerServiceAccount                 1.0        RemoteDCModule
Function        Add-FromDCADDomainControllerPasswordReplication... 1.0        RemoteDCModule
Function        Add-FromDCADFineGrainedPasswordPolicySubject       1.0        RemoteDCModule

Here the CommandType is Function and also notice the prefix FromDC in the noun. As I mentioned earlier, PowerShell creates a function to execute the actual command using Invoke-Command on the remote computer. If you want to know more about how the function is created, then pick any function from the exported module and see the definition of it using the command below…

# Syntax
(Get-Command -Name [function-name]).Definition

#Example
(Get-Command -Name Get-FromDCADUser).Definition

Execute the CmdLets

Since the exported module is saved in the local filesystem, you don’t need to create the remote computer session every time you execute the commands, the module will take care of establishing the connection to the remote computer and execute the commands against. So you can remove the remote session…

Remove-PSSession -Session $dcsession

Now, run any command and notice that there is a new session will be created (highlighted below)

ImplicitRemote1

So finally to justify the title of this post, you can run the cmdlets without installing the modules on the local computer. Especially it is much helpful on PowerShell Core, because some modules work with Windows PowerShell don’t work with PowerShell Core.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s