使用PowerShell包装现有COM对象

Rei*_*ien 7 com powershell

使用PowerShell System.DirectoryServices,我得到了一个如下所示的对象:

   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()
Run Code Online (Sandbox Code Playgroud)

我能找到的所有示例代码都涉及从PowerShell创建新的COM对象,而不是包装已返回的现有对象.我如何有用地处理这个对象(枚举和使用实际的属性和方法)?

注:此对象实际上确实有一个类型库("ActiveDs"),但由于某些原因,我无法使用它的开箱,为不同的问题(通过PowerShell和脚本的Windows Live作家加载类型库)建议应是这样的.

这是一个单线显示如何获得这样的对象:

((new-object DirectoryServices.DirectoryEntry -a '
LDAP://somedc').Properties.GetEnumerator() |?{$_.PropertyName -eq 'usnChanged' }).Value[0] | Get-Member
Run Code Online (Sandbox Code Playgroud)

Bil*_*art 5

PowerShell反射无法正确"查看"这些对象的属性和方法.为了获得属性和方法,我使用了一些包装器函数.这是一个例子:

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
Run Code Online (Sandbox Code Playgroud)

请注意,Set-Property和Invoke-Method使用数组作为最终参数,因此在调用这些函数时使用@().

  • 我已经使用了InvokeMember,但它很难看.实际上有一个TLB,但由于某种原因,PS似乎忽略了它.有没有办法列出可用的"真实"属性和方法,获取真实的类型名称,或加载正确的TLB? (2认同)