Author Posts

September 29, 2014 at 6:25 am

Hi there

I am scratching my head over a particular script and was hoping someone might help me out.

The purpose of my script is to use get a list of group members for multiple groups and out put them to a txt file. The script I have created so far does the job but I can only get it to output to multiple txt files, one for each group. The script is:

$groups = Get-Content C:\grouplist.txt

foreach($Group in $Groups)
{
Get-ADGroupMember -Id $Group | select @{Expression={$Group};Label="Group Name"},samaccountname | Export-CSV C:\$group.txt -NoTypeInformation
}

The text file "grouplist.txt" has a list of Active directory group names (group1, group2, group3 etc). The output will product a new text file for each group, below is an example for group1.txt

"Group Name","samaccountname"
"group1", "user1"
"group1", "user2"
"group1", "user3"

What I would like is a single text file to be created like the following:

Text file called grouplistresult.txt

"Group Name","samaccountname"
"group1", "user1"
"group1", "user2"
"group2", "user1"
"group2", "user3"
"group3", "user2"
"group3", "user3"

Hope that makes sense to everyone!

Many thanks

Orionuk

September 29, 2014 at 6:30 am

Just push all of the Get-ADGroupMember output to an object variable and then dump the variable to a file:

$groups = Get-Content C:\grouplist.txt

foreach($Group in $Groups)
{
$adusers = Get-ADGroupMember -Id $Group | select @{Expression={$Group};Label="Group Name"},samaccountname
}

$adusers | Export-CSV C:\allgroups.txt -NoTypeInformation

September 29, 2014 at 11:22 pm

Hi Charles

Thank you for replying. I did try that but it did not work as expected. What appears to happen is that if grouplist.txt contains multiple names then the result.txt only shows the last name in the list. So, for example, if the grouplist.txt contains:

group1
group2
group3

Then the result will only show group3. It is almost like each entry overwrites the last one.

I was thinking about using an array but not 100% certain how to encorporate it.

Regards

September 30, 2014 at 2:07 am

You can test if this works. It's a little more programatic but it should do the job.


    $groups = Get-Content C:\grouplist.txt
foreach($Group in $Groups)
{
    $users=Get-ADGroupMember -Id $Group
    foreach($user in $users)
    {
        add-content -Path c:\userlist.txt -Value "$group,$($user.samaccountname)"
    }
}

September 30, 2014 at 4:44 am

@Charles...very close. You can do this numerous ways, but assigning a variable to the for loop will take all results and place them into the variable

$groups = "Group1","Group2"
$result = foreach($group in $groups){Get-ADGroupMember -Identity $group | Select @{Label="Group Name";Expression={$group}}, SamAccountName}
$result

Another common method is appending the data. The reason you are only seeing the last group is because the variable is being overwritten. In this method, you need to create a blank array or you'll receive an op_Addition error because you can't add to nothing.

$groups = "Engineering","RES Users"
$result =@()
foreach($group in $groups){$result += Get-ADGroupMember -Identity $group | Select @{Label="Group Name";Expression={$group}}, SamAccountName}
$result

@Adi. One of the best things about Powershell is the ability to easily generate objects. Writing output in a for each is antiquated way of getting data into a file. in the above example, you can now take $result and just pipe it to Out-File (or Export-CSV or Export-CliXML or even ConvertTo-HTML):

$result | Out-File C:\Test\test.txt

Additionally, since you have the result you could Sort it with Sort-Object, or even figure you which users are in both groups (count 2 would indicate 2 instances of the SamAccountName):

$result | Group-Object SamAccountName -NoElement

Once you have an object you can leverage the power in Powershell and not export to a file to read later or put in Excel to review.

September 30, 2014 at 5:39 am

Yep, Rob, you're right... I should have caught that the variable was being overwritten. Sorry about that, Orion. Rob's second example is what I was thinking, but I didn't double-check myself before I posted... Guess I hadn't had enough coffee yet!

September 30, 2014 at 6:41 am

Thanks for the updates! I took those plus found some other examples and came up with the following which works perfectly:

$resultsarray =@()

$groups = Get-Content C:\grouplist.txt

foreach ($group in $groups) {

$groupmember = new-object PSObject

$groupmember = Get-ADGroupMember -Id $group | select samaccountname,name,@{Expression={$group};Label="Group Name"}

$resultsarray += $groupmember

}

$resultsarray| Export-csv -path C:\grouplistresult.txt -notypeinformation

September 30, 2014 at 7:55 am

You are blending some other methods, this is simple and clean:

$groups = Get-Content C:\grouplist.txt
$resultsarray =@()
foreach ($group in $groups) {
    $resultsarray += Get-ADGroupMember -Id $group | select samaccountname,name,@{Expression={$group};Label="Group Name"}
}

$resultsarray| Export-csv -path C:\grouplistresult.txt -notypeinformation

When you use Select(-Object), it creates a Powershell object, so there is no need for the New-Object line. If you are generating a custom PSObject, you would use New-Object like so:

$locations = "houston", "washington", "nevada"
$results = foreach ($location in $locations) {
    $properties = @{ "ServerName" = ("{0}001" -f $location);
                     "Location" = $location.ToString().ToUpper();
                     "SiteCode" = $location.Substring(0,3).ToUpper();
                   }
    
    New-Object -TypeName PSObject -Property $properties
}

$results  | Format-Table -AutoSize

Result:

ServerName    SiteCode Location  
----------    -------- --------  
houston001    HOU      HOUSTON   
washington001 WAS      WASHINGTON
nevada001     NEV      NEVADA    

Since we're just working with a string, we can't use Select-Object but we want to work with the string to create 3 seperate items for a Powershell object. The properties of a New-Object takes hash table input, so we create a hashtable with our ServerName, SiteCode and Location and use the $location variable to create different outputs. You could use the $results – @() and results += method, but again I like assigning the variable to the for loop. So, if you can leverage Select-Object and calculated expressions (e.g. @{Label="MyVar";Expression={"MyValue"}} to generate an object I would let Select do the heavy lifting. If you can't use Select, then you can create a New-Object like above.

April 19, 2016 at 12:10 pm

I am trying to do the same thing with one additional bit of information. I would like to also be able to get the description field of the group outputted to the CSV file as well. Is there anyway to do this using the above script?

April 19, 2016 at 12:18 pm

$groups = Get-Content C:\grouplist.txt

$results = foreach ($group in $groups) {
    Get-ADGroupMember $group | select samaccountname, name, @{n='GroupName';e={$group}}, @{n='Description';e={(Get-ADGroup $group -Properties description).description}}
}

$results

$results | Export-csv C:\grouplistresult.txt -NoTypeInformation

April 19, 2016 at 12:41 pm

Thank you. Worked perfectly!