I have now been creating a scrip that pulls all users from Active Directory, lists them up in alphabetical order and list up the groups each user belongs to.

Now I have some general programming knowledge but this is the first time I’m making a PowerShell scripts so I have been scouring the interwebs and the code below is what I have come up with so far.

#// Start of script
#// Original script found at https://community.spiceworks.com/
#// topic/381837-script-to-list-all-active-users-and-their-
#// group-membership-in-a-domain
#// Modified by arnfridur

#// Get year and month for csv export file
$DateTime = Get-Date -f "yyyy-MM"

#// Set CSV file Name
$CSVFile = "C:\ADUsers&Groups"+$DateTime+".csv"

#// Create empty array for CSV data
$CSVOutput = @()

#// Get all AD users in the domain
$ADUsers = Get-ADUser -Filter *

#// Set progress bar variables
$i=0
$tot = $ADUsers.count

foreach ($User in $ADUsers) {
  #// Set up progress bar
  $i++
  $status = "{0:N0}" -f ($i / $tot * 100)
  Write-Progress -Activity "Exporting AD Users" -status "Processing User $i of $tot : $status% Compleated" -PercentComplete ($i / $tot * 100)

  #// Ensure Groups variable is empty
  $Groups = ""

  #// Get groups and add to string
  $GroupArr = Get-ADUser -filter {Name -eq $ADUser.Name} | Get-ADPrincipalGroupMembership | select Name

  if ($GroupArr) {
      foreach ($Group in $GroupArr) {
          $Groups = $Groups + "," + $Group.Name
      }
      $Groups = $Groups.Substring(1,($Groups.Length) -1)
  }

  #// Set up hash table and add values
  $HashTab = $null
  $HashTab = [ordered]@{
    "Name" = $ADUsers.Name
    "Description" = $ADUsers.DisplayName
    "Groups" = $Groups
  }

  #// Add hash table to CSV data array
  $CSVOutput += New-Object PSObject -Property $HashTab
}

#// Export to CSV file
$CSVOutput | Sort-Object name | Export-CSV $CSVFile -NoTypeInformation

#// End of script

Now I’m am somewhat sure that this is a logic error that I have the most problem with part because it sort of works. That is it creates the .csv file but only lists up one user multiple times and the groups that user belongs to.

A fresh pair of eyes to spot the error in my script would be greatly appreciated.

6 Spice ups

Can you re-work the script? It seems off.

You first query AD to pull all users in, then you query AD again in the foreach loop.

It looks like the displayname property is not loaded when you query AD

Then you are using in the second foreach ‘$ADuser.name’ , rather than ‘$user’ as you should in the foreach, really it’s all over the place.

I removed the progress bar (just eye candy you can add it back once it does what you want), and it takes a while to run, but i think this is more what you wanted.

$DateTime = Get-Date -f "yyyy-MM"
$CSVFile  = "C:\ADUsers&Groups" + $DateTime + ".csv" 
$ADUsers  = Get-ADUser -Filter * -Properties displayname

$CSVOutput =
foreach ($User in $ADUsers) {
    $GroupArr = Get-ADPrincipalGroupMembership -Identity $user.SamAccountName

    [pscustomobject]@{
        "Name"        = $User.Name
        "Description" = $User.DisplayName
        "Groups"      = $GroupArr.name
    }
}

$CSVOutput | Sort-Object name | Export-CSV $CSVFile -NoTypeInformation

2 Spice ups

Yes, what you wrote is more what I want, now I just need it to list all the groups not just one group for each user.
I guess I could use foreach object do this …hmmm

Thank you by the way for the code. It is working almost as intended. The only thing I’m not figuring out is how to make it display the groups in the CSV file. Right now it is only showing up empty.

I added write-host to the code to see if it was going through stuff and it is. So why I can’t figure out the last bit is frustrating.

Am I misunderstanding something about how to write the groups down into the field?

[pscustomobject]@{
        "Name"    = $User.DisplayName
        "Groups"  = $GroupArr.Name

read about it here:

try like so:

$DateTime = Get-Date -f "yyyy-MM"
$CSVFile  = "C:\ADUsers&Groups" + $DateTime + ".csv" 
$ADUsers  = Get-ADUser -Filter * -Properties displayname

$CSVOutput =
foreach ($User in $ADUsers) {
    $GroupArr = Get-ADPrincipalGroupMembership -Identity $user.SamAccountName

    [pscustomobject]@{
        "Name"        = $User.Name
        "Description" = $User.DisplayName
        "Groups"      = $GroupArr
    }
}

$CSVOutput  | Sort-Object name |
Select-Object Name,Description,@{n='Groups';e={$_.Groups.name -join ';'}} |
Export-CSV $CSVFile -NoTypeInformation
1 Spice up

Thanks for the help with this and special thanks to you Neally.

I have learned a whole lot from this and here is the finished product.

#// Start of script
#// Original script found at https://community.spiceworks.com/
#// topic/381837-script-to-list-all-active-users-and-their-
#// group-membership-in-a-domain
#// Modified by arnfridur
#// Big thank you to Neally from the Spiceworks community for all the help

#// Get year and month for CSV export file.
$DateTime = Get-Date -f "yyyy-MM-dd"

#// Set CSV file name
$CSVFile = "C:\ADUsers&Groups"+$DateTime+".csv"

#// Going through the Users in AD.
$ADUsers = Get-ADUser -Filter * -Properties DisplayName

#// Setting up progress bar variables.
$i = 0
$tot = $ADUser.count

#// Setting up the output for the CSV file.
$CSVOutput =
  Foreach ($User in $ADUser) {
    #// Set up progress bar - visual eye candy.
    $i++
    $status = "{0:N0}" -f ($i / $tot *100)
    Write-Progress -Activity "Exporting AD Users" -status "Processing User $i of $tot : $status% Compleated" -PercentComplete ($i / $tot * 100)

    #// Now we get the groups a user is in.
    $Groups = Get-ADPrincipalGroupMembership -Identity $user.SamAccountName

    #// A place to store that data.
    [pscustomobject]@{
      "Name"   = $User.DisplayName
      "Groups" = $Groups
    }
  }

#// Create the CSV file, set up the csv file and export it.
$CSVOutput | Sort-Object name |
Select-Object Name,@{n='Groups';e={($_.Groups.name | Out-String).Trim()}} |
Export-CSV $CSVFile -Encoding UTF8

#// Enforcing the file to use the UTF8 format for silly characters.
#// End of script.

And yes I know the progress bar is just eye candy and not needed but sometimes I just want a visual confirmation that things are actually running. :slight_smile: