0

I want to return the group names in a semicolon delimited list for each AD user in an array. Here is what I have so far:

$ADuser = Get-ADUser -filter * -Properties * | ? {$_.employeeNumber -eq " 9408" -or $_.employeeNumber -eq "3816"} | Select-Object Name,SamAccountName,UserPrincipalName,DisplayName,GivenName,Surname,description,mail,Enabled,HomeDirectory,distinguishedname,MemberOf

foreach($user in $ADuser)
{

    $Groups = forEach ($group in $ADuser.memberOf)
    {
        (Get-ADGroup $group).name
    }

    $groupStr = $Groups -join ";"

    $ADuser = $ADuser | Select-Object Name,SamAccountName,UserPrincipalName,DisplayName,GivenName,surname,description,mail,Enabled,HomeDirectory,distinguishedname,@{n='Groups';e={$groupStr}}
}

This code works fine when $ADuser contains a single user. When $ADuser contains more than one user, I get the following error each time it tries to set Groups:

Get-ADGroup : Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again.
At line:8 char:22
+         (Get-ADGroup $group).name
+                      ~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-ADGroup], 
ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADGroup 

I expect the output to be like this for each $ADuser:

Name              : John.Doe
SamAccountName    : John.Doe
UserPrincipalName : John.Doe@mydomain.com
DisplayName       : John Doe
GivenName         : John
Surname           : Doe
description       : Joe is a person
mail              : John.Doe@mydomain.com
Enabled           : True
HomeDirectory     : \\fileserver\homefolders\John.Doe
distinguishedname : CN=John.Doe,OU=People,OU=my,DC=domain
Groups            : Group1;Group2;Group3;Group4
choooper2006
  • 63
  • 11
  • Change `$Groups = forEach ($group in $ADuser.memberOf)` to `$Groups = forEach ($group in $user.memberOf)` You are using `$user` as the delimiter for the `$ADUser` . If it were me I would change this to `$users` or `$ADUsers` to minimize confusion – jrider Sep 24 '18 at 21:13

2 Answers2

1

Looks like you have messed up with these two variables: $ADUsers and $users.

$ADuser = Get-ADUser -filter * -Properties * | ? {$_.employeeNumber -eq " 9408" -or $_.employeeNumber -eq "3816"} | Select-Object Name,SamAccountName,UserPrincipalName,DisplayName,GivenName,Surname,description,mail,Enabled,HomeDirectory,distinguishedname,MemberOf,Groups

    $Results = New-Object System.Collections.ArrayList

    foreach($user in @($ADuser))
    {

        $Groups = forEach ($group in @($user.memberOf))
        {
            (Get-ADGroup $group).name
        }
        $user.Groups = $Groups -join ';'
        [Void]$Results.Add($user)
    }

    $Results
Kirill Pashkov
  • 3,118
  • 1
  • 15
  • 20
  • Good point, but note that `@(...)` is never needed in an enumeration context: `foreach` will happily enumerate a scalar too (producing, by definition, a _single_ iteration). – mklement0 Sep 25 '18 at 02:47
  • I was able to make this work. However, when I used the `-or` operator, the script seemed to ignore it and only pulled the data where `$_.employeeNumber -eq "3816"`. Any thoughts on why? – choooper2006 Sep 25 '18 at 13:37
  • @BobbyZimmerman, could that be " 9408" specified with a typo? leading space before digits makes comparison go wrong. – Kirill Pashkov Sep 25 '18 at 13:39
  • @Kirill Pashkov, yes, that would be the issue. – choooper2006 Sep 25 '18 at 13:42
0

Kirill Pashkov's helpful answer solves your immediate problem.

To take a step back:

Your symptoms suggest that you're running on PSv2, which has the following implications:

  • Member-access enumeration (PSv3+) isn't available; that is, if $ADuser is an array (a collection), you cannot use .memberOf to implicitly collect the .memberOf property values of its elements.

  • A foreach (...) { ... } loop executes its loop body even if the value to enumerate is $null - in PSv3+ the loop body isn't executed at all.


That said, your code can presumably be reduced to this one command:

Get-ADUser -Properties * |
  ? {$_.employeeNumber -eq " 9408" -or $_.employeeNumber -eq "3816"} | 
    Select-Object Name, 
      SamAccountName,
      UserPrincipalName,
      DisplayName,       
      GivenName,
      Surname,
      description,
      mail,
      Enabled,
      HomeDirectory,
      distinguishedname,
      @{ 
        n='Groups';
        e={ ($_.memberOf | Get-AdGroup | Select-Object -ExpandProperty Name) -join ";" } 
      }
mklement0
  • 382,024
  • 64
  • 607
  • 775