title: User & Group Audit Script
body: <p>I am looking for help writing a powershell script that will query Active Directory and output a CSV.</p>
  
  <p>This script will list all groups and all users and signify with a character when a user belongs to that group.</p>
  
  <p>The output will look like this: <a href="https://imgur.com/1MfFv7Q" rel="nofollow">https://imgur.com/1MfFv7Q</a></p>
  
  <p>I've tried using dsquery and various other powershell methods, but none seem to work.</p>
  
  <p>I'm hoping someone here will have a different perspective on this and be able to help out.</p>
  
  <p>Thank you!</p>
  
  <p>Update 1:
  As requested, here's my code that I was trying to work with previously.</p>
  
  <pre><code>#Get a list of the groups
  $groups = Get-ADGroup -filter * -Properties Name | Select Name
  
  #iterate through groups array and append each with a comma
  $output = ForEach ($g in $groups){
  $topgroups.Add($g)
  $topgroups.Add(",")
  }
  
  #for each group, find out if the user is part of that group
  $output = ForEach ($g in $groups) {
   $results = Get-ADGroupMember -Identity $g.name -Recursive | Get-ADUser -Properties enabled, SamAccountName, givenname, surname,physicalDeliveryOfficeName
  
  ForEach ($r in $results){
   New-Object PSObject -Property @{
      GroupName = $g.Name
      Username = $r.name
      DisplayName = $r.displayname
    }
   }
  } 
  $output | Export-Csv -path c:\temp\output.csv -NoTypeInformation
  </code></pre>
  
  <p>Update 2:</p>
  
  <p>Added FTP Upload and some more information. Thanks again TheMadTechnician!</p>
  
  <p>My goal is to get this information from each of my clients, import this into SQL with SSIS with a timestamp, and then I can do can do comparison through sql reporting.</p>
  
  <p>Here's my script where it is currently:</p>
  
  <pre><code>New-Item c:\temp\audit -type directory
  
  $Domain = (gwmi WIN32_ComputerSystem).Domain
  $filename = $Domain + "_ADExport.csv"
  $fileoutput = "c:\temp\audit\" + $filename
  
  Remove-Item $fileoutput
  
  $GroupRef = @{}
  Get-ADGroup -filter * | ForEach{$GroupRef.Add($_.DistinguishedName,$_.Name)}
  
  $Users = Get-ADUser -Filter * -Prop MemberOf, passwordlastset, LastLogonDate
  ForEach($User in $Users){
   $LineItem = [PSCustomObject]@{'Enabled'=$User.Enabled;'First Name'=$User.givenname;'Last Name'=$User.surname;'Location'=$User.physicalDeliveryOfficeName;'Domain'=$Domain;'SAMAccountName'=$User.samaccountname;'LastLoggedOn'=$User.lastlogonDate;'PasswordLastSet'=$User.passwordlastset}
      $GroupRef.Values | ForEach{Add-Member -InputObject $LineItem -NotePropertyName $_ -NotePropertyValue ""}
      $User.MemberOf | ForEach{$LineItem.$($GroupRef["$_"]) = "X"}
  [Array]$Results += $LineItem
  }
  $Results|export-csv $fileoutput -notype
  
  
  #we specify the directory where all files that we want to upload  
  $Dir="C:/temp/audit/"
  
  #ftp server 
  $ftp = "ftp://8.8.8.8/"
  $user = "test" 
  $pass = "ThisIsARea11yL0NgPa33Word"  
  
  $webclient = New-Object System.Net.WebClient 
  
  $webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass)  
  
  #list every file
  foreach($item in (dir $Dir "*.csv")){ 
      "Uploading $item..." 
      $uri = New-Object System.Uri($ftp+$item.Name) 
      $webclient.UploadFile($uri, $item.FullName) 
   }
  </code></pre>
  
  <p>Update 3:</p>
  
  <p>Good afternoon:</p>
  
  <p>I've run into an issue where I am trying to restrict which OU this searches through:</p>
  
  <pre><code>$GroupRef = @{}
  $OUPATH = (Get-ADOrganizationalUnit -Filter 'Name -like "CLIENT_GROUPS"' | FT DistinguishedName -HideTableHeaders | Out-String).Trim()
  Get-ADGroup -SearchBase "$OUPATH" -Filter * | ForEach{$GroupRef.Add($_.DistinguishedName,$_.Name)}
  </code></pre>
  
  <p>The error is:</p>
  
  <pre><code>Exception setting "": "Cannot process argument because the value of argument "name" is not valid. Change the value of
  the "name" argument and run the operation again."
  At C:\Users\f12admin\Desktop\test.ps1:23 char:42
  +     $User.MemberOf | ForEach{$LineItem.$($GroupRef["$_"]) = "X"}
  +                                          ~~~~~~~~~~~~~~~
  + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationException
  + FullyQualifiedErrorId : ExceptionWhenSetting
  </code></pre>