Power shell script that can check each group if there is a nested group. Remove it and add those nested group members into the main group.

bsharath
bsharath used Ask the Experts™
on
Hi,

Power shell script that can check each group if there is a nested group. Remove it and add those nested group members into the main group.

Say i have 10 groups in an OU.
When run need to check each group.
If group A has 5 users and 1 group then check all members within that group and add them to group A and then remove the group thats nested.

need a log to show what the changes were done.

Can anyone help me with this..

Regards
Sharath
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
What WIndows Server version of DCs, what PowerShell version?
If the Windows is older than 2008 R2, do you have or is it possible to install the Management Gateway, so that we can use the PS 2.0 Active Directory Module?

Author

Commented:
Windows 2003 and windows 2008 Dc's
Powershell 1.0 & 2.0
Chris DentPowerShell Developer
Top Expert 2010

Commented:

Uses Quest CmdLets (http://www.quest.com/powershell/activeroles-server.aspx).

I suggest you test it on a limited set first because I haven't tested it at all.

Chris
# Load Quest CmdLets
Get-PsSnapIn -Reg | Add-PsSnapIn -ErrorAction SilentlyContinue

# Find groups
Get-QADGroup -SearchRoot "OU=Somewhere,DC=domain,DC=com" -SizeLimit 0 | ForEach-Object {
  $BaseGroup = $_.DN

  # Get all group members (Indirect Only)
  Get-QADGroupMember $BaseGroup -Indirect -SizeLimit 0 -LdapFilter "(!(memberOf=$BaseGroup))" | 
      Where-Object { $_.Type -Match "User|Contact" } | 
      ForEach-Object {

    $_ | Select-Object @{n='Operation';e={ "Adding Member to Base" }}, Name, DN
    Add-QADGroupMember $BaseGroup -Member $_.DN | Out-Null
  }
  Get-QADGroupMember $BaseGroup -Type Group -SizeLimit 0 | ForEach-Object {
    $_ | Select-Object @{n='Operation';e={ "Removing Group from Base" }}, Name, DN
    Remove-QADGroupMember $BaseGroup -Member $_.DN
  }
} | Export-CSV "LogFile.csv"

Open in new window

Expert Spotlight: Joe Anderson (DatabaseMX)

We’ve posted a new Expert Spotlight!  Joe Anderson (DatabaseMX) has been on Experts Exchange since 2006. Learn more about this database architect, guitar aficionado, and Microsoft MVP.

Author

Commented:
Thanks Chris works fine on the test
If the Group B has Contacts as members will it be added.?
Removing i get the group name twice in the log file
Can i get each groups log in each sheet please...
Chris DentPowerShell Developer
Top Expert 2010

Commented:

> If the Group B has Contacts as members will it be added.?

Yes.

> Removing i get the group name twice in the log file

Should be fixed below.

> Can i get each groups log in each sheet please...

No, I don't pull that information.

Chris
# Load Quest CmdLets
Get-PsSnapIn -Reg | Add-PsSnapIn -ErrorAction SilentlyContinue

# Find groups
Get-QADGroup -SearchRoot "OU=Somewhere,DC=domain,DC=com" -SizeLimit 0 | ForEach-Object {
  $BaseGroup = $_.DN

  # Get all group members (Indirect Only)
  Get-QADGroupMember $BaseGroup -Indirect -SizeLimit 0 -LdapFilter "(!(memberOf=$BaseGroup))" | 
      Where-Object { $_.Type -Match "User|Contact" } | 
      ForEach-Object {

    $_ | Select-Object @{n='Operation';e={ "Adding Member to Base" }}, Name, DN
    Add-QADGroupMember $BaseGroup -Member $_.DN | Out-Null
  }
  Get-QADGroupMember $BaseGroup -Type Group -SizeLimit 0 | ForEach-Object {
    $_ | Select-Object @{n='Operation';e={ "Removing Group from Base" }}, Name, DN
    Remove-QADGroupMember $BaseGroup -Member $_.DN | Out-Null
  }
} | Export-CSV "LogFile.csv"

Open in new window

Author

Commented:
Thanks
How will i know from the log which group its worked and removed and added on.
As the log shows all groups data in one colum
No GroupA names shown
Chris DentPowerShell Developer
Top Expert 2010

Commented:

This adds the base group name to the output, that part was an oversight.

Chris
# Load Quest CmdLets
Get-PsSnapIn -Reg | Add-PsSnapIn -ErrorAction SilentlyContinue

# Find groups
Get-QADGroup -SearchRoot "OU=Somewhere,DC=domain,DC=com" -SizeLimit 0 | ForEach-Object {
  $BaseGroup = $_

  # Get all group members (Indirect Only)
  Get-QADGroupMember $BaseGroup.DN -Indirect -SizeLimit 0 -LdapFilter "(!(memberOf=$BaseGroup))" | 
      Where-Object { $_.Type -Match "User|Contact" } | 
      ForEach-Object {

    $_ | Select-Object @{n='Operation';e={ "Adding Member to Base" }},
      @{n='Base Group';e={ $BaseGroup.Name }}, Name , DN
    Add-QADGroupMember $BaseGroup.DN -Member $_.DN | Out-Null
  }
  Get-QADGroupMember $BaseGroup -Type Group -SizeLimit 0 | ForEach-Object {
    $_ | Select-Object @{n='Operation';e={ "Removing Group from Base" }}, 
      @{n='Base Group';e={ $BaseGroup.Name }}, Name , DN
    Remove-QADGroupMember $BaseGroup.DN -Member $_.DN | Out-Null
  }
} | Export-CSV "LogFile.csv"

Open in new window

Chris DentPowerShell Developer
Top Expert 2010

Commented:

Sorry, another mistake to fix.

Chris
# Load Quest CmdLets
Get-PsSnapIn -Reg | Add-PsSnapIn -ErrorAction SilentlyContinue

# Find groups
Get-QADGroup -SearchRoot "OU=Somewhere,DC=domain,DC=com" -SizeLimit 0 | ForEach-Object {
  $BaseGroup = $_

  # Get all group members (Indirect Only)
  Get-QADGroupMember $BaseGroup.DN -Indirect -SizeLimit 0 -LdapFilter "(!(memberOf=$($BaseGroup.DN)))" | 
      Where-Object { $_.Type -Match "User|Contact" } | 
      ForEach-Object {

    $_ | Select-Object @{n='Operation';e={ "Adding Member to Base" }},
      @{n='Base Group';e={ $BaseGroup.Name }}, Name , DN
    Add-QADGroupMember $BaseGroup.DN -Member $_.DN | Out-Null
  }
  Get-QADGroupMember $BaseGroup.DN -Type Group -SizeLimit 0 | ForEach-Object {
    $_ | Select-Object @{n='Operation';e={ "Removing Group from Base" }}, 
      @{n='Base Group';e={ $BaseGroup.Name }}, Name , DN
    Remove-QADGroupMember $BaseGroup.DN -Member $_.DN | Out-Null
  }
} | Export-CSV "LogFile.csv"

Open in new window

Author

Commented:
But now i dont get the members that were added from the removed groups
Chris DentPowerShell Developer
Top Expert 2010

Commented:

If the script has already completed then you wouldn't, or are you running it on another group?

Chris

Author

Commented:
Thanks my mistake. it took some time to replicate
If there is an issue in additing or removing will it be logged?
Chris DentPowerShell Developer
Top Expert 2010

Commented:

Not at present, no.

This may / should work to catch that.

Chris
# Load Quest CmdLets
Get-PsSnapIn -Reg | Add-PsSnapIn -ErrorAction SilentlyContinue

# Find groups
Get-QADGroup -SearchRoot "OU=Somewhere,DC=domain,DC=com" -SizeLimit 0 | ForEach-Object {
  $BaseGroup = $_

  # Get all group members (Indirect Only)
  Get-QADGroupMember $BaseGroup.DN -Indirect -SizeLimit 0 -LdapFilter "(!(memberOf=$($BaseGroup.DN)))" | 
      Where-Object { $_.Type -Match "User|Contact" } | 
      ForEach-Object {

    $Added = Add-QADGroupMember $BaseGroup.DN -Member $_.DN
    If ($?) { $Success = $True } Else { $Success = $False }

    $_ | Select-Object @{n='Operation';e={ "Adding Member to Base" }},
      @{n='Base Group';e={ $BaseGroup.Name }}, Name , DN,
      @{n='Succeeded';e={ $Success }}

  }
  Get-QADGroupMember $BaseGroup.DN -Type Group -SizeLimit 0 | ForEach-Object {
    $Removed = Remove-QADGroupMember $BaseGroup.DN -Member $_.DN
    If ($?) { $Success = $True } Else { $Success = $False }

    $_ | Select-Object @{n='Operation';e={ "Removing Group from Base" }}, 
      @{n='Base Group';e={ $BaseGroup.Name }}, Name , DN,
      @{n='Succeeded';e={ $Success }}

  }
} | Export-CSV "LogFile.csv"

Open in new window

Author

Commented:
Thanks
I get these
Get-QADGroupMember : An operation error occurred.
At line:13 char:21
+   Get-QADGroupMember <<<<  $BaseGroup.DN -Type Group -SizeLimit 0 | ForEach-Object {
    + CategoryInfo          : NotSpecified: (:) [Get-QADGroupMember], DirectoryAccessException
    + FullyQualifiedErrorId : Quest.ActiveRoles.ArsPowerShellSnapIn.DirectoryAccess.DirectoryAccessException,Quest.Act
   iveRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetGroupMemberCmdlet
PowerShell Developer
Top Expert 2010
Commented:

> DirectoryAccessException

It's rather specific to your directory, lets have it write some progress so you can see which it's got to.

Chris
# Load Quest CmdLets
Get-PsSnapIn -Reg | Add-PsSnapIn -ErrorAction SilentlyContinue

# Find groups
Get-QADGroup -SearchRoot "OU=Somewhere,DC=domain,DC=com" -SizeLimit 0 | ForEach-Object {
  $BaseGroup = $_

  Write-Host "Processing $($BaseGroup.DN)"

  # Get all group members (Indirect Only)
  Get-QADGroupMember $BaseGroup.DN -Indirect -SizeLimit 0 -LdapFilter "(!(memberOf=$($BaseGroup.DN)))" | 
      Where-Object { $_.Type -Match "User|Contact" } | 
      ForEach-Object {

    $Added = Add-QADGroupMember $BaseGroup.DN -Member $_.DN
    If ($?) { $Success = $True } Else { $Success = $False }

    $_ | Select-Object @{n='Operation';e={ "Adding Member to Base" }},
      @{n='Base Group';e={ $BaseGroup.Name }}, Name , DN,
      @{n='Succeeded';e={ $Success }}

  }
  Get-QADGroupMember $BaseGroup.DN -Type Group -SizeLimit 0 | ForEach-Object {
    $Removed = Remove-QADGroupMember $BaseGroup.DN -Member $_.DN
    If ($?) { $Success = $True } Else { $Success = $False }

    $_ | Select-Object @{n='Operation';e={ "Removing Group from Base" }}, 
      @{n='Base Group';e={ $BaseGroup.Name }}, Name , DN,
      @{n='Succeeded';e={ $Success }}

  }
} | Export-CSV "LogFile.csv"

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial