Active Directory筛选成员

时间:2009-09-09 20:25:35

标签: sharepoint powershell active-directory

我试图将所有CN从活动目录中删除,以便将基于该名称的组填充到Sharepoint Services中。我可以列出“memberof”部分,但我似乎无法使用split(“,”)

拆分它
$Dom = 'LDAP://OU=External,OU=Users,OU=HomeOffice,DC=mydoman,DC=com'
$Root = New-Object DirectoryServices.DirectoryEntry $Dom 
$i=0
# Create a selector and start searching from the Root of AD
$selector = New-Object DirectoryServices.DirectorySearcher
$selector.SearchRoot = $root 
$adobj= $selector.findall() |`
where {$_.properties.objectcategory -match "CN=Person"} 
foreach ($person in $adobj){ 
    $prop=$person.properties
    $i++
    Write-host "$($prop.department) - $($prop.sn), $($prop.givenname)"
    Write-host $person.properties["memberof"]
}
"Total $i"

现在我得到了我需要的一切,但我需要一些方法来过滤掉CN的......

2 个答案:

答案 0 :(得分:1)

作为一般规则,write-host不是生成输出的最佳方式。理想情况下,您希望从函数中发出对象,并让PowerShell为您执行格式化。这是更“管道友好”的做事方式。在这种情况下,如果你有一个Get-GroupMembers函数,你可以将它传递给类似

的东西
Get-Person | ft CN

诀窍是创建一个新对象并向其添加属性,或者只是发出你正在拉动的DirectoryServices对象。要创建新的自定义对象,您可以执行以下操作:

$obj = new-object psobject 
$obj | add-member -membertype noteproperty name $PropName -value $valueToStore

人们可以使用你的函数并将它传递给format-table,format-list,select-object,group-object,sort-object和各种其他东西。 Keith Hill的有效PowerShell有一个很棒的chapter on Output,你可能会发现它很有帮助。

Don Jones on using objects instead of text还有一篇文章也很好。

答案 1 :(得分:0)

test1.ps1

#Connet using LDAP
$Dom = 'LDAP://OU=External Accounts,OU=Users,OU=The Office,DC=mydomain,DC=com'
$Root = New-Object DirectoryServices.DirectoryEntry $Dom 

#Integer for the loop
$i=0

# Create a selector and start searching from the Root of AD
$selector = New-Object DirectoryServices.DirectorySearcher
$selector.SearchRoot = $root 

#Find the Groups
$adobj= $selector.findall() |`
where {$_.properties.objectcategory -match "CN=Person"} 
foreach ($person in $adobj){ 
    $prop=$person.properties
    $i++
    #Write-host "$($prop.department) - $($prop.sn), $($prop.givenname)" -foregroundcolor Magenta
    $test = $person.properties["memberof"]
    ForEach-Object {
        $test`
        -replace "CN=OLDLEGACYGROUP",""`
        -replace "CN=",""`
        -replace ",OU=Sales",""`
        -replace ",OU=Some Groups",""`
        -replace ",OU=Groups","" `
        -replace ",OU=The Office","" `
        -replace ",DC=mydomain","" `
        -replace ",DC=com","" `
        -replace ",","`r`n"
    }
}

test2.ps1

# Lets start with a clean slate :)
Clear

# Lets reference the assembly / GAC that we need for this
#region
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
$SPSite = New-Object Microsoft.SharePoint.SPSite("https://myintranetorextranetsite.myfqdn.com")
$OpenWeb = $SpSite.OpenWeb("/") 
#endregion

# Add some eye candy :)
# region
# I really wanted some old school thing in here :)
write-host "    _    ____       ____                   " -foregroundcolor Magenta
write-host "   / \  |  _ \     / ___| _   _ _ __   ___ " -foregroundcolor Magenta
write-host "  / _ \ | | | |____\___ \| | | | '_ \ / __|" -foregroundcolor Magenta
write-host " / ___ \| |_| |_____|__) | |_| | | | | (__ " -foregroundcolor Magenta
write-host "|_/   \_\____/     |____/ \__, |_| |_|\___|" -foregroundcolor Magenta
write-host "                          |___/            " -foregroundcolor Magenta
Write-Host "    Version 2.0" -foregroundcolor Red
Write-Host "    Build 2009 09-11 21:30" -foregroundcolor Red
Write-host "    Created by Mitchell J. Skurnik" -foregroundcolor Red
#endregion

# Create the stopwatch
#region
[System.Diagnostics.Stopwatch] $sw;
$sw = New-Object System.Diagnostics.StopWatch
$sw.Stop()
$sw.Start()
#endregion

# Function to control Adding groups
function creategroup
{
    param ([string] $siteurl = "https://myintranetorextranetsite.myfqdn.com")
    $site = New-Object Microsoft.SharePoint.SPSite($siteurl)
    $web = $site.RootWeb;
    $group = $currentgroup;
    $perm = "Read";
    $owner = "jdoe";
    if ($owner -eq "") { $owner = $web.CurrentUser.LoginName }

    $exists = $web.SiteGroups | where { $_.Name -eq $group }
    if ($exists -eq $null)
    {
        # Create group
        $web.SiteGroups.Add($group, $web.EnsureUser($owner), $null, "");
        # Give permissions to the group
        $assign = New-Object Microsoft.SharePoint.SPRoleAssignment($web.SiteGroups[$group]);
        $assign.RoleDefinitionBindings.Add($web.RoleDefinitions[$perm])
        $web.RoleAssignments.Add($assign)
        Write-Host -ForegroundColor green "Creating sharepoint group - " $currentgroup;
    } 
    $site.Dispose();
}

# Function to add users to the specified group
function addUser
{
    # Open a connection to the sharepoint  site and then select the sub site you want
    $themail = $prop.mail
    $thedisplay = $prop.displayname

    # If there are accounts that dont have some info lets populate it
    if ($themail -eq "")
    {
        $themail = "testaccount@myfqdn.com"
    }
    if ($thedisplay -eq "")
    {
        $thedisplay = "Account, Test"
    }
    if ($themail -eq $null)
    {
        $themail = "testaccount@myfqdn.com"
    }
    if ($thedisplay -eq $null)
    {
        $thedisplay = "Account, Test"
    }
    $TheNewGroup = $OpenWeb.SiteGroups | Where-Object {$_.Name -match $currentGroup}
    $TheNewGroup.AddUser("NTAMR\" + $prop.samaccountname,$themail,$prop.displayname,"")
    #write-host "Added: " $thedisplay -foregroundcolor Red
}

# Function to remove people - be careful using this script :(
# Also not done
function removeUser
{
    #$TheNewGroup = $OpenWeb.SiteGroups | Where-Object {$_.Name -match $currentGroup}
    #$TheNewGroup.AddUser("NTAMR\" + $prop.samaccountname,$themail,$prop.displayname,"")
    #$TheNewGroup.Remove($LoginToDel)
}

# Now onto the real stuff
Write-host "Searching for Groups" -foregroundcolor Green

# Clear out the existing text file so we have a clean slate
$file = New-Item -type file "C:\location\to\my\folder\allGroups.txt" -Force

# Execute the Group Dump Script
C:\location\to\my\folder\test.ps1 | Out-File -filepath "C:\location\to\my\folder\allGroups.txt" -append

# Clean up the list by removing duplicates and sorting everything
$TextFile = $TextFile = "C:\Powershell\allGroups.txt" 
$NewTextFile = "C:\Powershell\allGroups - Sorted.txt"
GC $TextFile | Sort | GU > $NewTextFile

# Use LDAP to connect to Active Directory
#region
$Dom = 'LDAP://OU=External Accounts,OU=Users,OU=The Office,DC=mydomain,DC=com'
$Root = New-Object DirectoryServices.DirectoryEntry $Dom 
#endregion

# Create a selector and start searching from the Root of AD
#region
$selector = New-Object DirectoryServices.DirectorySearcher
$selector.SearchRoot = $root 
#endregion

# Integer to compare file length
$c=0

# Get the Group text file's length and write to scree and variable
$fileLength = [System.IO.File]::ReadAllText($NewTextFile).Split("`n").Count
Write-Host "Found " $fileLength "Groups in Active Directory" -foregroundcolor Magenta

# Integer for thumbing through 'memberOf' in active directory
$d = 0

# Integer for the amount of of users found
$f = 0

# Start a while loop where we read through the entire groups text file
while ($c -le $fileLength)
{
    # Increment the line number for the next pass through
    $c++

    # Grab the first line of text from the groups file (Really the 0th line) and then tell the user
    $currentGroup = (Get-Content $NewTextFile)[$c]

    # Create the group
    CreateGroup
    #Write-Host "Created Group: " $currentGroup -foregroundcolor Red

    #
    Write-host $c "/" $fileLength "`t" $currentGroup -foregroundcolor Red

    # Query Active directory and force some commands
    $adobj= $selector.findall() | where {$_.properties.objectcategory -match "CN=Person"} 
    foreach ($person in $adobj)
    { 
        # Variable for the different properties to reduce fatigue
        $prop=$person.properties

        # The Department
        $department = $prop.department

        # Sir Name
        $sn = $prop.sn

        # Given Name
        $gn = $prop.givenname

        $un = $prop.samaccountname

        # Assign the really long memberof to a variable
        $memberof = $person.properties["memberof"]

        # Length of memberof
        $memberofcount = $test.Count


        # Loop for each group the member is in
        while ($d -le $memberof.Count)
        {
            $blah = ForEach-Object{`
                $memberof[$d]`
                -replace "CN=OLDLEGACYGROUP",""`
                -replace "CN=",""`
                -replace ",OU=Sales",""`
                -replace ",OU=Some Groups",""`
                -replace ",OU=Groups","" `
                -replace ",OU=The Office","" `
                -replace ",DC=mydomain","" `
                -replace ",DC=com","" `
            }
            # Incriment the d
            $d++

            # Is that user in the group?
            if ($blah -eq $currentGroup)
            {
                # Hey look we found somebody in that group :)
                Write-host "`t`t`t" $un -foregroundcolor Magenta
                addUser
                $f++
            }
            #elseif ($blah -ne $currentGroup)
            #{
            #   removeUser
            #}

            else
            {
                # Oh noes...nobody is in that group...that is strange
            }
        }


        # Are we at the end of what the user has
        if ($d -ge $memberofs.Count)
        {
            # Looks like we are :)
            $d=0
        }
    }

    # Display amount of users found
    #Write-Host "`t`t`t" $f " user(s) found"
    $f = 0
}

# Stop Watch
$sw.Stop()

# Write the compact output to the screen
write-host "Updated in Time: ", $sw.Elapsed.ToString()


#This space is saved for future development