I have a requirement to generate a CSV report to get group members. However, I there are many child domains which contains groups starting with ADM.
I need report in the following format:
GroupName User Company LasLogon CN
ADM_AM UserOne CP1
I've found one script on internet:
Get-ADGroup -Server dc1.chd1.pd.local -Filter 'Name -like "ADM*"' |
ForEach-Object{
$hash=#{GroupName=$_.Name;Member=''}
$_ | Get-ADGroupMember -ea 0 -recurs |
ForEach-Object{
$hash.Member=$_.Name
New-Object psObject -Property $hash
}
} |
sort groupname,member
This script only gives me GroupName and UserName but not other information.
How can I generate this report?
I'm not sure what "ADM_AM, UserOne, CP1" is, but i got this much for you. I'm still new to powershell so forgive me if this is a lot of code =)
$array = #()
Foreach ($group in (Get-ADGroup -Server dc1.chd1.pd.local -Filter 'Name -like "ADM*"'))
{
$hash=#{Username ='';GroupName=$group.Name;Company='';LastLogon='';CN=''}
$members = $hash.GroupName | Get-ADGroupMember -Recursive -ErrorAction SilentlyContinue
Foreach($member in $members)
{
$properties = $member.SamAccountName | Get-ADUser -Properties SamAccountName, Company, lastLogon, CN
$hash.Username = $properties.SamAccountName
$hash.Company = $properties.Company
$hash.LastLogon = $properties.lastLogon
$hash.CN = $properties.CN
$obj = New-Object psObject -Property $hash
$array += $obj
}
}
$array | Export-Csv C:\ -NoTypeInformation
Here is what I would do, Im sure you can shorten it. You shoud specify a searchbase. Once you have the members samaccountname, you can use Get-ADUser to get whatever fields you want.
$GrpArr = #()
$Groups = get-adgroup -filter {name -like "adm*"} -searchbase "ou=Groups,dc=all,dc=ca" | select samaccountname
foreach ($group in $groups)
{
$GrpArr += $group
$members = get-adgroupmember $group | select samaccountName
foreach ($member in $members)
{
$memprops = get-aduser $member -properties company
$comp = $memprops.company
$grpArr += "$member,$comp"
}
}
$grpArr | export-csv c:\temp\Groups.csv -NoTypeInformation
Related
I have this script that extracts the users that belong to the groups I need.
$GroupList = Get-Content C:\Scripts\grouplist.txt
$Results = foreach ($Group in $GroupList) {
$Description = Get-ADGroup -Identity $Group -Properties Description | Select-Object -ExpandProperty Description
Get-ADGroupMember -Identity $Group |
Select-Object -Property SamAccountName, Name, #{Name='GroupName';Expression={$Group}}, #{Name='Description';Expression={$Description}}
}
$Results
$Results | Export-csv -Path C:\Scripts\SecurityGroups.csv -NoTypeInformation
The problem is that I only need users in the enabled state.
And I can't. Could you help me please?
Thanks.
As mentioned per the comments you can use the Get-Aduser cmdlet after you populated your results. Here you have to filter out groups, otherwise the cmdlet will throw exceptions for every group.
$results = #()
foreach ($group in $grouplist) {
$description = (Get-ADGroup $group -Properties description).description
$members = Get-ADGroupMember $group | ?{$_.objectClass -eq "user"} | % {Get-ADUser $_ -Properties enabled}
$results += $members | ? {$_.Enabled -eq $true } | select samaccountname, name, #{name='groupname';expression={$group}}, #{name='description';expression={$description}}
}
Alternatively, you can use LDAP-filters. This option is noticeably faster since you only make one request per group, not one per user.
$results = #()
foreach ($group in $grouplist) {
$group = Get-ADGroup $group -Properties description
$members = Get-ADUser -LDAPFilter "(&(memberof=$($group.DistinguishedName))(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))"
$results += $members | select samaccountname, name, #{name='groupname';expression={$group}}, #{name='description';expression={$group.description}}
}
With LDAP-filters you could also request members of multiple groups at once, but since you want the context in which group a user was found this is not an option here..
I put together the below, which does the job. However, the output isn't very workable. So I wanted to output this all to a CSV using Export-Csv. Im aware I can do this by moving to a ForEach-Object query, but im not entirely sure how to achieve that.
I have added an attempt to convert it in hopes of a little help. I'm not sure how to specify the variable for each object. For example the first section calls all domains in the forest. How do i use each response in the next piped query? and so on.
$domains = (Get-ADForest).Domains
$controllers = #()
$worked = $false
foreach ($domain in $domains) {
$controller = Get-ADDomainController -Discover -ForceDiscover -DomainName $domain |
Select-Object HostName
$controllers += $controller
}
while (-not $worked) {
try {
foreach ($item in $controllers) {
$value = $item.HostName.Value
Write-Host $value
Write-Host 'Domain Admins'
Get-ADGroupMember -Identity 'Domain Admins' -Server $value |
Get-ADUser -Properties name, samaccountname, Description, EmailAddress |
Where {$_.Enabled -eq $true} |
Format-Table Name, SamAccountName, Description, EmailAddress -AutoSize
}
$worked = $true
} catch {}
}
Conversion Attempt
ForEach-Object{
(Get-ADForest).domains | Get-ADDomainController -Discover -ForceDiscover -DomainName $domain |Select-Object HostName | Get-ADGroupMember -identity 'Domain Admins' -Server $value | Get-ADUser -Properties samaccountname, Description, EmailAddress | Where {$_.Enabled -eq $true}
}| Export-Csv -Path "$HOME/Desktop/DomainAdmins.csv" samaccountname, Description, EmailAddress -AutoSize
If you can get the values from your Get-ADUser call and put them in an object, you can then pipe to convertto-csv.
Here's an example:
$arr = #([pscustomobject]#{name="name"; sam="samaccountname"}, [pscustomobject]#{name="name2"; sam="samaccountname2"});
$arr | ConvertTo-Csv -NoTypeInformation
"name","sam"
"name","samaccountname"
"name2","samaccountname2"
You could get rid of the Format-Table call. The code I've shown in the example pipes and array of objects into the convertto-csv cmdlet. So if Get-ADUser returns objects, you should be able to pipe right into ConvertTo-CSV or Export-Csv -append
The objects are hashtables that are cast to pscustomobjects, it's a nice quick way to illustrate the technique.
The result, as shown, will be csv headers that match your hashtable keys, and the hastable values will be the CSV values.
This is working fine in my local environment and storing the result in D:\Test_File.csv
$domains = (Get-ADForest).Domains
$controllers = #()
$worked = $false
foreach ($domain in $domains) {
$controller = Get-ADDomainController -Discover -ForceDiscover -DomainName $domain | Select-Object HostName
$controllers += $controller
}
while (-not $worked) {
try
{
foreach ($item in $controllers)
{
$value = $item.HostName.Value
Write-Host $value
Write-Host 'Domain Admins'
Get-ADGroupMember -Identity 'Domain Admins' -Server $value |
Get-ADUser -Properties name, samaccountname, Description, EmailAddress |?{$_.Enabled -eq $true}|Export-Csv -Append "D:\Test_File.csv"
}
#$worked = $true
}
catch
{
$Error_Message=$_.Exception.Message
}
}
Looking to write a powershell script that will pull ALL AD users, their group memberships and the groups Description Field.
I have been using two scripts to accomplish this, and just manually manipulating them in excel. Any attempt to combine them has been met with error.
Import-module activedirectory
$ou ="DC=blah,DC=blah"
Get-ADGroup -Filter * -SearchBase $OU | select -expandproperty name | % {
$group= "$_"
$result += Get-ADGroupMember -identity "$_" | select #{n="Group";e={$group}},name
}
$result | export-csv 'c:\users\membership.csv' -notypeinformation
And:
Import-Module ActiveDirectory
$Groups = ForEach ($G in (Get-ADGroup -Filter * ))
{
$UN = Get-ADGroup $G -Properties Description | select name, description
New-Object PSObject -Property #{
Desc=$UN.description
Name=$UN.name
}
}
$Groups | Export-CSV C:\users\GroupDesc.csv -notypeinformation
I hope i've got this right, this will pull all users from AD and get the groups each one is a member of (including the groups description). After everything is done it puts the info into a csv.
Import-Module ActiveDirectory
$OU = "DC=blah,DC=blah"
#$allUsers = Get-ADUser -LDAPFilter "(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2))" # all users that are enabled
#$allUsers = Get-ADUser -Filter * # all users
$allUsers = Get-ADUser -Filter * -SearchBase $OU
$results = #()
foreach($user in $allUsers)
{
$userGroups = Get-ADPrincipalGroupMembership -Identity $user
foreach($group in $userGroups)
{
$adGroup = Get-ADGroup -Identity $group -Properties Description
$results += $adGroup | Select-Object -Property #{name='User';expression={$user.sAMAccountName}},Name,Description
}
}
$results | Export-Csv -Path 'C:\Membership.csv' -NoTypeInformation -Encoding Unicode
I'm trying to make a PS script which would list all Active Directory user group membership (recursive).
I already have working script:
import-module activedirectory
$users = get-aduser -Filter {Name -Like "*"} -Searchbase "ou=Users, dc=Domain" | Where-Object { $_.Enabled -eq 'True' }
$targetFile = "D:\users.csv"
rm $targetFile
Add-Content $targetFile "User;Group"
foreach ($user in $users)
{
$groups = Get-ADPrincipalGroupMembership $user
foreach ($group in $groups)
{
$username = $user.samaccountname
$groupname = $group.name
$line = "$username;$groupname"
Add-Content $targetFile $line
}
}
But script doesn't list groups recursively, i.e., if group listed in the output file is part of another group.
Example:
Group1: User
Group2: Group3: User
Script shows only Group1 and 3 but not 2.
What should I add to the first script that it writes group membership recursively?
Sorry I am publishing an answer for a question from 3 years ago but if someone will see it, it can help.
Credit to:
How to get ALL AD user groups (recursively) with Powershell or other tools?
You can use the LDAP_MATCHING_RULE_IN_CHAIN:
Get-ADGroup -LDAPFilter "(member:1.2.840.113556.1.4.1941:=CN=User,CN=USers,DC=x)"
You can use it anywahere that you can use an LDAP filter.
Example:
$username = 'myUsername'
$dn = (Get-ADUser $username).DistinguishedName
Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $dn) | select -expand Name | sort Name
Fix in your script:
import-module activedirectory
$users = get-aduser -Filter {Name -Like "*"} -Searchbase "ou=Users, dc=Domain" | Where-Object { $_.Enabled -eq 'True' }
$targetFile = "D:\users.csv"
rm $targetFile
Add-Content $targetFile "User;Group"
foreach ($user in $users)
{
$dn = $user.DistinguishedName
$groups = Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $dn) | select -expand Name | sort Name
foreach ($group in $groups)
{
$username = $user.samaccountname
$groupname = $group.name
$line = "$username;$groupname"
Add-Content $targetFile $line
}
}
If you make it a function you can call it recursively. Check this out, I think you'll be pleased with the results:
Function Get-ADGroupsRecursive{
Param([String[]]$Groups)
Begin{
$Results = #()
}
Process{
ForEach($Group in $Groups){
$Results+=$Group
ForEach($Object in (Get-ADGroupMember $Group|?{$_.objectClass -eq "Group"})){
$Results += Get-ADGroupsRecursive $Object
}
}
}
End{
$Results | Select -Unique
}
}
Toss that at the top of your script, and then call it for each user. Something like:
import-module activedirectory
$users = get-aduser -Filter {Name -Like "*"} -Searchbase "ou=Users, dc=Domain" -Properties MemberOf | Where-Object { $_.Enabled -eq 'True' }
$targetFile = "D:\users.csv"
rm $targetFile
Add-Content $targetFile "User;Group"
foreach ($user in $users)
{
$Groups = $User.MemberOf
$Groups += $Groups | %{Get-ADGroupsRecursive $_}
$Groups | %{New-Object PSObject -Property #{User=$User;Group=$_}}|Export-CSV $targetfile -notype -append
}
Now, depending on the size of your AD structure that may take quite a while, but it will get you what you were looking for.
It is very easy. Just use ActiveRoles Management Shell for Active Directory. Cmdlet Get-QADMemberOf with parameter Indirect is the one you are looking for. Example:
Get-QADMemberOf john.smith -Indirect
The Quest object returned already include All Recursive groupes (and first level users) in properties $_.AllMembers
Add-PSSnapin Quest.ActiveRoles.ADManagement
$UsersFirstLevel = ($Members | Get-QADObject -Type Group -DontUseDefaultIncludedProperties | Get-QADGroupMember -DontUseDefaultIncludedProperties | ?{$_.type -eq 'user'})
$UsersSubGroup = ($Members | Get-QADObject -Type Group -DontUseDefaultIncludedProperties | Get-QADGroupMember -DontUseDefaultIncludedProperties | ?{$_.type -eq 'group'}).Allmembers | Get-QADObject -DontUseDefaultIncludedProperties | ?{$_.type -eq 'user'}
$RecursiveUsers = $UsersFirstLevel
$RecursiveUsers += $UsersSubGroup
$RecursiveUsers = $RecursiveUsers | Sort-Object -Unique
Newer versions of PowerShell (AD Module) do have -Recursive switch. So you can easily use Get-ADGroupMember.
Example: Get-ADGroupMember -Identity My_Group -Recursive
I need to return all members of multiple security groups using PowerShell. Handily, all of the groups start with the same letters.
I can return a list of all the relevant security groups using the following code:
Get-ADGroup -filter 'Name -like"ABC*"' | Select-Object Name
And I know I can return the membership list of a specific security group using the following code:
Get-ADGroupMember "Security Group Name" -recursive | Select-Object Name
However, I can't seem to put them together, although I think what I'm after should look something like this (please feel free to correct me, that's why I'm here!):
$Groups = Get-ADGroup -filter 'Name -like"ABC*"' | Select-Object Name
ForEach ($Group in $Groups) {Get-ADGroupMember -$Group -recursive | Select-Object Name
Any ideas on how to properly structure that would be appreciated!
Thanks,
Chris
This is cleaner and will put in a csv.
Import-Module ActiveDirectory
$Groups = (Get-AdGroup -filter * | Where {$_.name -like "**"} | select name -expandproperty name)
$Table = #()
$Record = [ordered]#{
"Group Name" = ""
"Name" = ""
"Username" = ""
}
Foreach ($Group in $Groups)
{
$Arrayofmembers = Get-ADGroupMember -identity $Group | select name,samaccountname
foreach ($Member in $Arrayofmembers)
{
$Record."Group Name" = $Group
$Record."Name" = $Member.name
$Record."UserName" = $Member.samaccountname
$objRecord = New-Object PSObject -property $Record
$Table += $objrecord
}
}
$Table | export-csv "C:\temp\SecurityGroups.csv" -NoTypeInformation
If you don't care what groups the users were in, and just want a big ol' list of users - this does the job:
$Groups = Get-ADGroup -Filter {Name -like "AB*"}
$rtn = #(); ForEach ($Group in $Groups) {
$rtn += (Get-ADGroupMember -Identity "$($Group.Name)" -Recursive)
}
Then the results:
$rtn | ft -autosize
Get-ADGroupMember "Group1" -recursive | Select-Object Name | Export-Csv c:\path\Groups.csv
I got this to work for me... I would assume that you could put "Group1, Group2, etc." or try a wildcard.
I did pre-load AD into PowerShell before hand:
Get-Module -ListAvailable | Import-Module
This will give you a list of a single group, and the members of each group.
param
(
[Parameter(Mandatory=$true,position=0)]
[String]$GroupName
)
import-module activedirectory
# optional, add a wild card..
# $groups = $groups + "*"
$Groups = Get-ADGroup -filter {Name -like $GroupName} | Select-Object Name
ForEach ($Group in $Groups)
{write-host " "
write-host "$($group.name)"
write-host "----------------------------"
Get-ADGroupMember -identity $($groupname) -recursive | Select-Object samaccountname
}
write-host "Export Complete"
If you want the friendly name, or other details, add them to the end of the select-object query.