Search code examples
powershellactive-directorypsmemberof

Powershell export Active Directory User data not complete


I have to export the user data of accounts before we delete them. The problem is, that not all group memberships are written in the .txt file (example below).

This is the code:

              Get-ADUser  -Properties * -Filter "cn -eq '$name'" |
              format-list -property @{Label = "Name";Expression = {$_.sAMAccountName}},
              @{Label = "Initials";Expression = {$_.initials}},    
              @{Label = "Email";Expression = {$_.Mail}},
              @{Label = "Groups";Expression = {%{(Get-ADPrincipalGroupMembership $name | select -expandproperty name)}}},
              @{Label = "Creation";Expression = {$_.whenCreated}},
              @{Label = "Deletion";Expression = {%{(Get-Date)}}},
              @{Label = "Last change";Expression = {$_.whenChanged}}  |

              #write data into txt file

             Out-File -append "C:\temp\deleted.txt" -Encoding utf8 

And this is the output:


Name            : John Doe
Initials        : Jdo
Email           : [email protected]
Groups          : {Domain-User, Remotedesktopuser, Administrator, Share-User...}
Creation        : 23.03.2018 13:36:44
Deletion        : 17.12.2018 08:46:30
Last Change     : 16.12.2018 10:42:21

Solution

  • It's really not the Format-List causing this, the same thing would happen with a select, though using Format-* like this is not really a thing. This will be a list by default, so, no real reason to use it for what you are after.

    You don't even need that expand.

    The issue is the fact that you cannot use that loop and expect that to work, the auto formatters won't allow it. You have to directly handle the collection, something like this...

    Get-ADUser  -Properties * -Filter * |
    Select-Object -property @{Label = "Name";Expression = {$_.sAMAccountName}},
    @{Label = "Initials";Expression = {$_.initials}},    
    @{Label = "Email";Expression = {$_.Mail}},
    @{Label = "Creation";Expression = {$_.whenCreated}},
    @{Label = "Deletion";Expression = {%{(Get-Date)}}},
    @{Label = "Last change";Expression = {$_.whenChanged}},
    @{Label = "Groups";Expression = {%{(Get-ADPrincipalGroupMembership $_.SamAccountName).Name -join ','}}} |
    Out-File -append "C:\temp\deleted.txt" -Encoding utf8 
    Get-Content -Path "C:\temp\deleted.txt" 
    
    # Results
    
    Name        : Administrator
    Initials    : 
    Email       : [email protected]
    Creation    : 3/31/2017 8:02:15 PM
    Deletion    : 12/17/2018 4:07:52 AM
    Last change : 12/9/2018 7:23:22 PM
    Groups      : Domain Users,Administrators,Schema Admins,Enterprise Admins,Domain Admins,Group Policy Creator Owners,Organization Management,Recipient 
                  Management,ADSyncAdmins,ADRMSSuperUsers
    …
    

    Update as per the OP comment / question

    No worries, glad it worked for you.

    As for ...

    Would you mind to explain me what the difference between that two AD Group commands are?

    If you mean ...

    Get-ADPrincipalGroupMembership Administrator | select -expandproperty name
    ... vs ... (Get-ADPrincipalGroupMembership Administrator).Name

    ... they are ostensibly the same thing, each producing and array list of group names.

    # use the expand switch to show the group name list
    Get-ADPrincipalGroupMembership Administrator | select -expandproperty name
    
    Domain Users
    Administrators
    Schema Admins
    Enterprise Admins
    Domain Admins
    Group Policy Creator Owners
    Organization Management
    Recipient Management
    ADSyncAdmins
    ADRMSSuperUsers
    
    # Use the property to view the group name list
    (Get-ADPrincipalGroupMembership Administrator).Name
    
    Domain Users
    Administrators
    Schema Admins
    Enterprise Admins
    Domain Admins
    Group Policy Creator Owners
    Organization Management
    Recipient Management
    ADSyncAdmins
    ADRMSSuperUsers
    

    However, the formatters, when the data is being serialized, will try to put this all on one line. Yet, they will truncate this to fit the screen / page width. So, if you want a different layout, then either you need to go in and muck with the default formatter files, or handle it is code. Personally, I never try to mess with them, and just work to handle it in code. So, this...

    (Get-ADPrincipalGroupMembership Administrator).Name -join ','
    

    ... just says, I know this collection is an array list. I know that this will get truncated per screen/page width, so, concatenate this list of strings as one string and autowrap.

    You could have done the same thing with your original expand the same way ...

    (Get-ADPrincipalGroupMembership Administrator | select -expandproperty name) -join ','
    

    I stuck the groups list at the end for aesthetic reasons as well as the shorter form, as I prefer not writing unnecessary code or using unneeded options as much as possible. Everyone has their preferences.