Cannot search by Division attribute - powershell

I am wanting to create security group for filtering purposes, they do not exist yet and I am wanting to create them.
I would like to get all my AD user and select the value of the Division field.
With that field I'd like to add them to a group in an OU called "SafetyNet"
If the group that matches the name of their division exist - they would be added to that group. If not, the group would be created and then they would be added.
I imagine it would look something like this:
$users = get-aduser -filter "enabled -eq '$true' -and division -like '*'" -properties division
foreach ($user in $users) {
$group = get-adgroup $user.division
if ($group) {
$groupname = get-adgroup -Filter "name -like '$($user.division)'"
Add-ADGroupMember -Identity $groupname -members $user
}
else {
new-adgroup -name $user.division -SamAccountName $user.division -GroupCategory Security -GroupScope global -path "OU=TinyPulse, DC=smh, DC=org"
start-sleep -Seconds 5
Add-ADGroupMember -Identity $user.division -Members $user
}
}
It doesn't seem like division is a searchable attribute which make this difficult.

Related

PowerShell - add an exclusion into Remove-ADGroupMember command?

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).

Remove all groups withen a specific OU

I'm attempting to make an AD cleanup script that will go through a terminated OU and verify all users are removed from specific OU's. currently if I run it it will remove all users in the terminated OU from all OU's. I might just be blind but is there an easy way to have it only remove groups from selected OU's?
$OUs = "OU=Terminated,OU=####,OU=####,DC=####,DC=####"
$results = foreach ($OU in $OUs) {
get-aduser -SearchBase $OU -filter * -properties MemberOf | foreach-object {
? $_.MemberOf -like "*OU I want removed*" | Remove-ADGroupMember -Members $_.DistinguishedName -Confirm:$false -whatif
}
}
$results | Export-Csv '.\Users groups have been remoed from.csv' -NoTypeInformation
I thought it would work, however all it gives me is:
Where-Object : A positional parameter cannot be found that accepts argument 'Microsoft.ActiveDirectory.Management.ADPropertyValueCollection'.
At C:\###\###\###\accounts script.ps1:8 char:13
+ ? $_.MemberOf -like "*Distrobution Lists*" | <#%{$keep -n ...
Given that you have a separate OU for groups, you can iterate over the groups that a terminated user has and see if any of the groups belong to that specific OU. If thats the case, then remove all those groups.
$results = ""
foreach ($ou in $OUs)
{
$users = Get-ADUser -SearchBase $ou -Filter *
foreach ($user in $users)
{
$groups = Get-ADPrincipalGroupMembership -Identity $User | ? {$_.distinguishedName -like "*OU I WANT TO REMOVE FROM*" }
foreach($group in $groups)
{
Remove-ADPrincipalGroupMembership -Identity $user -MemberOf $group -whatif
results += "$user removed from its Groups: $($groups | % { $_.name })\r\n"
}
}
}
results | Out-File -Append C:\temp\new.txt
$groups will have members in this format. You can use distinguishedName as a filter type and use something like "OU=Groups,DC=this,DC=com" instead of "OU=Groups" that might be considered broad.
distinguishedName : CN=GroupName,OU=****,DC=****,DC=****
GroupCategory : Security
GroupScope : Global
name : <Name Of The Group>
objectClass : group
objectGUID : <Object Guid>
SamAccountName : <Name Of The Group>
SID : <SID>
I like to keep the variables so i can use them to log what changes are being performed.
NOTE: I used -whatif to make sure it doesnt do what you intend to for testing reasons. Remove-ADPrincipalGroupMembership also updates user with one group.
Another Way to go about it
foreach ($ou in $OUs)
{
$users = Get-ADUser -SearchBase $ou -Filter *
$groups = Get-ADGroup -Filter * -SearchBase $DecomOUGROUP
foreach($group in $groups) {
Remove-ADGroupMember -Identity $group -Members $users -ErrorAction SilentlyContinue
}
}

Renaming AD user object name in powershell

I am trying to get only AD Objects of type user and then iterate over all them and change AD user object name. So I have done below:
$Users = Get-ADObject -Filter {(ObjectClass -eq "user")} # OR Get-ADObject -Filter 'ObjectClass -eq "user"'
$Users | foreach
{
# Here code to create name based on conditions ($newUserObjectName)
Rename-ADObject -Identity $_ -NewName $newUserObjectName
}
The problem is that Get-ADObject is returning not only users but also computer objects.... I only want user object classes. Also I am not sure If below line of code is correct by setting identity to $_ in order to update the current user in the iteration:
Rename-ADObject -Identity $_ -NewName $newUserObjectName
Why not use Get-ADUser instead of Get-ADObject and just return the DistinguishedName? Obviously, DON'T just run this code :)
$users = (Get-ADUser -Filter *).DistinguishedName #This gets all the users in AD
Foreach($user in $users){
Rename-ADObject -Identity $user -NewName $newUserObjectName
}
The Computer objectClass is derived from the User objectClass. Hence, queries for user class will return both Computers and Users. If you want to filter for Users only, you have to specify ObjectCategory as Person
$Users = Get-ADObject -Filter {(Objectclass -eq "user") -and (objectCategory -eq "Person")}
Use that or you can use the goodole Get-ADuser
Use Get-ADUser and Set-ADUser:
$Users = Get-ADUser -Filter *
$Users | foreach {
# Naming code
Set-ADUser -Identity $_.SamAccountName -SamAccountName $newName
}
This replaces all user's identities to $newName.
Note you can replace -SamAccountName with any other property of an ADUser. for example if you want to replace the display name instead, you would use -Name $newName

How can I loop through OU in AD to add users to various security groups?

I'm somewhat new to writing PS scripts, I usually only need simple one or two liners, but for this I'm trying to loop through a specific OU in Active Directory to find each users department, add "grp" before it and add them to the security group by that name. For example, a department might be something like 10005 so I'd like to add them to security group named "grp10005". Here's what I have but it isn't working.
Import-Module ActiveDirectory
$users = $i = $null
$strCC
$strGRP = 'grp' & strCC
$users = Get-ADUser -SearchBase "ou=Test,ou=OurUsers,ou=Logins,dc=domain,dc=com" -filter * {department -eq $strCC}
ForEach($user in $users)
{
Add-ADGroupMember 'strGRP' -Members $_.DistinguishedName
-ErrorAction SilentlyContinue
$i++
}
I removed the syntax errors and modified the approach a bit.
Import-Module ActiveDirectory
$users = $null
$strDept = "Finance"
$strGRP = ('grp' + $strDept)
$users = Get-ADUser -SearchBase "ou=Test,ou=OurUsers,ou=Logins,dc=domain,dc=com" -Filter { Department -eq $strDept }
ForEach($user in $users)
{
Add-ADGroupMember 'strGRP' -Members $user.DistinguishedName
-ErrorAction SilentlyContinue
}
Edit:
Based on the comments below it sounds like you are not wanting to use a filter at all but you want to check every user in the OU, find out what their current department is, then add them to a group by that name but with "grp" prefixed on to it.
Here is a possible solution:
Import-Module ActiveDirectory
$users = $null
$users = Get-ADUser -SearchBase "ou=Test,ou=OurUsers,ou=Logins,dc=domain,dc=com" -Filter * -Properties Department
ForEach($user in $users)
{
Add-ADGroupMember ("grp" + $user.Department) -Members $user.DistinguishedName -ErrorAction SilentlyContinue
}
You can use the following code:
Import-Module ActiveDirectory
$users = $null
$i = 0
$strCC = "CC"
$strGRP = ("GroupName" + $strCC)
$users = Get-ADUser -SearchBase "ou=Test,ou=OurUsers,ou=Logins,dc=domain,dc=com" -filter {department -eq $strCC}
ForEach($user in $users)
{
Add-ADGroupMember $strGRP -Members $user.DistinguishedName `
-ErrorAction SilentlyContinue
$i++
}
Note the difference between the two types of loop:
$array | foreach-object {
Write-Host $_
}
and:
foreach ($item in $array) {
Write-Host $item
}

List AD users who do not belong to one of several groups

First up, I am not a script writer, so I apologise if this sounds like a real newbie question.
I am trying to write a Powershell query to list all user accounts within a certain OU sub-tree who do not belong to at least one of 4 groups.
As far as I can tell you cannot query this directly on the AD User object, so you need to iterate through the groups to get the membership, but I'm not clear on how to go about this across multiple groups.
I have put together a script that can find all users, add them to a temporary group and then remove them if they belong to one of the four other groups, but this looks like a horrible way to approach it, so I am hoping someone has a better solution.
Here's what I currently have (don't laugh) :-(
Import-Module ActiveDirectory
$groupname = "TempGroup"
$excludegroup1 = "Group1"
$excludegroup2 = "Group2"
$excludegroup2 = "Group4"
$excludegroup2 = "Group4"
$users = Get-ADUser -Filter * -SearchBase "ou=xxx,dc=xxx,dc=xxx" -SearchScope Subtree
foreach($user in $users)
{
Add-ADGroupMember -Identity $groupname -Member $user.samaccountname -ErrorAction SilentlyContinue
}
$members = Get-ADGroupMember -Identity $groupname
$excludemembers = Get-ADGroupMember -Identity $excludegroup1
foreach($member in $excludemembers)
{
Remove-ADGroupMember -Identity $groupname -Member $member.samaccountname
}
$members = Get-ADGroupMember -Identity $groupname
$excludemembers = Get-ADGroupMember -Identity $excludegroup2
foreach($member in $excludemembers)
{
Remove-ADGroupMember -Identity $groupname -Member $member.samaccountname
}
$members = Get-ADGroupMember -Identity $groupname
$excludemembers = Get-ADGroupMember -Identity $excludegroup3
foreach($member in $excludemembers)
{
Remove-ADGroupMember -Identity $groupname -Member $member.samaccountname
}
$members = Get-ADGroupMember -Identity $groupname
$excludemembers = Get-ADGroupMember -Identity $excludegroup4
foreach($member in $excludemembers)
{
Remove-ADGroupMember -Identity $groupname -Member $member.samaccountname
}
All help gratefully accepted.
All users, computers, groups and contacts (and possibly other objects) in Active Directory have a property called memberof. This property contains the distinguished names of all groups from the whole forest that this entity is a member of, as the attribute's name implies.
Given this information, you can now construct an ldap search query to find all entities that are not members of at least one of those groups:
(!(|(memberof=CN=Group1,dc=domain,dc=com)(memberof=CN=Group3,dc=domain,dc=com)(memberof=CN=Group3,dc=domain,dc=com)))
Other conditions may be included as necessary.
If you need to obtain the distinguished names of those groups first, you can either hard-code them in your filter or do a normal Powershell search for the groups and then read their distinguished names.
You can use the ldap query via the command's -LDAPFilter parameter.
In case anyone is interested, this is the code I have now. It uses a group, which it flushes each run, because then I can simply double-click a user to get into their object and add them to the group they're missing from.
Import-Module ActiveDirectory
$groupname = "NotInGroups"
$members = Get-ADGroupMember -Identity $groupname
foreach($member in $members)
{
Remove-ADGroupMember -Identity $groupname -Member $member.samaccountname
}
$users = Get-ADUser -Filter {((memberof -notlike "CN=Group1,DC=domain,DC=local") -AND (memberof -notlike "CN=Group2,DC=domain,DC=local") -AND (memberof -notlike "CN=Group3,DC=domain,DC=local") -AND (memberof -notlike "CN=Group4,DC=domain,DC=local"))} -SearchBase "ou=users,dc=domin,dc=local" -SearchScope Subtree
foreach($user in $users)
{
Add-ADGroupMember -Identity $groupname -Member $user.samaccountname -ErrorAction SilentlyContinue
}