?
Solved

Create/manage shadow groups by script

Posted on 2011-04-20
11
Medium Priority
?
2,274 Views
Last Modified: 2012-05-11
Hey

I'm looking for a script for managing my shadow groups in Active Directory.

Company -> Dep1 -> Tech
Company -> Dep1 -> Users
Company -> Dep2 -> Tech
Company -> Dep2 -> Users

I would like to have:

Shadow Group Company (all users - including sub ou's)
Shadow Group Company, Dep1 (all users in Dep1 - including sub ou's)
Shadow Group Company, Dep1, Tech (all users in Tech)
... etc. etc...

I have found this: http://www.sole.dk/post/active-directory-shadow-group-script-will-let-you-spend-less-time-on-updating-group-memberships/?p=446

... but I need to have the full OU in the shadow group name

Thanks in advance.

Mike
0
Comment
Question by:mikeydk
  • 6
  • 3
9 Comments
 
LVL 13

Expert Comment

by:soostibi
ID: 35438755
Do you have Windows Server 2008 R2 DCs or can we use Quest's AD PowerShell snapin?
0
 
LVL 1

Author Comment

by:mikeydk
ID: 35450382
Yes running 2008 R2 DCs...
0
 
LVL 13

Expert Comment

by:soostibi
ID: 35453054
If you run and define the function defined in the attached script you can use it these ways:


- for the whole domain:
sync-shadowgroup -root "dc=yoursubdomain,dc=yourmaindomain" -recurse

for just one OU, but not for sub-OUs:
sync-shadowgroup -root "OU=yourOU,dc=yoursubdomain,dc=yourmaindomain"

for one OU, and all its sub-OUs:
sync-shadowgroup -root "OU=yourOU,dc=yoursubdomain,dc=yourmaindomain" -recurse

It creates the following name for the Shadow Groups:

shadow-yourmaindomain-yoursubdomain-yourmainOU-yoursubOU

It deletes any members from the shadowgroup, which is moved to a different OU and inserts any new user.

Hope this is close to your request.  
Import-Module activedirectory

function sync-shadowgroup {
param(
    [Parameter(
        Mandatory = $true,
        ValueFromPipeline = $true
    )]
    [string] $root,
    [switch] $recurse
)
$ofs = "-"
$oubase = Get-ADObject -Identity $root
$ous = if($recurse){Get-ADOrganizationalUnit -SearchBase $oubase -Filter *}
    else{Get-ADOrganizationalUnit -Identity $oubase}
if(!$ous){throw "Invalid OU or DN root!"}

$ous | %{
$ou = $_
$narr = ($ou.distinguishedname -split ",?\w\w=") | ?{$_}
$fullname = [string] $narr[-1..-($narr.count)]
$shgname = "shadow-$fullname"

$sh = Get-ADGroup -SearchBase $ou -Filter {name -eq $shgname} -ErrorAction silentlycontinue
if(!$sh){
    $sh = New-ADGroup -Path $ou -Name $shgname -GroupCategory security -GroupScope global -PassThru
}

Get-ADUser -ResultSetSize $null -SearchBase $ou -Filter * -Properties memberof |  %{
   if($_.memberof -notcontains $sh.distinguishedname){Add-ADGroupMember -Identity $sh -Members $_}
}
Get-ADGroupMember -Identity $sh | %{
    if($_.distinguishedname -notmatch ([regex]::Escape("$($ou.distinguishedname)"))){
        Remove-ADGroupMember -Identity $sh -Members $_ -Confirm:$false
    }
}
}
}

Open in new window

0
A Cyber Security RX to Protect Your Organization

Join us on December 13th for a webinar to learn how medical providers can defend against malware with a cyber security "Rx" that supports a healthy technology adoption plan for every healthcare organization.

 
LVL 13

Expert Comment

by:soostibi
ID: 35453061
And you can also use it in a pipeline with or without the recurse switch:

Get-ADOrganizationalUnit -Filter {name -eq 'yourOUsSimpleName'} | sync-shadowgroup
0
 
LVL 1

Author Comment

by:mikeydk
ID: 35458346
Hey

Thanks ;) It works...

But... I get the follownig error at my root OU:

Get-ADGroupMember : The size limit for this request was exceeded
At C:\Scripts\SG.ps1:33 char:18
+ Get-ADGroupMember <<<<  -Identity $sh | %{
    + CategoryInfo          : NotSpecified: (CN=PIT_SG_local...=skole,DC=local:ADGroup) [Get-ADGroupMember], ADExcepti
   on
    + FullyQualifiedErrorId : The size limit for this request was exceeded,Microsoft.ActiveDirectory.Management.Comman
   ds.GetADGroupMember

Do you know why?
0
 
LVL 13

Expert Comment

by:soostibi
ID: 35458739
There is a default result size limit of 1000 object for Get-AD.... cmdlets. Here is a corrected script.
Import-Module activedirectory

function sync-shadowgroup {
param(
    [Parameter(
        Mandatory = $true,
        ValueFromPipeline = $true
    )]
    [string] $root,
    [switch] $recurse
)
$ofs = "-"
$oubase = Get-ADObject -Identity $root
$ous = if($recurse){Get-ADOrganizationalUnit -ResultSetSize $null -SearchBase $oubase -Filter * }
    else{Get-ADOrganizationalUnit -Identity $oubase -ResultSetSize $null}
if(!$ous){throw "Invalid OU or DN root!"}

$ous | %{
$ou = $_
$narr = ($ou.distinguishedname -split ",?\w\w=") | ?{$_}
$fullname = [string] $narr[-1..-($narr.count)]
$shgname = "shadow-$fullname"

$sh = Get-ADGroup -SearchBase $ou -Filter {name -eq $shgname} -ErrorAction silentlycontinue
if(!$sh){
    $sh = New-ADGroup -Path $ou -Name $shgname -GroupCategory security -GroupScope global -PassThru
}

Get-ADUser -ResultSetSize $null -SearchBase $ou -Filter * -Properties memberof -ResultSetSize $null |  %{
   if($_.memberof -notcontains $sh.distinguishedname){Add-ADGroupMember -Identity $sh -Members $_}
}
Get-ADGroupMember -Identity $sh -ResultSetSize $null | %{
    if($_.distinguishedname -notmatch ([regex]::Escape("$($ou.distinguishedname)"))){
        Remove-ADGroupMember -Identity $sh -Members $_ -Confirm:$false
    }
}
}
}

Open in new window

0
 
LVL 1

Author Comment

by:mikeydk
ID: 35468315
Hey

Now I get:

Get-ADUser : Cannot bind parameter because parameter 'ResultSetSize' is specified more than once. To provide multiple v
alues to parameters that can accept multiple values, use the array syntax. For example, "-parameter value1,value2,value
3".
At line:24 char:94
+ Get-ADUser -ResultSetSize $null -SearchBase $ou -Filter * -Properties memberof -ResultSetSize <<<<  $null |  %{
    + CategoryInfo          : InvalidArgument: (:) [Get-ADUser], ParameterBindingException
    + FullyQualifiedErrorId : ParameterAlreadyBound,Microsoft.ActiveDirectory.Management.Commands.GetADUser

Get-ADGroupMember : A parameter cannot be found that matches parameter name 'ResultSetSize'.
At line:27 char:47
+ Get-ADGroupMember -Identity $sh -ResultSetSize <<<<  $null | %{
    + CategoryInfo          : InvalidArgument: (:) [Get-ADGroupMember], ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.ActiveDirectory.Management.Commands.GetADGroupMember
0
 
LVL 13

Accepted Solution

by:
soostibi earned 2000 total points
ID: 35469969
Sorry there is result set size two times in line 29. But unfortunately Get-ADGroupMember does not have a result set size parameter.
The root of the domain is the only place where you get this error message? If so, we have to exclude this from making a shadow group.
Import-Module activedirectory

function sync-shadowgroup {
param(
    [Parameter(
        Mandatory = $true,
        ValueFromPipeline = $true
    )]
    [string] $root,
    [switch] $recurse
)
$ofs = "-"
$oubase = Get-ADObject -Identity $root
$ous = if($recurse){Get-ADOrganizationalUnit -ResultSetSize $null -SearchBase $oubase -Filter * }
    else{Get-ADOrganizationalUnit -Identity $oubase -ResultSetSize $null}
if(!$ous){throw "Invalid OU or DN root!"}

$ous | %{
$ou = $_
$narr = ($ou.distinguishedname -split ",?\w\w=") | ?{$_}
$fullname = [string] $narr[-1..-($narr.count)]
$shgname = "shadow-$fullname"

$sh = Get-ADGroup -SearchBase $ou -Filter {name -eq $shgname} -ErrorAction silentlycontinue
if(!$sh){
    $sh = New-ADGroup -Path $ou -Name $shgname -GroupCategory security -GroupScope global -PassThru
}

Get-ADUser -ResultSetSize $null -SearchBase $ou -Filter * -Properties memberof |  %{
   if($_.memberof -notcontains $sh.distinguishedname){Add-ADGroupMember -Identity $sh -Members $_}
}
Get-ADGroupMember -Identity $sh | %{
    if($_.distinguishedname -notmatch ([regex]::Escape("$($ou.distinguishedname)"))){
        Remove-ADGroupMember -Identity $sh -Members $_ -Confirm:$false
    }
}
}
}

Open in new window

0
 
LVL 13

Expert Comment

by:soostibi
ID: 35470161
I found an alternative solution, please test it!
Import-Module activedirectory

function sync-shadowgroup {
param(
    [Parameter(
        Mandatory = $true,
        ValueFromPipeline = $true
    )]
    [string] $root,
    [switch] $recurse
)
$ofs = "-"
$oubase = Get-ADObject -Identity $root
$ous = if($recurse){Get-ADOrganizationalUnit -ResultSetSize $null -SearchBase $oubase -Filter * }
    else{Get-ADOrganizationalUnit -Identity $oubase}
if(!$ous){throw "Invalid OU or DN root!"}

$ous | %{
$ou = $_
$narr = ($ou.distinguishedname -split ",?\w\w=") | ?{$_}
$fullname = [string] $narr[-1..-($narr.count)]
$shgname = "shadow-$fullname"

$sh = Get-ADGroup -SearchBase $ou -Filter {name -eq $shgname} -ErrorAction silentlycontinue
if(!$sh){
    $sh = New-ADGroup -Path $ou -Name $shgname -GroupCategory security -GroupScope global -PassThru
}

Get-ADUser -ResultSetSize $null -SearchBase $ou -Filter * -Properties memberof |  %{
   if($_.memberof -notcontains $sh.distinguishedname){Add-ADGroupMember -Identity $sh -Members $_}
}
$shdn = $sh.distinguishedname
Get-ADUser -ResultSetSize $null -Filter {memberof -eq $shdn} | %{
    if($_.distinguishedname -notmatch $ou.distinguishedname){
        Remove-ADGroupMember -Identity $sh -Members $_ -Confirm:$false
    }
} 
}
}

Open in new window

0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Compliance and data security require steps be taken to prevent unauthorized users from copying data.  Here's one method to prevent data theft via USB drives (and writable optical media).
High user turnover can cause old/redundant user data to consume valuable space. UserResourceCleanup was developed to address this by automatically deleting user folders when the user account is deleted.
This tutorial will walk an individual through the process of configuring their Windows Server 2012 domain controller to synchronize its time with a trusted, external resource. Use Google, Bing, or other preferred search engine to locate trusted NTP …
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

807 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question