Comparing RPC, WMI and WinRM for remote server management with PowerShell V2

1. Overview

In a recent blog post, I was looking at PowerShell V2 remoting in Windows Server 2008 R2.
If you haven’t seen it, take a look at

In that post, I mentioned three different ways to gather information about services on a remove server (throughout this post, I use this task as an example of what I administrator would run remotely):

·         Using Get-Service with the –ComputerName parameter (RPC)

·         Using Get-WMIObject with a –ComputerName parameter (WMI)

·         Using Invoke-Command to execute Get-Service remotely (WinRM)

In this post, I spent more time looking deeper at some the most significant differences between them.


2. Commands and Outputs

For starters, here are the three versions of a sample command to query a remote server and the output they produce: the first using Get-Service, the second using Get-WMIObject  and the third using Invoke-Command.

From an IT Administrator perspective, the Get-Service form is short and to the point. It is a good example of how PowerShell makes things simple to manage.

The Invoke-Command is not so bad either, with the advantage that IT Administrators don’t have to restrict themselves to cmdlets that have the –ComputerName option.

The Get-WMIObject seems a bit scary for someone without a developer background. You also lose some of the discoverability advantages of PowerShell (you can’t press TAB to complete your query, for instance).

On the other hand, for developers familiar with Win32 APIs and WMI classes, the option to use Get-WMIObject  seems very attractive.


Get-Service LanManServer -ComputerName josebda-s0


Status   Name          DisplayName

——   —-          ———–

Running  LanManServer  Server


Get-WMIObject -ComputerName josebda-s0 -query “Select * from Win32_Service Where Name=’LanManServer ‘” | ft


ExitCode Name           ProcessId StartMode  State    Status

——– —-           ——— ———  —–    ——

       0 LanmanServer         868 Auto       Running  OK


Invoke-Command josebda-s0 {Get-Service LanManServer}


Status   Name          DisplayName   PSComputerName

——   —-          ———–   ————–

Running  LanManServer  Server        josebda-s0


3. Properties and Methods

While the three options look similar, the objects returned are different. The first is of type “System.ServiceProcess.ServiceController”, the second returns the type “System.Management.ManagementObject#rootcimv2Win32_Service” and last one is of type “Deserialized.System.ServiceProcess.ServiceController”. Take a look below at the details on each different type below, obtained using Get-Member.  Note that the deserialized version has no methods to perform actions on the service, like stop or start.


Get-Service LanManServer -ComputerName josebda-s0 | Get-Member


TypeName: System.ServiceProcess.ServiceController


Name                      MemberType    Definition

—-                      ———-    ———-

Name                      AliasProperty Name = ServiceName

RequiredServices          AliasProperty RequiredServices = ServicesDependedOn

Disposed                  Event         System.EventHandler Disposed(System.Object, System.EventArgs)

Close                     Method        System.Void Close()

Continue                  Method        System.Void Continue()

CreateObjRef              Method        System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)

Dispose                   Method        System.Void Dispose()

Equals                    Method        bool Equals(System.Object obj)

ExecuteCommand            Method        System.Void ExecuteCommand(int command)

GetHashCode               Method        int GetHashCode()

GetLifetimeService        Method        System.Object GetLifetimeService()

GetType                   Method        type GetType()

InitializeLifetimeService Method        System.Object InitializeLifetimeService()

Pause                     Method        System.Void Pause()

Refresh                   Method        System.Void Refresh()

Start                     Method        System.Void Start(), System.Void Start(string[] args)

Stop                      Method        System.Void Stop()

ToString                  Method        string ToString()

WaitForStatus             Method        System.Void WaitForStatus(System.ServiceProcess.ServiceControllerStatus desi…

CanPauseAndContinue       Property      System.Boolean CanPauseAndContinue {get;}

CanShutdown               Property      System.Boolean CanShutdown {get;}

CanStop                   Property      System.Boolean CanStop {get;}

Container                 Property      System.ComponentModel.IContainer Container {get;}

DependentServices         Property      System.ServiceProcess.ServiceController[] DependentServices {get;}

DisplayName               Property      System.String DisplayName {get;set;}

MachineName               Property      System.String MachineName {get;set;}

ServiceHandle             Property      System.Runtime.InteropServices.SafeHandle ServiceHandle {get;}

ServiceName               Property      System.String ServiceName {get;set;}

ServicesDependedOn        Property      System.ServiceProcess.ServiceController[] ServicesDependedOn {get;}

ServiceType               Property      System.ServiceProcess.ServiceType ServiceType {get;}

Site                      Property      System.ComponentModel.ISite Site {get;set;}

Status                    Property      System.ServiceProcess.ServiceControllerStatus Status {get;}


Get-WMIObject -computername josebda-s0 -query “Select * from Win32_Service Where Name=’LanManServer'” | Get-Member


TypeName: System.Management.ManagementObject#rootcimv2Win32_Service


Name                    MemberType   Definition

—-                    ———-   ———-

Change                  Method       System.Management.ManagementBaseObject Change(System.String DisplayName, System…

ChangeStartMode         Method       System.Management.ManagementBaseObject ChangeStartMode(System.String StartMode)

Delete                  Method       System.Management.ManagementBaseObject Delete()

GetSecurityDescriptor   Method       System.Management.ManagementBaseObject GetSecurityDescriptor()

InterrogateService      Method       System.Management.ManagementBaseObject InterrogateService()

PauseService            Method       System.Management.ManagementBaseObject PauseService()

ResumeService           Method       System.Management.ManagementBaseObject ResumeService()

SetSecurityDescriptor   Method       System.Management.ManagementBaseObject SetSecurityDescriptor(System.Management….

StartService            Method       System.Management.ManagementBaseObject StartService()

StopService             Method       System.Management.ManagementBaseObject StopService()

UserControlService      Method       System.Management.ManagementBaseObject UserControlService(System.Byte ControlCode)

AcceptPause             Property     System.Boolean AcceptPause {get;set;}

AcceptStop              Property     System.Boolean AcceptStop {get;set;}

Caption                 Property     System.String Caption {get;set;}

CheckPoint              Property     System.UInt32 CheckPoint {get;set;}

CreationClassName       Property     System.String CreationClassName {get;set;}

Description             Property     System.String Description {get;set;}

DesktopInteract         Property     System.Boolean DesktopInteract {get;set;}

DisplayName             Property     System.String DisplayName {get;set;}

ErrorControl            Property     System.String ErrorControl {get;set;}

ExitCode                Property     System.UInt32 ExitCode {get;set;}

InstallDate             Property     System.String InstallDate {get;set;}

Name                    Property     System.String Name {get;set;}

PathName                Property     System.String PathName {get;set;}

ProcessId               Property     System.UInt32 ProcessId {get;set;}

ServiceSpecificExitCode Property     System.UInt32 ServiceSpecificExitCode {get;set;}

ServiceType             Property     System.String ServiceType {get;set;}

Started                 Property     System.Boolean Started {get;set;}

StartMode               Property     System.String StartMode {get;set;}

StartName               Property     System.String StartName {get;set;}

State                   Property     System.String State {get;set;}

Status                  Property     System.String Status {get;set;}

SystemCreationClassName Property     System.String SystemCreationClassName {get;set;}

SystemName              Property     System.String SystemName {get;set;}

TagId                   Property     System.UInt32 TagId {get;set;}

WaitHint                Property     System.UInt32 WaitHint {get;set;}

Comments (1)

  1. Anonymous says:

    Excellent post and backs up my own feeling in an objective manor. Maybe worth adding that you want to filter out as much data as possible in a WMI query rather than pull back all data and filter locally in PowerShell (specifically when querying something like the remote event log)