2013-11-27 10 views
7

Korzystanie PowerShell i System.DirectoryServices, Dostałem obiekt, który wygląda tak:Wykorzystanie PowerShell zawinąć istniejący obiekt COM

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() 

Wszystko przykład kodu, który można znaleźć oferty z tworzeniem nowych obiektów COM z PowerShell , nie owija istniejących obiektów, które zostały zwrócone. Jak mogę z pożytkiem poradzić sobie z tym obiektem (wyliczyć i użyć rzeczywistych właściwości i metod)?

Uwaga: ten przedmiot faktycznie robi mają biblioteki typów („Activeds”), ale z jakiegoś powodu nie jestem w stanie go używać po wyjęciu z pudełka, jak inna kwestia (Loading a Type Library via PowerShell and scripting Windows Live Writer) sugeruje powinno być.

Oto jedna wkładka pokazujący jak uzyskać taki obiekt:

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

Istnieje cmdlet że zaprojektowane specjalnie do pracy z usługą Active Directory. http://technet.microsoft.com/en-us/library/ee617195.aspx Możliwe, że ułatwisz sobie życie, jeśli z nich skorzystasz. –

+0

Czy możesz podać przykład kodu, który zwraca ten konkretny obiekt, z którym masz problemy? –

+0

Niestety, nie mogę zainstalować żadnych nowych modułów; inaczej z pewnością bym to wykorzystał. – Reinderien

Odpowiedz

5

PowerShell odbicie nie prawidłowo „zobaczyć” właściwości i metody tych obiektów. Aby uzyskać dostęp do właściwości i metod, używam niektórych funkcji opakowania. Oto przykład:

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 

Zauważ, że Set-nieruchomości i wywołać sposobie korzystania tablicę jako ostatecznego parametru, więc używam @() podczas wywoływania tych funkcji.

+2

Używam już InvokeMember, ale jest brzydki. W rzeczywistości istnieje TLB, ale z jakiegoś powodu PS zdaje się go ignorować. Czy istnieje sposób na listę rzeczywistych właściwości i dostępnych metod, aby uzyskać prawdziwą nazwę typu lub załadować właściwą TLB? – Reinderien

1

Tylko trochę inne podejście następnie Bill Stewart:

Chodzi o to, że zazwyczaj nie musisz/chcesz utworzyć wiele instancji ComObject:

Function Invoke-ComObject([Parameter(Mandatory = $true)]$ComObject, [Switch]$Method, [Parameter(Mandatory = $true)][String]$Property, $Value) { 
    If ($ComObject -IsNot "__ComObject") { 
     If (!$ComInvoke) {$Global:ComInvoke = @{}} 
     If (!$ComInvoke.$ComObject) {$ComInvoke.$ComObject = New-Object -ComObject $ComObject} 
     $ComObject = $ComInvoke.$ComObject 
    } 
    If ($Method) {$Invoke = "InvokeMethod"} ElseIf ($MyInvocation.BoundParameters.ContainsKey("Value")) {$Invoke = "SetProperty"} Else {$Invoke = "GetProperty"} 
    [__ComObject].InvokeMember($Property, $Invoke, $Null, $ComObject, $Value) 
}; Set-Alias ComInvoke Invoke-ComObject 

Jeśli dotyczy to metody, należy dodać przełącznik –Method, w przypadku właściwości cmdlet automatycznie określi, czy właściwość należy pobrać, czy ustawić w zależności od tego, czy wartość jest dostarczana. Za pomocą tego polecenia cmdlet nie trzeba najpierw tworzyć elementu ComObject i pobierać np. aby uzyskać ComputerName (DN) od ADSystemInfo w prosty oneliner:

ComInvoke ADSystemInfo ComputerName 

zrobić to samo z PathName:

$EscapedMode = ComInvoke PathName EscapedMode 
ComInvoke PathName EscapedMode @($ADS_ESCAPEDMODE_ON) 
ComInvoke Pathname -Method Set @("CN=Ken Dyer,OU=H/R,DC=fabrikam,DC=com", $ADS_SETTYPE_DN) 
ComInvoke Pathname -Method Retrieve @($ADS_FORMAT_X500_PARENT) 
ComInvoke PathName EscapedMode @($EscapedMode) 

Nazwa NameTranslate przykład:

ComInvoke -Method NameTranslate Init @(1, "domain.com") 
ComInvoke -Method NameTranslate Set @(8, "User001") 
ComInvoke -Method NameTranslate Get @(1) 

Or jeśli chcesz mieć wiele instancji, możesz najpierw utworzyć instancję ComObject, a następnie dostarczyć ją do funkcji ComInvoke na:

$NameTranslate = New-Object -ComObject NameTranslate 
ComInvoke -Method $NameTranslate Init @(1, "domain.com") 
ComInvoke -Method $NameTranslate Set @(8, "User001") 
ComInvoke -Method $NameTranslate Get @(1) 

do najnowszej wersji Invoke-ComObject patrz: https://powersnippets.com/invoke-comobject/

Powiązane problemy