Benutzer mit den meisten Antworten
Beschreibung von AD-Gruppen kann nicht gelesen werden

Frage
-
Hallo zusammen,
ich habe ein Script geschrieben um alle Member (inkl. Beschreibung) einer lokalen Gruppe auszulesen. Die Beschreibung kommt auch einwandfrei mit bei Domain Accounts und Domain Groups, aber leider nur, wenn diese Universal sind. Die beiden entscheidenden Code-Schnipsel sind..
$Group = [ADSI]"WinNT://$Computer/$LocalGroupName" $Members = @($Group.Invoke("Members")) $MemberName = $Member.GetType().InvokeMember("Name","GetProperty",$null,$Member,$null) $MemberType = $Member.GetType().InvokeMember("Class","GetProperty",$null,$Member,$null) $MemberDescription = $Member.GetType().InvokeMember("Description","GetProperty",$null,$Member,$null) $MemberPath = $Member.GetType().InvokeMember("ADSPath","GetProperty",$null,$Member,$null)
Bei Domain Local Groups habe ich nun das Problem, dass die Beschreibung mit folgendem Fehler nicht ausgelesen werden kann:
Exception calling "InvokeMember" with "5" argument(s): "The group name could not be found. " At line:108 char:33 + $MemberDescription = $Member.GetType().InvokeMem ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : COMException
Alle anderen Eigenschaften (Name, Class, ADSPath) funktionieren. Stelle ich die Gruppe auf Universal um, funktioniert auch die Abfrage der Beschreibung sofort, ebenso wie bei Benutzern.
Habt ihr dafür eine eine Erklärung und noch besser eine Lösung?
Gruß,
Michael
Antworten
-
Der WinNT: Provider ist ein Uhrgestein aus Windows NT Zeiten.
Dieser unterstützt nur Sachen die auch schon unter Windows NT vorhanden waren.
Die Universellen Gruppen sind das einzige was Windows NT und das Moderne AD gemeinsam haben.Um das moderne Active Directory abzufragen musst du den LDAP: Provider benutzen!
Siehe Erklärung hier: WinNT vs. LDAP
http://www.rlmueller.net/WinNT_LDAP.htmungefähr so:
$Group = [ADSI]"WinNT:////$Computer/$LocalGroupName" $Members = @($Group.Invoke("Members")) ForEach($Member in $Members) { $ADSPath = $Member.GetType().InvokeMember("ADSPath","GetProperty",$null,$Member,$null) $Name = $Member.GetType().InvokeMember("Name","GetProperty",$null,$Member,$null) # Abfragen ob es ein lokaler oder ein Member aus der Domäne ist If(-Not ($ADSPath -Like "*$($env:COMPUTERNAME)*")) { # Domänen Member! # LDAP Provider benutzen $AdsiSearcher = [AdsiSearcher]'' $AdsiSearcher.Filter = "(sAMAccountName=$Name)" $SearchResult = $AdsiSearcher.FindOne() $MemberName = $SearchResult.Properties.name $MemberDescription= $SearchResult.Properties.description } Else { # Lokaler Member! $MemberName = $Name $MemberDescription = $Member.GetType().InvokeMember("Description","GetProperty",$null,$Member,$null) } $MemberName $MemberDescription }
PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
auf der deutschsprachigen PowerShell Community
Mein 21 Teiliger PowerShell Video Grundlehrgang
Deutsche PowerShell Videos auf Youtube
Folge mir auf:
Twitter | Facebook | Google+- Bearbeitet Peter Kriegel Dienstag, 28. Oktober 2014 16:00
- Als Antwort markiert mhedv Mittwoch, 29. Oktober 2014 09:08
Alle Antworten
-
Der WinNT: Provider ist ein Uhrgestein aus Windows NT Zeiten.
Dieser unterstützt nur Sachen die auch schon unter Windows NT vorhanden waren.
Die Universellen Gruppen sind das einzige was Windows NT und das Moderne AD gemeinsam haben.Um das moderne Active Directory abzufragen musst du den LDAP: Provider benutzen!
Siehe Erklärung hier: WinNT vs. LDAP
http://www.rlmueller.net/WinNT_LDAP.htmungefähr so:
$Group = [ADSI]"WinNT:////$Computer/$LocalGroupName" $Members = @($Group.Invoke("Members")) ForEach($Member in $Members) { $ADSPath = $Member.GetType().InvokeMember("ADSPath","GetProperty",$null,$Member,$null) $Name = $Member.GetType().InvokeMember("Name","GetProperty",$null,$Member,$null) # Abfragen ob es ein lokaler oder ein Member aus der Domäne ist If(-Not ($ADSPath -Like "*$($env:COMPUTERNAME)*")) { # Domänen Member! # LDAP Provider benutzen $AdsiSearcher = [AdsiSearcher]'' $AdsiSearcher.Filter = "(sAMAccountName=$Name)" $SearchResult = $AdsiSearcher.FindOne() $MemberName = $SearchResult.Properties.name $MemberDescription= $SearchResult.Properties.description } Else { # Lokaler Member! $MemberName = $Name $MemberDescription = $Member.GetType().InvokeMember("Description","GetProperty",$null,$Member,$null) } $MemberName $MemberDescription }
PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
auf der deutschsprachigen PowerShell Community
Mein 21 Teiliger PowerShell Video Grundlehrgang
Deutsche PowerShell Videos auf Youtube
Folge mir auf:
Twitter | Facebook | Google+- Bearbeitet Peter Kriegel Dienstag, 28. Oktober 2014 16:00
- Als Antwort markiert mhedv Mittwoch, 29. Oktober 2014 09:08
-
Hallo Michael !
War mit meiner Antwort noch nicht zufrieden, weil in dem Beispiel mit dem [AdsiSearcher] nicht berücksichtigt wird, das man auch verschiedenen Domänen abfragen kann.
Allgemein wird für den Umgang mit Lokalen Gruppen empfohlen NICHT den WinNT: Provider zu benutzen, weil der keine Active Directory Pfade unterstützt und es schwer ist, sauber an die Domänen Informationen eines Members zu kommen.
Besser ist es WMI (CIM) für Lokale Gruppen zu benutzen.
Ich habe meine eigen Funktion nochmal überarbeitet. Bitte nutze diese!Function Get-WMILocalGroupMembers { <# .Synopsis Function to get all members of a local group with WMI .DESCRIPTION Function to get all members of a local group with WMI To get all User members recursive use the -recurse switchparameter If you provide the -Computername Parameter the members of a local group on that system are retrieved .PARAMETER Name Name of the group to retrieve the members. The Name of the locale Administrators group is the default (The group name is retrived by SID of S-1-5-32-544) .PARAMETER Domain The Domain of the group The default domain is the local Computer .PARAMETER Recursive Specifies to get all User members (non containers) in the hierarchy of a group. No container members (of type group) are returned! .PARAMETER ComputerName Specifies the target computer for the management operation. The value can be a fully qualified domain name, a NetBIOS name, or an IP address. To specify the local computer, use the local computer name, use localhost, or use a dot (.) . This parameter does not rely on Windows PowerShell remoting, which uses WS-Management. You can use the ComputerName parameter of Get-WmiObject even if your computer is not configured to run WS-Management remote commands. To specify the local computer, such as in a list of computer names, use "localhost", the local computer name, or a dot (.). The local computername is the default. .EXAMPLE Get-WMILocalGroupMembers Retrieves all members from the locale system and the locale Administrator group .EXAMPLE Get-WMILocalGroupMembers -Name -ComputerName 'Server1' Retrieves all members from the remote system 'Server1' and the locale Administrator group .EXAMPLE Get-WMILocalGroupMembers -Name 'Remote Desktop Users' Retrieves all members from the locale system and the locale group with Name 'Remote Desktop Users'. .EXAMPLE Get-WMILocalGroupMembers -Name 'Remote Desktop Users' -Recurse Retrieves all User members recursive from the locale system and the locale group with Name 'Remote Desktop Users'. .EXAMPLE Get-WMILocalGroupMembers -Name -ComputerName 'Server1' -Name 'Remote Desktop Users' Retrieves all members from the remote system 'Server1' and the group with Name 'Remote Desktop Users' which is a local group on 'Server1'. .EXAMPLE Get-WMILocalGroupMembers -Name 'DomainAdmins' -Domain 'Avalon' Retrieves all members from the the group with Name 'DomainAdmins' from the Domain 'Avalon' (Avalon\DomainAdmins) The local system is used to retrieve the members. .EXAMPLE Get-WMILocalGroupMembers -ComputerName 'Server1' -Name 'DomainAdmins' -Domain 'Avalon' Retrieves all members from the the group with Name 'DomainAdmins' from the Domain 'Avalon' (Avalon\DomainAdmins) The remote system 'Server1' is used to retrieve the members. .EXAMPLE $Group = Get-WmiObject -Query "Select * From Win32_Group Where LocalAccount = TRUE And SID = 'S-1-5-32-544'" Get-WMILocalGroupMembers -Win32Group $Group Retrieves all members from the given WMI Win32_Group from the locale system. .EXAMPLE Get-WmiObject -Query 'Select * From Win32_Group Where LocalAccount = TRUE' | Get-WMILocalGroupMembers Retrieves all local Groups of the currens System and retrieves all members from this groups. .INPUTS None You cannot pipe input to Get-WMILocalGroupMembers. .OUTPUTS PSObject with following NoteProperties: ParentName The name of the group which the member is member of ParentDomain The domain of the group which the member is member of Name The name of the groupmember Domain The domain of the groupmember SID The SID of the groupmember FullName The FullName of the groupmember in Active Directory also knowen as Displayname This is filled on Users only Type The Type of the groupmember Valid typevalues are 'User' or 'Group' Description The value out of the description field from the member ComputerName .NOTES Author: Peter Kriegel Initial Version: 1.0.0 04.February.2014 Current Version 1.1.0 29.Oktober.2014 Added begin{} and process{} blocks Added Pipeline Support for the -Win32Group Parameter #> [CmdletBinding(DefaultParametersetname='DomainAndName')] param( [Parameter( ParametersetName='Win32Group', ValueFromPipeline = $true )] [ValidateNotNullOrEmpty()] $Win32Group, [Parameter( ParametersetName='DomainAndName' )] [String]$Name, [Parameter(ParametersetName='DomainAndName')] [ValidateNotNullOrEmpty()] [String]$Domain = $env:ComputerName, [ValidateNotNullOrEmpty()] [String[]]$ComputerName = @($env:ComputerName), [Switch]$Recursive ) begin { Function Intern { param( [String]$Name, [String]$Domain, [String]$ComputerName, [Switch]$Recursive ) # Get all members from the given Localgroup from the given ComputerName Get-WmiObject -computername $ComputerName -query "Select * From win32_groupuser Where GroupComponent=""Win32_Group.Domain='$Domain',Name='$Name'""" | ForEach-Object { # detect Type of Account If($_.PartComponent -Like '*Win32_UserAccount*' ) { $Type = 'User' } ElseIf ($_.PartComponent -Like '*Win32_Group*') { $Type = 'Group' If($Recursive) { If ($PreventCircularReference -notcontains $_.PartComponent) { $PreventCircularReference += $PreventCircularReference $Group = ([WMI]($_.PartComponent)) Intern -Name $Group.Name -Domain $Group.Domain -ComputerName $ComputerName -Recurse Return } Else { Return } } } # Convert the PartComponent to an vital WMI object $Result = [WMI]($_.PartComponent) | Select-Object ParentName,ParentDomain,Name,Domain,SID,FullName,Type,Description,ComputerName $Result.ParentName = $Name $Result.ParentDomain = $Domain $Result.ComputerName = $ComputerName $Result.Type = $Type $Result } # end of ForEach-Object } #end of Function Intern # create the 'static' variable for the internal Function to prevent circular references New-Variable -Name PreventCircularReference -Value @() -Option 'AllScope' } # end of begin block process { # test Parameters If($Win32Group -or ($PsCmdlet.ParameterSetName -eq 'Win32Group')) { If($Win32Group.__CLASS -notlike '*Win32_Group*') { $exception = New-Object System.ArgumentException 'Parametervalue is not a type of WMI/CIM class Win32_Group','Win32Group' $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception,'Win32Group','InvalidArgument',$null $PsCmdlet.WriteError($errorRecord) Return } # Translate group to Name and Domain $Name = $Win32Group.Name $Domain = $Win32Group.Domain } # set default for groupname If([String]::IsNullOrEmpty($Name)) { # For internationalization support we get the Name of the Administrators Group by SID $Name = (Get-WmiObject -ComputerName $ComputerName -Query "Select * From Win32_Group Where LocalAccount = TRUE And SID = 'S-1-5-32-544'").Name } # call internal Function to do the work Intern -Name $Name -Domain $Domain -ComputerName $ComputerName -Recursive:$Recursive } # end of process block }
Schau dir dort die Beispiele an!
PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
auf der deutschsprachigen PowerShell Community
Mein 21 Teiliger PowerShell Video Grundlehrgang
Deutsche PowerShell Videos auf Youtube
Folge mir auf:
Twitter | Facebook | Google+