Find users in AD group and add them into another group - powershell

I have Kerio Connect server and it doesn't allow group inheritance. So I need to create one group for mail and another group for AD with similar users.
I wrote:
Import-Module ActiveDirectory
Get-ADGroupMember -Identity Sales.Department |select SamAccountName |ForEach-Object {Add-ADGroupMember -Identity sales.mail -Members $_.SamAccountName}
And I need to make it for all groups with expression *.Department and mail groups with *.mail

Retrieve the group members of sales.department using Get-ADGroup and then add the group members to sales.mail using Add-ADGroupMember
$MemberList = (Get-ADGroup -Identity "sales.department" -Properties member).member
Add-ADGroupMember -Identity "sales.mail" -Members $MemberList

For that pupose you better use the Add-ADPrincipalGroupMembership cmdlet instead of the Add-ADGroupMember: For me is working fine:
Get-ADGroupMember -Identity Source-Group-Name |select SamAccountName |ForEach-Object {Add-ADPrincipalGroupMembership -Identity $_.SamAccountName -MemberOf Target-Group-Name}

Related

PowerShell Set-ADGroup replace member multiple domains (FSP)

I am trying to set the membership of a group using Set-ADGroup with the -Replace parameter. I tried with
$adUsers = #()
$adUsers += Get-ADUser -Server domain1.corp.com -Identity user1
$adUsers += Get-ADUser -Server domain2.corp.com -Identity user2
$adUsers = $adUsers | select-object -expandproperty distinguishedname
Set-ADGroup -Server domain3.corp.com -Identity mygroup -Replace #{Member=$adUsers}
but that fails with
The specified account does not exist.
If you looked at my previous attempt you might have noted that my user objects come from two different doamins while my group comes from a third one.
So to test my code, I simplified my setup and tried with users coming from the same domain as the one where the group was located in
$adUsers = #()
$adUsers += Get-ADUser -Server domain3.corp.com -Identity user4
$adUsers += Get-ADUser -Server domain3.corp.com -Identity user5
$adUsers = $adUsers | select-object -expandproperty distinguishedname
Set-ADGroup -Server domain3.corp.com -Identity mygroup -Replace #{Member=$adUsers}
This works.
So I figured the AD module might not be liking FSPs.
But then I ran the following code:
$adUsers = #()
$adUsers += Get-ADUser -Server domain1.corp.com -Identity user1
$adUsers += Get-ADUser -Server domain2.corp.com -Identity user2
Add-ADGroupMember -Server domain3.corp.com -Identity mygroup -Members $adUsers
And this works. So it seems working with FSPs is certainly possible in the AD module.
But why is it not working for Set-ADGroup?
Should I be using something different from the distinguished name? I tried with the string representation of the SID, but that seems to be even worse (An internal error occured).
I am aware that I could use a combination of Remove-ADGroupMember and Add-ADGroupMember to make my code work but that seems inefficient as I would have to figure out first which users to remove. Replacing the member list with the correct entries seems more performant.
Update After some more testing I discovered that using the FSP in combination with Set-ADGroup works. So I can use 'CN=S-1-5-21-xxx-yyy-zzz-rid,CN=ForeignSecurityPrincipals,DC=DOMAIN3,DC=CORP,DC=com'. Of course that implies the FSP object exists already in DOMAIN3. Because if it does not and I fake the distinguishedname, the method logically just returns
Set-ADGroup: An internal error occurred.
Now I am wondering if Set-ADGroup -replace method can only work with existing objects while Add-ADGroupMember can also create (FSP) objects.
The problem was with the way the data needs to be formatted. You can use a users SID but it needs to be in the format <SID=S-1-5-21-xxx-yyy-zzz-rid>. This way FSPs are also automatically created when necessary
So my code ended up being something like:
[string[]]$sids= #()
$sids+= Get-ADUser -Server domain1.corp.com -Identity user1 -Properties #('SID') | ForEach-Object { '<SID=' + $_.SID + '>'}
$sids+= Get-ADUser -Server domain2.corp.com -Identity user2 -Properties #('SID') | ForEach-Object { '<SID=' + $_.SID + '>'}
Set-ADGroup -Server domain3.corp.com -Identity mygroup -Replace #{Member=$sids}

Powershell: How to get specific properties from users in a OU

I am trying to get some information for an audit. here's the code that i used but the output is empty except for the name. Can anyone point me in the right direction?
Thanks in advance!
$ou = Get-ADGroup -Identity Administrators -Properties member
$user = Get-ADGroupmember -Identity $ou
foreach ($user in $ou){
Get-ADGroupmember -Identity Administrators | Select-Object name, lastlogondate,passwordlastset
}
Try this
$members = Get-ADGroupMember -Identity Administrators -recursive | select samaccountname
foreach ($user in $members){
Get-ADUser -Identity $user.samaccountname -Properties name, lastlogondate,passwordlastset| Select-Object name, lastlogondate,passwordlastset
}
By default the properties lastlogondate and passwordlastset are not returned, you have to specify those (or all by using a *) using the -properties argument
Get-ADGroupmember -Identity Administrators -properties name,lastlogondate,passwordlastset | Select-Object name, lastlogondate,passwordlastset
or
Get-ADGroupmember -Identity Administrators -properties * | Select-Object name, lastlogondate,passwordlastset

Faster Way to remove users from a huge list of groups?

I run the following code to remove disabled users from a list of 9874 groups:
$user = get-aduser <userid> -Server "<server from another domain>"
foreach ($Group in $Groups) {
Write-Host "Removing $user from $group" -Foreground Green
Remove-ADGroupMember -Identity $group -Members $user -Confirm:$false
}
It's a bottle neck for me as it checks/removes the account from each group. Is there a way to speed this up with more efficient PS code?
If memberOf is the only thing are you interested in for a given user, you can run the following. It only loads the memberOf property and removes the user from each of these. Gives you a bit of a performance boost since its not loading all the account properties.
Get-ADUser <userid> -Server "<server from another domain>" -Properties MemberOf `
| Select -Expand MemberOf | % {
Remove-ADGroupMember $_ -member <userid>"
}

Powershell - Remove-ADGroupMember

I'm trying to remove the groups from users in other domain.
Example: Me as admin wants to disable an user and remove his groups in other domain.
The problem is I don't know how to use Remove-ADGroupMember -Server in Foreach loop, if I don't use Foreach I can use the -Server option.
Error of Remove-ADGroupmember:
How can I get -Server property within Foreach?
$groups = (Get-Aduser -server ServerY -Identity manusys -Properties MemberOf).memberof
Foreach ($group in $groups) {
Remove-ADGroupMember -identity $group -Members manusys -Confirm:$false -ErrorAction:SilentlyContinue
}
The user account Manusys has these groups:
CN=NO_CamerasAlertMGR,OU=Ordinary Distribution Lists,OU=Distribution Lists,DC=test,DC=com
CN=NO_CamerasAlertCM,OU=Ordinary Distribution Lists,OU=Distribution Lists,DC=test,DC=com
CN=NO_CamerasReport,OU=Ordinary Distribution Lists,OU=Distribution Lists,DC=test,DC=com
CN=NO_CamerasReport_CM,OU=Ordinary Distribution Lists,OU=Distribution Lists,DC=test,DC=com
CN=NO_CamerasReport_MGR,OU=Ordinary Distribution Lists,OU=Distribution Lists,DC=test,DC=com
The Server param is available to use with Remove-ADGroupMember, using it within foreach doesn't change this.
Don't just rely on the ISE auto-prompts, referring to the documentation (remove-adgroupmember) will always show you what parameters are available.
The problem you are actually seeing, is that the ISE no longer prompts/shows the commands parameters once you've used one of the Common Parameters (Confirm & ErrorAction in your code, but there are others)...
You can see this with the command by itself - it will continue to prompt for params:
Remove-ADGroupMember -identity $group -Members manusys
But add a CommonParam, and it will not provide its own params anymore:
Remove-ADGroupMember -identity $group -Members manusys -Confirm:$false
So to fix your original issue, add the Server param to Remove-ADGroupMember:
$groups = (Get-Aduser -server ServerY -Identity manusys -Properties MemberOf).memberof
Foreach ($group in $groups) {
Remove-ADGroupMember -server ServerY -identity $group -Members manusys -Confirm:$false -ErrorAction:SilentlyContinue
}

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
}