Getting AD groups and their users - powershell

I've been trying to get a list of all the groups in our AD environment (with the description) and their members and output it to a CSV file. Ideally the users would be shown under their group. The script I've been trying to use is:
Import-Module ActiveDirectory
Get-ADGroup -Filter * -Properties Description |
Select-Object Name, Description |
ForEach-Object {
Get-ADGroupMember -Identity $_.DistinguishedName -Recursive |
Get-ADObject -Properties SamAccountname, Title, Department |
Select-Object Name, SamAccountName, Title, Department, DistinguishedName, ObjectClass
} | Export-Csv -Path c:\temp\ADGrab.csv -NoTypeInformation
The error I keep getting is as follows:
Get-ADGroupMember : Cannot validate argument on parameter 'Identity'. The argument
is null or empty. Supply an argument that is not null or empty and then try the
command again.
At C:\Users\j_kennedy_ta\AppData\Local\Temp\9\2898ceb2-a6cf-4fbf-9341-e651dad2145d.ps1:4 char:28
+ Get-ADGroupMember -Identity <<<< $_.distinguishedname -Recursive |
+ CategoryInfo : InvalidData: (:) [Get-ADGroupMember], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADGroupMember

Without the nasty Select-Object and with group information in the CSV file:
Import-Module ActiveDirectory
Get-ADGroup -Filter * -Properties Description |
ForEach-Object {
# Store for later use
$groupName = $_.Name
$groupDescription = $_.Description
Get-ADGroupMember -Identity $_.DistinguishedName -Recursive |
Get-ADObject -Properties SamAccountname, Title, Department |
Select-Object Name, SamAccountName, Title, Department, DistinguishedName, ObjectClass, ` # Mind the gap
# Calculated properties with group information
#{ name = "GroupName"; expression = $groupName }, `
#{ name = "GroupDescription"; expression = $groupDescription }
} | Export-Csv -Path c:\temp\ADGrab.csv -NoTypeInformation

Related

Powershell variable issue Get-Content and Get-ADGroup

I'm trying to figure out the reason why I can run the script using variable $groups with Get-Content but it wont work if variable $groups goes with Get-ADGroup list I did below...
Block that works:
$groups = Get-Content C:\groups.csv
$results = #()
$file = "C:\Usuarios_Grupos_Darwin_AD.csv"
foreach($Group in $Groups) {
$results +=Get-ADGroupMember -Id $Group -Recursive | %{Get-ADUser -Identity $_.SamAccountName -Properties Enabled,Name} | Select #{Expression={$Group};Label=”Group Name”},SamAccountName,Name,Enabled
}
$results | export-csv -notypeinformation -Delimiter ";" -path $file
Block that's not working:
(only the first line has been changed)
$groups = Get-ADGroup -Filter {Name -like '*Darwin*'} -Properties * | select -property Name
$results = #()
$file = "C:\Usuarios_Grupos_Darwin_AD.csv"
foreach($Group in $Groups) {
$results +=Get-ADGroupMember -Id $Group -Recursive | %{Get-ADUser -Identity $_.SamAccountName -Properties Enabled,Name} | Select #{Expression={$Group};Label=”Group Name”},SamAccountName,Name,Enabled
}
$results | export-csv -notypeinformation -Delimiter ";" -path $file
Here is the error:
Get-ADGroupMember : Cannot bind parameter 'Identity'. Cannot create object of type "Microsoft.ActiveDirectory.Management.ADGroup". The adapter cannot set the value of property
"Name".
At line:11 char:34
+ $results +=Get-ADGroupMember -Id $Group -Recursive | %{Get-ADUser -Id ...
+ ~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ADGroupMember], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.ActiveDirectory.Management.Commands.GetADGroupMember
I'm trying to embed the output list all in one script without having to generate csv with another script.
Thanks in advance !!
A few notes about your code:
the -Filter parameter should be a string, not a scriptblock
using $results += is very costly because the entire array needs to be rebuilt in memory on each addition
Get-ADGroupMember can return also computer and (when not used with -Recursive) also group objects, not just users, so you cannot pipe directly to Get-ADUser
never use -Properties * if all you want is one single property
Try this:
# Get-ADGroup already returns objects with these properties:
# DistinguishedName, GroupCategory, GroupScope, Name, ObjectClass, ObjectGUID, SamAccountName, SID
$groups = Get-ADGroup -Filter "Name -like '*Darwin*'"
$file = "C:\Usuarios_Grupos_Darwin_AD.csv"
# let PowerShell collect the objects for you instead of using +=
$results = foreach($Group in $Groups) {
# Get-ADGroupMember can return objects of type users and computers (also groups when used without -Recursive)
# so filter the result to get only user objects
$Group | Get-ADGroupMember -Recursive | Where-Object { $_.objectClass -eq 'user' } | ForEach-Object {
$_ | Get-ADUser | Select #{Name = 'Group Name'; Expression={$Group.Name}}, SamAccountName, Name, Enabled
}
}
$results | Export-Csv -Path $file -NoTypeInformation -Delimiter ";"

Powershell Get-ADGroupMember export to CSV -- throwing error "Cannot convert 'System.Object[]'..."

Third day noob with Powershell here.
Problem: We have several AD groups which follow a prefix naming convention. For example, "IT_1", "IT_2", "IT_3" and so on. I am attempting to export a csv with member details from each "IT_" group, along with the name of the group.
The output should have the following columns populated with data. The column GroupName will refer to IT_1, IT_2, i.e the name of the group.
"name","GroupName","distinguishedName","objectClass","objectGUID","SamAccountName","SID"
My code can work for a single group. "IT_1". For example:
$groups = Get-ADGroup -Filter 'Name -like "IT_1"'
Get-ADGroupMember $groups `
| Select-Object name, #{Name='GroupName';Expression={$groups.Name}}, distinguishedName, objectClass, objectGUID, SamAccountName, SID `
| Export-Csv -Path "C:\Users\dude\Desktop\users.csv"
However, when I alter the groups variable with a wildcard "IT_*" as per below:
$groups = Get-ADGroup -Filter 'Name -like "IT_*"'
Get-ADGroupMember $groups `
| Select-Object name, #{Name='GroupName';Expression={$groups.Name}}, distinguishedName, objectClass, objectGUID, SamAccountName, SID `
| Export-Csv -Path "C:\Users\dude\Desktop\users.csv"
The following exception is thrown:
Get-ADGroupMember : Cannot convert 'System.Object[]' to the type 'Microsoft.ActiveDirectory.Management.ADGroup' required
by parameter 'Identity'. Specified method is not supported.
At line:3 char:19
+ Get-ADGroupMember $groups `
+ ~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ADGroupMember], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.ActiveDirectory.Management.Commands.GetADGroupMember
What am I missing here?
I am sure this is a simple fix for an experienced user.
The -Identity parameter of Get-ADGroupMember does not allow an array, so you need to loop over the results from Get-ADGroup
Get-ADGroup -Filter 'Name -like "IT_*"' | ForEach-Object {
$groupName = $_.Name
$_ | Get-ADGroupMember |
Select-Object name, #{Name='GroupName';Expression={$groupName}},
distinguishedName, objectClass, objectGUID, SamAccountName, SID
} | Export-Csv -Path "C:\Users\dude\Desktop\users.csv" -NoTypeInformation
Inside the ForEach-Object loop, the $_ automatic variable represents the ADGroup object for each iteration

Get AD Groups where the Owner is disabled with Powershell

This are the lines where Powershell gets all the groups in AD
Get-ADGroup -Filter * -Properties SamAccountName, managedBy, Name, Description, GroupCategory |
Select-Object SamAccountName, #{Name = 'ManagedBy'; Expression = { (Get-ADUser -Identity $_.managedBy -Properties DisplayName).DisplayName }},Name, Description, GroupCategory
What I'm trying to accomplish is to get only the AD groups where the owner Enabled property is set to disabled, something like the following but I cannot complete the logic
Get-ADGroup -Filter * -Properties SamAccountName, managedBy, Name, Description, GroupCategory |
Where (Get-ADUser -Filter "DisplayName -eq '$($_.DisplayName)'" | Select SamAccountName, Enabled -eq "false") |
Select-Object SamAccountName, #{Name = 'ManagedBy'; Expression = { (Get-ADUser -Identity $_.managedBy -Properties DisplayName).DisplayName }},Name, Description, GroupCategory
EDIT:
Applying jfrmilner's answer I get the following error
Get-ADUser : Cannot find an object with identity: 'CN=example,OU=example,OU=User Archive,DC=example,DC=example' under: 'DC=example,DC=example'.
At line:2 char:18
+ Where-Object { !(Get-ADUser -Identity $_.ManagedBy).Enabled } |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (CN=exampl...,DC=example,DC=nexample:ADUser) [Get-ADUser], ADIdentityNotFoundException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException,Microsoft.ActiveDirectory.Management.Commands.GetADUser
This will return only AD Groups where the ManagedBy User is Disabled:
Get-ADGroup -LDAPFilter "(ManagedBy=*)" -Properties ManagedBy, Description | Where-Object { !(Get-ADUser -Identity $_.ManagedBy).Enabled }

Powershell list group names for each user in array

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
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'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 ";" }
}

Variables in ADUsers2CSV script

My main goal is to export some info about users from Active Directory to CSV file.
But in my AD, there is also bunch of some service accounts that I don't want to export and I want to use only specific OUs.
So I created CSV file with "list" of these OUs and filenames of exported CSV, looks like:
oubase,oucity,filename
OU=_SubCompany1,OU=_City1,filename1.csv
OU=_SubCompany1,OU=_City2,filename2.csv
OU=_SubCompany3,OU=_City1,filename3.csv
And my PS script:
Import-Module ActiveDirectory
$adserver = "ad1.domain.com"
$filter = "'(& (msExchMailboxGuid=*) (!sAMAccountName=*_*))'"
$selection = "personalTitle, msDS-PhoneticFirstName, msDS-PhoneticLastName, msDS-PhoneticDepartment, Title, mobile, telephoneNumber, facsimileTelephoneNumber, SamAccountName"
$targetpath = "C:\Scripts\ADUsers\export\"
$exportfiles = "C:\Scripts\ADUsers\export\export_files.csv"
Import-Csv -Path $exportfiles | ForEach-Object {
$oubase = $_.'oubase'
$oucity = $_.'oucity'
$filename = $_.'filename'
$fullpath = $targetpath + $filename
$fullbase = "'OU=Users," + $oucity + "," + $oubase + ",DC=domain,DC=com'"
#$fullbase = 'OU=Users,OU=_City2,OU=_SubCompany1,DC=domain,DC=com'
Get-ADUser -Server $adserver -LDAPFilter $filter -Properties * -SearchBase $fullbase |
select $selection |
Export-Csv -Encoding Unicode $fullpath
But the script isn't working. There is some problem with variables in the Get-ADUser command.
When I type in directly all the values, everything is working:
Get-ADUser -Server ad1.domain.com -LDAPFilter '(& (msExchMailboxGuid=*) (!sAMAccountName=*_*))' -Properties * -SearchBase 'OU=Users,OU=_City2,OU=_SubCompany1,DC=domain,DC=com' |
select personalTitle, msDS-PhoneticFirstName, msDS-PhoneticLastName, msDS-PhoneticDepartment, Title, mobile, telephoneNumber, facsimileTelephoneNumber, SamAccountName |
Export-Csv -Encoding Unicode C:\Scripts\ADUsers\export\filename2.csv
When I try to display the content of variables, it seems OK, no extra whitespaces or commas etc.
I think variables $filter and $fullbase are problematic.
When I try it like with $filter variable, command won't return any error and it creates empty CSVs:
Get-ADUser -Server $adserver -LDAPFilter $filter -Properties * -SearchBase 'OU=Users,OU=_City2,OU=_SubCompany1,DC=domain,DC=com' |
select personalTitle, msDS-PhoneticFirstName, msDS-PhoneticLastName, msDS-PhoneticDepartment, Title, mobile, telephoneNumber, facsimileTelephoneNumber, SamAccountName |
Export-Csv -Encoding Unicode C:\Scripts\ADUsers\export\filename2.csv
When I try it with $fullbase variable, command returns this error.
Get-ADUser -Server $adserver -LDAPFilter '(& (msExchMailboxGuid=*) (!sAMAccountName=*_*))' -Properties * -SearchBase $fullbase |
select personalTitle, msDS-PhoneticFirstName, msDS-PhoneticLastName, msDS-PhoneticDepartment, Title, mobile, telephoneNumber, facsimileTelephoneNumber, SamAccountName |
Export-Csv -Encoding Unicode C:\Scripts\ADUsers\export\filename2.csv
Get-ADUser : The supplied distinguishedName must belong to one of the following
partition(s): 'DC=domain,DC=com , CN=Configuration,DC=domain,DC=com ,
CN=Schema,CN=Configuration,DC=domain,DC=com , DC=DomainDnsZones,DC=domain,DC=com ,
DC=ForestDnsZones,DC=domain,DC=com'.
At C:\Scripts\ADUsers\export\ad-users_export-csv.ps1:21 char:1
+ Get-ADUser -Server $adserver -LDAPFilter '(& (msExchMailboxGuid=*) (!sAMAccountN ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ADUser], ArgumentException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.ArgumentException,Microsoft.ActiveDirectory.Management.Commands.GetADUser
Do you have any ideas what am I doing wrong?