I have a script used to manage group memberships, but am running into a challenge when it comes to searching multiple OU's.
Currently, within the script, I have the following code used to query AD:
$Users = Get-ADUser -LDAPFilter $LDAPString -SearchBase $SearchOU
(...)
Foreach ($User in $Users)
{
If ($User.distinguishedName -notin $Members.distinguishedName)
{
Add-ADGroupMember -Identity $GroupDN -Members $User.distinguishedName -Server $DomainController
}
}
So far, I have tried the following, where $OU is an array of OU's, but I end up with just the first result.
Foreach ($OU in $SearchOUs)
{
$Users += Get-ADUser -LDAPFilter $LDAPString -SearchBase $OU
}
Is there an easy way to combine the resulting hash tables or is it best to simply create a new hash table and add results to that?
Your second attempt is close. Try adding $Users = #() before the Foreach. The += operator is overloaded, so it can pick the wrong operation. Initializing the variable to an empty array makes it clear what you want:
$Users = #()
Foreach ($OU in $SearchOUs)
{
$Users += Get-ADUser -LDAPFilter $LDAPString -SearchBase $OU
}
Also, it's an array, not a hashtable. Those are distinct.
Related
When somebody leaves my organization, we remove all AD group memberships apart from the PrimaryGroup which is Domain Users. We often process these in batches, so pull the affected usernames from a CSV file.
I have the following code, and while it does the job of deleting all group memberships, I get an error for each user:
The user cannot be removed from a group because the group is currently the user's primary group
Whilst it does the job, how can I "clean up" the process to avoid this message each time? Is there a way to exclude Domain Users from the groups it removes the user from, or should I do this another way?
$users = Import-Csv "c:\temp\leavers.csv"
foreach ($user in $users) {
Get-ADPrincipalGroupMembership -identity $user.username | foreach {Remove-ADGroupMember $_ -Members $user.username -Confirm:$false}
}
You can use Where-Object for filtering those groups that are not in an array of groups to exclude. In case you only want to filter for 1 specific group, you would use -NE instead of -NotIn in below example.
$groupToExclude = 'Domain Users', 'someOtherGroup'
$users = Import-Csv "c:\temp\leavers.csv"
foreach ($user in $users) {
try {
Get-ADPrincipalGroupMembership -Identity $user.username |
Where-Object Name -NotIn $groupToExclude |
Remove-ADGroupMember -Members $user.username -Confirm:$false
}
catch {
Write-Warning $_.Exception.Message
}
}
If you get the ADUser object before the ADGroup memberships, you can get the PrimaryGroup of the user and ensure that the list of groups to remove from are not its PrimaryGroup:
$users = Import-Csv "c:\temp\leavers.csv"
foreach ($user in $users) {
$primaryGroup = ( Get-ADUser $user.UserName -Properties PrimaryGroup ).PrimaryGroup
Get-ADPrincipalGroupMembership -Identity $user.UserName | Where-Object {
$_ -ne $primaryGroup
} | ForEach-Object {
Remove-ADGroupMember $_ -Members $user.username -Confirm:$False -WhatIf
}
}
Since this has the potential to be a very destructive command, I have included a safeguard in the example above. Remove the -WhatIf parameter from Remove-ADGroupMember to actually perform the removal.
I'd propose a slightly different approach - just drop Get-ADPrincipalGroupMembership altogether. For example:
$users = Import-Csv -Path c:\temp\leavers.csv
foreach ($user in $users) {
# Assuming DN is not in the csv...
$distinguishedName = (Get-ADUser -Identity $user.UserName).DistinguishedName
Get-ADGroup -LdapFilter "(member=$distinguishedName)"
# Alternatively, just pipe memberOf property to Get-ADGroup...
(Get-ADUser -Identity $user.UserName -Property MemberOf).MemberOf |
Get-ADGroup
}
That way you don't have to filter out something you insisted on getting (by using above mentioned cmdlet).
I have an existing script which will search data from different domain separately.Please help me to search data from different domain in one shot.
script im using :
Get-ADUser -Server "domainA" -Filter {samaccountname -like "xyaxsdf"} -Properties
samaccountname,EmailAddress
You can use something as simple as this.
Just set your domains in $Domains then a Foreach loop will do the query for each domain. Result as you can see is stored in the $Output variable, which will contains the results of all your queries
$Domains = #('DomainA', 'DomainB')
$Output = Foreach ($Dom in $Domains) {
Get-ADUser -Server $Dom -Filter { samaccountname -like "xyaxsdf" } -Properties samaccountname, EmailAddress
}
I'm trying to create a simple script that will automate membership to a security group for my org.
I think my variables are coming back empty and are likely either defined wrong or I messed up the syntax somehow. Hoping someone here can help me see the error in my ways!
I am going to edit the code below to better explain my issue. The attribute I am calling can either have a value of M or it is null.
If I run the following command, I get back a list of users who have extensionattribute6 = M
get-aduser -filter {extensionattribute6 -like 'M*'}
If I attempt to add in the section that specifies OU, the results become null.
I guess all I'm asking is if there is a syntax mistake with the OUs or, if not, if anyone could hazard a guess as to what I am doing wrong. :)
$OU = "ou=ou1,ou=ou2,ou=ou3,dc=dc1,dc=dc2"
get-aduser -filter {extensionattribute6 -like 'M*'} -searchbase $OU
When you use the filter and like operator, you have to use the * on the right side of the statement.
$managers = Get-ADUser -SearchBase $OU -Filter "extensionattribute6 -like 'M*'"
This will add a list of AD Users that have a value that Starts with M in extensionattribute6. If you dont add the * to the right side, 'M', then it will look for all users with an extensionAttribute6 value that equals M.
If you are comparing them to be equal, then you can use -eq for equality (without stars * inside quote)
$managers = Get-ADUser -SearchBase $OU -Filter "extensionattribute6 -eq 'M'"
If you have multiple specific OUs you want to go over, might i suggest using a list of these OUs and iterating over them.
$OUs = #()
$OUs += "OU=OU1,DC=domain,dc=com"
$OUs += "OU=OU2,OU=someParent,dc=domain,dc=com"
...
$managers = #()
foreach($OU in $OUs) {
$managers += Get-ADUser -SearchBase $OU -Filter "extensionattribute6 -eq 'M'"
}
I arrived at a solution to this. I needed to call a new variable, borrowing heavily from what Jawad suggested.
The code I settled on is as follows.
$Managers = #()
$Managers += get-aduser -filter * -searchbase "ou=ou1,ou=ou2,ou=ou3,dc=dc1,dc=dc2" -properties extensionattribute6 | where-object{$_.extensionattribute6 -like 'M*'}
foreach ($Manager in $Managers) {add-adgroupmember -identity <groupname> -members $Manager}
I have written a script That is designed to search an OU for all the users contained whiten. it then gets all groups that that user it finds are members of, and if the DistinguishedName of a group is found to match a string it will remove thate user from that group specifically.
However it is incredibly slow taking anywhere from 5-45 seconds an entry. is this normal or is there any way for me to expedite it?
$OUs = "OU=Terminated,OU=####,OU=####,DC=####,DC=####"
foreach ($ou in $OUs)
{
$users = Get-ADUser -SearchBase $ou -Filter *
foreach ($user in $users)
{
$groups = Get-ADPrincipalGroupMembership -Identity $User | ? {$_.distinguishedName -like "*Groups_I_Want_Removed*" }
foreach($group in $groups)
{
Remove-ADPrincipalGroupMembership -Identity $user -MemberOf $group -whatif
}
}
}
$results = foreach ($OU in $OUs)
{
get-aduser -SearchBase $OU -filter * -Properties MemberOf | ? MemberOf -like "*Distribution Lists*"
}
$results | Export-Csv .\Output_of_users_remaining.csv -NoTypeInformation
My concern is that this script is going through thousands of users and the last time I ran it it was unable to finish within 3 hours and I stopped it at the end of the day. in that time it said it had corrected about 5000~ish users.
Hello I simply don't understand how the like works in powershell.
This line gives 1 record:
Get-ADGroup -Filter {DistinguishedName -eq "CN=Development,CN=Users,DC=mycompany,DC=it"}
but this one:
Get-ADGroup -Filter {DistinguishedName -like "*Development*"}
doesn't return anything. What's wrong with it?
Distinguished Names cannot be wild-card matched with LDAP, which is what the -Filter will get translated to internally.
That's why you don't see any results
You could retrieve all OU's that contain "Development" in the name and search through them all:
$ADGroups = #()
$DevOUs = Get-ADOrganizationalUnit -Filter {name -like "*ex*"}| Select-Object DistinguishedName
foreach($ou in $DevOUs)
{
$DN = $ou.DistinguishedName
foreach($Group in (Get-ADGroup -SearchBase $DN))
{
# Prevent duplicates
if($ADGroups -notcontains $Group)
{ $ADGroups += $Group }
}
}