0

I am trying to read group membership of computers from a particular OU and write to a CSV file. The input criteria for the group membership is like if the computer is part of say "admin" and i need the csv file in the below format

---------------------------------------------------------
Computer   Group1  Group2  Group3 Group4
ABCD       admin1   admin2 admin3 admin4
EFGH                admin2  admin3
XYZZ       admin1                  admin4
--------------------------------------------------------------
but end up like this.
---------------------------------------------------------
Computer   Group1  Group2  Group3 Group4
ABCD       admin1  admin2  admin3 admin4
EFGH       admin2  admin3
XYZZ       admin1  admin4
--------------------------------------------------------------

The code is like this

$All_computer = Get-ADComputer -Filter * -Property * -SearchBase $ou -Server $server | Select-object Name,DNSHostName,Description,memberof 
$computerExport = $All_computer | 
ForEach-Object {

  $ComputerName = $_.Name
  $Description = $_.description
  $DNSHostname = $_.DNSHostName
  $memberof = $_.memberof
  
$groups = $memberof.where{$_ -like  "*$unput_group*"} 
$Group_member = [pscustomobject]@{
        Workstation = $ComputerName
        Comp_Description = $Description
        DNS_Hostname = $DNSHostname
    }
$i = 0

foreach($group in $Groups) 
{
$i++
$member = $group.split('=')[1].split(',')[0]
$Group_member | add-member -MemberType NoteProperty -Name "Group$i" -Value $member
}

$Group_member
  } 

 }

$computerExport | export-csv .\Membership_status.csv -NoTypeInformation

What do i need to do to get the group membership to populate to proper column.

Enigma
  • 123
  • 1
  • 13

2 Answers2

0

Well of course it does. I mean it's doing what you're asking it to do. You're only adding the number of properties to the custom object that is found from the where object query. I am really struggling to understand what you're trying to do this for but I THINK what you really want is for each object to have all the possible properties but to have null values for those that don't match that particular computer or better yet to use a boolean.

So... Maybe like this:

[string]$GroupSearch = "admin"

$All_computer = Get-ADComputer -Filter * -Property DNSHostName, Description, memberof -SearchBase $ou -Server $server | Select-Object Name, DNSHostName, Description, memberof 
$MatchedGroups = $All_Computer.MemberOf | Sort -Unique | ?{$_.Name -match $GroupSearch}

$computerExport = ForEach ($C in $All_computer) {
    $Group_member = [pscustomobject]@{
        Workstation      = $($C.Name)
        Comp_Description = $($C.Description)
        DNS_Hostname     = $($C.DNSHostName)
    }

    ForEach ($group in $MatchedGroups) {
        [string]$GrpName = $($group.split('=')[1].split(',')[0])
        If ($C.MemberOf -contains $group) {
            $Group_member | Add-Member -MemberType NoteProperty -Name $GrpName -Value $true
        } else {
            $Group_member | Add-Member -MemberType NoteProperty -Name $GrpName -Value $false
        }
    }
    $Group_member
} 

$computerExport | Export-Csv .\Membership_status.csv -NoTypeInformation
mOjO
  • 98
  • 6
0

If I understand the question, you need to get all computers from a certain OU that are member of group(s) with a similar partial name. To do that, I would suggest creating an array of computer objects at first with a temporary extra property called 'Groups' in which the group names that match the partial name are stored.

Later, we'll put these in the correct order as new properties called 'Group1', 'Group2' etc.

# the partial groupname to search for
$unput_group = 'admin'

# Get-ADComputer by default already returns these properties:
# DistinguishedName, DNSHostName, Enabled, Name, ObjectClass, ObjectGUID, SamAccountName, SID,  UserPrincipalName

# get an array of computer objects that are member of 'admin*' group(s) with the desired properties
# one extra temporary property is added which contains an array of 'admin*' group names
$All_computer = Get-ADComputer -Filter * -Property Description, MemberOf  -SearchBase $ou -Server $server |
                Where-Object { $_.MemberOf -match $unput_group} |
                Select-Object @{Name = 'Workstation'; Expression = {$_.Name}},
                              @{Name = 'Comp_Description'; Expression = {$_.Description}},
                              @{Name = 'DNS_Hostname'; Expression = {$_.DNSHostName}},
                              @{Name = 'Groups'; Expression = { @($_.MemberOf |
                                        Where-Object { $_ -match "CN=($unput_group[^,]+)" } | 
                                        ForEach-Object { $matches[1] }) }}

# get all the group names from the computers we have collected and sort unique
$All_Groups = $All_computer.Groups | Sort-Object -Unique

# build a lookup hashtable with property names ('Group1', 'Group2' etc)
$hash = [ordered]@{}
for ($i = 1; $i -le $All_Groups.Count; $i++) {
    $hash["Group$i"] = $All_Groups[$i - 1]
}

# now loop through the collection and add the group properties in order
$result = foreach ($computer in $All_computer) {
    foreach ($propertyName in $hash.Keys) {
        $group = if ($computer.Groups -contains $hash[$propertyName]) { $hash[$propertyName] }
        $computer | Add-Member -MemberType NoteProperty -Name $propertyName -Value $group
    }
    # output the updated object and remove the temporary 'Groups' property
    $computer | Select-Object * -ExcludeProperty Groups
}

# finally, save the results to disk
$result | Export-Csv -Path .\Membership_status.csv -NoTypeInformation
Theo
  • 57,719
  • 8
  • 24
  • 41
  • Theo... thanks for this.. this one filters out computers with the partial name.. Much appreciated. – Enigma Sep 17 '21 at 13:04