Hope all is well.
Trying to see if this possible.
Task: I have list of AD group that I need find members of each group. Only get the list active users.
Issue: I wanted to see if I can put the name of the group as Column name and Group Members under each column. Not sure if this possible. So far. I was only able to use Write-Output - Group and add extra line in way to difference each group.
$data = Import-Csv -Path C:\Source\Listofusers.csv
$results = Foreach ($datauser in $data)
{
$getadgroupmember = Get-ADGroupMember -Identity $datauser.ADGroups -Recursive | ? {$_.objectclass -eq "user"}
write-output "`n"
write-output $datauser.ADGroups
write-output "-----------------------------------------------------------------"
foreach ($activeanddisabledusers in $getadgroupmember)
{
Get-ADUser -Identity $activeanddisabledusers -Properties enabled | Where-Object {$_.Enabled -eq 'true'} | Select-Object -ExpandProperty SamAccountName}
}
Related
I'm a beginner in programming in general..
What I'm trying to do is to create a powershell script that will:
Get information on each user on an Active Directory group.
Inside each group there may be another group, so I would want it to get the list of users from each nested group as well.
Only give me the information for each group once.
This is what I have so far:
$list = Get-ADGroupMember Admins
foreach($u in $list) {
Get-ADObject $u
}
foreach ($_ in $u) {
if ($u.ObjectClass -eq 'user') {
Get-ADUser $u -Properties * | select givenname, surname, samaccountname | ft -autosize
} else {
Get-ADGroupMember $u -Recursive | select name, samaccountname | ft -autosize
}
}
So far I'm trying to get it to work with that one group 'Admins' and then if it does I would want to run the code for more groups at the same time.
Any help or guidance would be appreciated.
You seem to want only properties that are returned by default by Get-ADUser aswell as Get-ADGroup, so in both cases, there is no need to specify the -Properties parameter.
Get-ADGroupMember can return user, computer and group objects, so at the moment, your else condition expects groups, where you could end up with a computer object..
In your code, you output to console with ft -autosize both in the if and the else, but it would be simpler to capture both types of resulting objects in a variable at the start of the loop and output it as a whole afterwards:
# you can load a list of group names from a predefined array:
$Groups = 'Admins', 'Users'
# or load from a file, each group name listed on a separate line:
# $Groups = Get-Content -Path 'D:\Test\ADGroups.txt'
# or get all AD groups in the domain:
# $Groups = (Get-ADGroup -Filter *).Name
$result = foreach ($group in $Groups) {
Get-ADGroup -Filter "Name -eq '$group'" | ForEach-Object {
# we could use the $group variable, but this ensures correct casing
$groupName = $_.Name
$members = $_ | Get-ADGroupMember -Recursive
foreach ($member in $members) {
if ($member.objectClass -eq 'user') {
Get-ADUser -Identity $member.DistinguishedName |
Select-Object #{Name="GroupName"; Expression={$groupName}},
#{Name="MemberType";Expression={'User'}},
Name,
GivenName,
Surname,
SamAccountName
}
elseif ($member.objectClass -eq 'group') {
Get-ADGroup -Identity $member.DistinguishedName |
Select-Object #{Name="GroupName";Expression={$groupName}},
#{Name="MemberType";Expression={'Group'}},
Name,
#{Name="GivenName";Expression={''}}, # groups don't have this property
#{Name="Surname";Expression={''}}, # groups don't have this property
SamAccountName
}
}
}
}
# output is console
$result | Format-Table -AutoSize
# write to CSV file
$result | Export-Csv -Path 'D:\Test\GroupsInfo.csv' -NoTypeInformation
The trick is here to output objects with equal properties for both a user and a group object
How could I get a List of Members on multible AD Groups with more than 5000 Users
Example:
Group1 = includes 6000 Members and Group2
Group2 = includes 7000 Members
the result of the get-adgroupmember of Group1 should 13000
how can I do that? Here I have the Problem, that it will not look in sub groups recursive will not work with get-adgroup
$group = "group1"
$ADInfo = Get-ADGroup -Identity $Group -Properties Members
$outputfile = $group
$ADInfo.Members | get-aduser | Select name, enabled, UserPrincipalName, SamAccountName
#$ADInfo.Members | get-aduser | Select name, enabled, UserPrincipalName, SamAccountName | Export-Csv c:\temp\$outputfile-member.csv -Delimiter "," -NoTypeInformation
# to show output
$members = #()
$members = $ADInfo.members
$members.count
With groups that large, it will be slow, but this should do what you want:
$groups = 'group1', 'group2' # array of group names
foreach ($group in $groups) {
Write-Host "Working on group '$group'"
$result = Get-ADGroupMember -Identity $group -Recursive | Where-Object { $_.objectClass -eq 'user' } | ForEach-Object {
Get-ADUser -Identity $_.distinguishedName | Select-Object Name, Enabled, UserPrincipalName, SamAccountName
}
# show result on screen
$result | Format-Table -AutoSize
# write to export file
$result | Export-Csv -Path "c:\temp\$group-members.csv" -NoTypeInformation
}
Hope that helps
The easiest solution would be to adjust the MaxGroupOrMemberEntries parameter in ADWS on the DC you are targeting. You can see information on ADWS defaults here.
You could do something like the following, which is potentially convoluted:
function Get-ADGroupMembers
{
param ($groupname)
Get-ADGroupMember $groupname | where ObjectClass -eq 'Group' | ForEach-Object {
$_.Name
Get-ADGroupMembers $_.Name
}
}
$maingroup = 'group1'
$subgroups = Get-ADGroupMembers $maingroup
$allGroups = #($maingroup)+#($subgroups)
$regexEscapes = $allGroups |% { [regex]::Escape($_) }
$filter = "CN=({0})" -f ($regexEscapes -join "|")
$output = foreach ($group in $allGroups) {
Get-AdGroup $group -Properties Members | Select #{n='Members';e={$_.Members -notmatch $filter}}
}
$output.Members
Explanation:
The function will list the Name property value for each recursively discovered member group.
Since the -notmatch regex operator is used in filtering, a regex match string needs to be constructed. There could be multiple groups so the | (regex OR) character needs to be used.
The [regex]::Escape method escapes all backslashes and other special regex characters that may appear in the name strings.
$output is an array of PSCustomObjects that contain the Members property. The Members property contains the DN of all members that are users.
Non-PowerShell commands may be better suited for this particular case if the ADWS default limits are not modified.
I was wondering if this script could be changed into one for only active users?
import-module ActiveDirectory
Start-Transcript -Path "C:\test\teetest.txt"
$groups = Get-ADGroup -filter {(name -like "runners*") -or (name -like "helpers*")
foreach($group in $groups)
{
$countUser = (Get-ADGroupMember $group.DistinguishedName).count
Write-Host "The group $($group.Name) has $countUser user(s)."
}
Stop-Transcript
Any help would be appreciated.
If I understand your question correctly and by active users you mean groups with at least 1 member(i.e. greater than 0). You could just filter out results using Where-Object cmdlet. Like so:
$groups = Get-ADGroup -filter {(name -like "runners*") -or (name -like "helpers*") -Properties Members | Where-Object { $_.Members.Count –gt 0 }
Yes, you can add a filter to only get the number of active Members in the Group.
Since Get-ADGroupMember doesn't supply all properties for the Users you have to do another lookup for each of them:
$countUser = (Get-ADGroupMember $group.DistinguishedName | % { Get-ADuser -Identity $_ -Property Enabled | Where-Object {$_.Enabled -eq $true}}).count
Explanation:
% { Get-ADuser -Identity $_ -Property Enabled - Get the Informations for each User found in the Group with the Enabled Property added to it
Where-Object {$_.Enabled -eq $true} - Filters the users that are enabled
I think this may be because the Get-ADGroupMember not just returns user objects with a limited set of properties, but can also return groups and computers.
Since you are only looking for users that are direct descendents of the groups 'runners*' or 'helpers*', it is better to limit the objects returned by the Get-ADGroupMember cmdlet to be users only.
Below I do this by adding Where-Object { $_.objectClass -eq "user" }.
Next, to ensure the .Count property can be used I would suggest to enclose the thing in a #() so the returned value actually is an array and therefore has the Count property.
For a script like this, I also suggest NOT to try and put it all in one single line, because that makes spotting mistakes (like forgetting a closing bracket) more difficult.
Try this:
Start-Transcript -Path "C:\test\teetest.txt"
$groups = Get-ADGroup -Filter {(name -like "runners*") -or (name -like "helpers*")}
foreach($group in $groups) {
$countUser = 0
Get-ADGroupMember $group.DistinguishedName | Where-Object { $_.objectClass -eq "user" } |
ForEach-Object {
if ((Get-ADuser -Identity $_.DistinguishedName).Enabled) { $countUser++ }
}
Write-Host "The group $($group.Name) has $countUser user(s)."
}
Stop-Transcript
Replace the $countUser statement alone with below example.
For only Enabled User Accounts
$countUserEnabled = (get-aduser -filter *|where {$_.enabled -eq "True"}).count
For only Disabled User Accounts
$countUserDisabled = (get-aduser -filter *|where {$_.enabled -ne "False"}).count
I am trying to copy from one ad group to another. However I am having trouble with piping the data and feeding the add-group command with array items please help
Write-Host "You have selected the following group: $SourceGroup"
$SourceGroup = Read-Host
Write-Host "Enter the name of the new group you want the membership of $SourceGroup copied to"
$DestinationGroup = Read-Host
$P1 = Get-ADGroup $SourceGroup -Property member | Select member | Format-Table -HideTableHeaders
$P2 = Foreach ($Member in $P1) { Get-ADUser $Member -Property SamAccountName | Select SamAccountName }
Foreach ($Member in $P1) { Add-ADGroupMember -Identity $DestinationGroup -Member $Member }
You break it by using Format-Table. Formatting is for display, you should not format anything you expect to work with in the shell. By all means format it at the end once you're done.
Anyway, you should be able to simplify it.
Get-ADGroup $SourceGroup | Get-ADGroupMember | ForEach-Object {
Add-ADGroupMember $DestinationGroup -Member $_.DistinguishedName
}
Chris
As a beginner I am having trouble with a rather straightforward task. I need to write a ps script that will copy files to users in different groups - each group gets different files. All files are on a network location, so I don't need to do anything on their computers.
First idea is to get a variable with all active users and then check to which groups they belong. If they belong to one of the three groups the script will copy the necessary files to their network location. There is a problem with one group for managers, as they belong to two groups that I am interested in, but I can probably fix that with conditions.
Most of the code I written for this are just snipets as the one below, trying to test PS out:
$Source = Get-ADUser -LDAPFilter "(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2))" #Import active users as a source variable
foreach ($user in $Source) #for every user in source get his groups
{
$UserGroups = get-aduser $user -Properties memberof | select -expand memberof
If ($user.IsMember("LDAP://" + ) -eq $False)
{
Write-Host "He is a member!"
}
I know it is not much, I have been searching the net for a suitable examples for over a week now with no luck.
Here is an example of how to test membership for a group:
$targetGroup1 = "Administrators"
$targetGroup2 = "Domain Users"
Get-ADUser -Filter * -Properties MemberOf | ForEach-Object {
if(($_.MemberOf -match "CN=$targetGroup1") -and ($_.MemberOf -match "CN=$targetGroup2")) {
"$($_.Name) is a member both groups"
"copying files from a special location"
} elseif($_.MemberOf -match "CN=$targetGroup1") {
"$($_.Name) is a member of $targetGroup1"
"copying files from source1"
} elseif($_.MemberOf -match "CN=$targetGroup2") {
"$($_.Name) is a member of $targetGroup2"
"copying files from source2"
}
}
Something like this maybe (code is untested):
Import-Module ActiveDirectory
$groupOneMembers = Get-AdGroupMember Group1 | Select-Object -ExpandProperty SamAccountName
$groupTwoMembers = Get-AdGroupMember Group2 | Select-Object -ExpandProperty SamAccountName
$groupThreeMembers = Get-AdGroupMember Group3 | Select-Object -ExpandProperty SamAccountName
foreach($member in $groupOneMembers) {
Copy-Item -Recurse \\server\GroupOneFiles \\server\Users\$member
}
foreach($member in $groupTwoMembers) {
Copy-Item -Recurse \\server\GroupOneFiles \\server\Users\$member
}
foreach($member in $groupThreeMembers) {
Copy-Item -Recurse \\server\GroupOneFiles \\server\Users\$member
}