Use PowerShell to wrap an existing COM object

com, powershell

Solution

PowerShell reflection doesn't properly "see" these objects' properties and methods. To get to the properties and methods, I use some wrapper functions. Here is an example:

function Get-Property {
  param(
    [__ComObject] $object,
    [String] $propertyName
  )
  $object.GetType().InvokeMember($propertyName,"GetProperty",$NULL,$object,$NULL)
}

function Set-Property {
  param(
    [__ComObject] $object,
    [String] $propertyName,
    $propertyValue
  )
  [Void] $object.GetType().InvokeMember($propertyName,"SetProperty",$NULL,$object,$propertyValue)
}

function Invoke-Method {
  param(
    [__ComObject] $object,
    [String] $methodName,
    $methodParameters
  )
  $output = $object.GetType().InvokeMember($methodName,"InvokeMethod",$NULL,$object,$methodParameters)
  if ( $output ) { $output }
}

$ADS_ESCAPEDMODE_ON = 2      # see ADS_ESCAPE_MODE_ENUM
$ADS_SETTYPE_DN = 4          # see ADS_SETTYPE_ENUM
$ADS_FORMAT_X500_PARENT = 8  # see ADS_FORMAT_ENUM

$Pathname = New-Object -ComObject "Pathname"
# store initial EscapedMode
$escapedMode = Get-Property $PathName "EscapedMode"
# Enable all escaping
Set-Property $PathName "EscapedMode" @($ADS_ESCAPEDMODE_ON)
Invoke-Method $Pathname "Set" @("CN=Ken Dyer,OU=H/R,DC=fabrikam,DC=com",$ADS_SETTYPE_DN)
Invoke-Method $Pathname "Retrieve" @($ADS_FORMAT_X500_PARENT)
# outputs 'OU=H\/R,DC=fabrikam,DC=com'
$escapedMode = Set-Property $PathName "EscapedMode" @($escapedMode)
# set EscapedMode property back to initial value

Note that the Set-Property and Invoke-Method use an array as their final parameter, so I use @( ) when calling those functions.

Problem

Using PowerShell and `System.DirectoryServices`, I've been given an object that looks like this: ``` TypeName: System.__ComObject Name MemberType Definition ---- ---------- ---------- CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType) Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetLifetimeService Method System.Object GetLifetimeService() GetType Method type GetType() InitializeLifetimeService Method System.Object InitializeLifetimeService() ToString Method string ToString() ``` All example code that I can find deals with creating new COM objects from PowerShell, not wrapping existing objects that have been returned. How can I usefully deal with this object (enumerate and use the actual properties and methods)? Note: this object actually does have a type library ("ActiveDs"), but for some reason I am unable to use it out of the box, as a different question (Loading a Type Library via PowerShell and scripting Windows Live Writer) suggests should be the case. Here is a one-liner showing how to get such an object: ``` ((new-object DirectoryServices.DirectoryEntry -a ' LDAP://somedc').Properties.GetEnumerator() |?{$_.PropertyName -eq 'usnChanged' }).Value[0] | Get-Member ```

Original source

Related problems