I am looking for some powershell code that can add a user from one domain to another domain group. I can't seem to find the magic code that will work that uses System.DirectoryServices.
###############
# Query user
################
# Variables
$path="GC://ldap-server.company.com"
# To limit the information returned add properties. Use an empty string to
pull everything
$property="objectcategory,distinguishedname,cn,mailnickname,samaccountname"
$searchFilter="(&(objectClass=User)(samaccountname=joker))"
$rootEntry = New-Object System.DirectoryServices.DirectoryEntry $path
$search= New-Object System.DirectoryServices.DirectorySearcher $rootEntry;
if ($properties) {
foreach ($property in [regex]::split($properties, ", ?")) {
[void]$search.PropertiesToLoad.Add($property);
}
}
$search.Filter = $searchFilter;
$searchResults = $search.FindOne();
$user = $searchResults.GetDirectoryEntry()
$user_dn = $searchResults.GetDirectoryEntry().distinguishedName;
# to find the first or only result, use $searchResults = $search.FindOne();
################
#Query group
################
# Same as Query user, just change
$property="";
$searchFilter="(&(objectClass=Group)(samaccountname=mygroup))";
$search.Filter = $searchFilter;
$searchResults = $search.FindOne();
################
#Add user to group
################
# From your group query
$group_dn = $searchResults.GetDirectoryEntry().distinguishedName
I tried this, but it did not seem to add the user and is ADSI:
$Group = [ADSI]"LDAP://"+$group_dn
$User = [ADSI]"LDAP://"+$user_dn
If ($Group.IsMember($User.ADsPath) -eq $False)
{
$Group.Add($User.ADsPath)
}
I was unfortunate enough to have to do this the hard way once (a domain migration where the source domain was still on Windows Server 2008). What you need to do is add the user or group from the remote domain as a foreign security principal:
...
$group_dn = $searchResults.GetDirectoryEntry().distinguishedName
$fsp = New-Object Security.Principal.NTAccount('DOM1', 'username')
$sid = $fsp.Translate([Security.Principal.SecurityIdentifier]).Value
$group = New-Object DirectoryServices.DirectoryEntry("LDAP://$group_dn")
[void]$group.Member.Add("<SID=$sid>")
$group.CommitChanges()
$group.Close()
If possible you should use the ActiveDirectory module (requires at least Windows Server 2008 R2 and access to the AD Web Services).
Related
a few weeks ago I started setting up my MDT(Microsoft Deployment Toolkit) custom Image. Nearly everything works fine so far except my recent Powershell script which is meant for adding a computer to a specific security group without RSAT Tools. I tested it on a newly installed OS but I keep on getting the Exception as in the Powershell Exception link shown below. I'm not really into Powershell programming and I tested several scripts to get it to work and I ended up with this one but I think I didn't fully get the hang of it.
Any help/advice or alternative is highly appreciated :).
My Powershell Code:
<#
PowerShell to join computer object to Active Directory Group without AD module being imported
This finds the computer object anywhere in AD and adds it to a security group in a known location
#>
#Get computer name
$ComputerName = gc env:computername
#Check to see if computer is already a member of the group
$isMember = new-object DirectoryServices.DirectorySearcher([ADSI]"NameofMYSecurityGroup")
$ismember.filter = “(&(objectClass=computer)(sAMAccountName= $Computername$)(memberof=CN=Computers,DC=MY_DOMAIN,DC=LOCAL))”
$isMemberResult = $isMember.FindOne()
#If the computer is already a member of the group, just exit.
If ($isMemberResult) {exit}
else
#If the computer is NOT a member of the group, add it.
{
$searcher = new-object DirectoryServices.DirectorySearcher([ADSI]"NameofMYSecurityGroup")
$searcher.filter = “(&(objectClass=computer)(sAMAccountName= $Computername$))”
$FoundComputer = $searcher.FindOne()
$P = $FoundComputer | select path
$ComputerPath = $p.path
$GroupPath = "LDAP://CN=Computers,DC=MY_DOMAIN,DC=LOCAL"
$Group = [ADSI]"$GroupPath"
$Group.Add("$ComputerPath")
$Group.SetInfo()
}
it's german by the way but it basically says:
Exception calling "Add" with 1 Arguments: "Unknown Name. (Exception From HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME))
AT F:\"SourcePath"
+ $Group.Add("$ComputerPath")
+CategoryInfo :NotSpecified: (:) [], MethodInvocationException
+FullyQuallifiedErrord :CatchFromBaseAdapterMethodInvoke
Exception Link:
Powershell Exception
Untested, but this may help you in the right direction:
$ComputerName = $env:COMPUTERNAME
$GroupDN = 'CN=Computers,DC=MY_DOMAIN,DC=LOCAL'
# initialize the DirectorySearcher
$root = New-Object System.DirectoryServices.DirectoryEntry("LDAP://RootDSE")
$searcher = New-Object System.DirectoryServices.DirectorySearcher($root.defaultNamingContext)
$searcher.SearchScope = 'SubTree'
# Check to see if computer is already a member of the group
$searcher.Filter = "(&(objectCategory=Computer)(objectClass=User)(samaccountname=$ComputerName$)(memberof=$GroupDN))"
$isMember = $searcher.FindOne()
# If the computer is already a member of the group, just exit.
if ($isMember) { exit }
# get the computer object
$searcher.Filter = "(&(objectCategory=Computer)(objectClass=User)(samaccountname=$ComputerName$))"
$ComputerDN = $searcher.FindOne().Properties['distinguishedname']
$ComputerObject = [ADSI]"LDAP://$ComputerDN"
# get the group object
$GroupObject = [ADSI]"LDAP://$GroupDN"
# add the computer to the group
$GroupObject.Add($ComputerObject.AdsPath)
# no need for this $Group.SetInfo()
The company has an AD structure that I need to search for the groupnames where the user is member.
I do know it should be in the "memberof" attribute for the users, let's just say that is not always correct.
I tried the below code to find the username (or objectname) within the "members" attribute for all of the groups within an OU and then bring back the name of the group.
Unfortunately I think I am missing something.
Reverse search (IE: listing the members of a group) is working, but in my case I do not know the name of the groups. Also I need all of the groups, not just a single.
uname ="*anyoldusername*"
$Searcher = [ADSISearcher]"(member=$uname)"
$Searcher.SearchRoot = [ADSI] "LDAP://mydomainsearchroot"
$Searcher.PageSize = 10000
$result = $Searcher.FindAll().Properties.cn
echo $result
This should do it:
$UserName ="TestUser"
$Searcher = [ADSISearcher]""
$Searcher.SearchRoot = [ADSI]"LDAP://mydomainsearchroot"
$Searcher.Filter = "Name=$UserName"
$UserDN = $Searcher.FindOne().properties.distinguishedname
$Searcher.Filter = "(member:1.2.840.113556.1.4.1941:=$UserDN)"
$Searcher.PageSize = 10000
$result = $Searcher.FindAll().Properties.cn
$result
The first search is to find the DN of the user, since that's required for the filter in the next search. To read more about the "1.2.840.113556.1.4.1941" filter see this documentation.
Oh, and echo is an alias for Write-Output in Powershell, better to use that directly or even omit it entirely since a string or variable on it's own will default to Write-Output anyway as you can see when $result is run at the end.
Trying to figure out, how to map a network share based on group membership of Novell eDir.
I found a smart script in Technet for ActiveDirectory via ADSISEARCHER which is working pretty well in AD :)
# extract group names and removes unnecessary characters
$memberOf = ([ADSISEARCHER]"samaccountname=$($env:USERNAME)").Findone().$does.memberof -replace '^CN=([^,]+).+$','$1'
# check if user is member of group A
if($memberOf -contains "GroupA") {
# map network-drive
(New-Object -ComObject WScript.Network).MapNetworkDrive('X:','\\filer\sharename')
}
Is there any chance to use something similar for NDS?
As far as I researched I have to use LDAP to connect to NDS and list all groups of a user object, but haven't much luck yet.
Thx
I found a useful script out there which I just have to edit a littlebit...
URL to Script:
http://activedirectoryfaq.com/2014/01/searching-novell-nds-edirectory-with-powershell/
My final script in case somebody needs this crap:
<#
.SYNOPSIS
Mapping a network share based on a specific group membership in NDS
.DESCRIPTION
The script is mapping a network drive, based on a NDS group membership.
The first match wins!
#>
# --------<SET CORRESPONDING VALUES HERE >--------
# Hostname of eDir Server (e.g.: NDSSRV01):
$LDAPServer = "hostname"
# Name of BaseDN (e.g.: o=MyCompany):
$dn = "o=basedn"
# ------------------------------------------------
# set username of current logged on user
$filter = "(uid=$env:USERNAME)"
# Creating necessary objects
[reflection.assembly]::LoadWithPartialName("system.directoryservices.protocols") | out-null
$ldapIdentifier = new-object directoryservices.protocols.ldapdirectoryidentifier($LDAPServer)
$ldapConnection = new-object directoryservices.protocols.ldapconnection($ldapIdentifier,$null,0)
# Attributes to search for:
# To search for multiple use comma separated list (eg: "groupmembership","cn","emailAddress")
[string[]]$attr = "groupmembership"
# Establishing LDAP connection
$scope = $ADS_SCOPE_SUBTREE
$searchRequest = new-object directoryservices.protocols.searchrequest($dn,$filter,$ADS_SCOPE_SUBTREE,$attr)
$searchRequest.typesonly = $false
$searchRequest.sizelimit = 10
$result = [directoryservices.protocols.searchresponse]$ldapConnection.sendrequest($searchRequest)
$entry = $result.entries
# extract group names and removes unnecessary characters
$membership = $entry[0].Attributes["groupmembership"].getValues([string]) -replace '^CN=([^,]+).+$','$1'
# check if user is member of group A
if($membership -contains "GroupA") {
# map network-drive
(New-Object -ComObject WScript.Network).MapNetworkDrive('X:','\\filer\sharegroupa')
}
# check if user is member of group B
elseif($membership -contains "GroupB") {
# map network-drive
(New-Object -ComObject WScript.Network).MapNetworkDrive('X:','\\filer\sharegroupb')
}
# elseif() ... and so on
# if nothing matches, then:
else {
Write-Host 'current user is not a member of a specified group'
}
I'm trying to make a script to help automate this process a bit but am fairly new to using PowerShell with SharePoint and don't really know the route to take.
I have a list of 40 items and I need to make a library for each one. Each library then needs to have unique permissions with 3 default groups(Owners, Members, Visitors). The groups should be named the same as the List.Title + Owners/Members/Visitors.
So far I create a site group as follows:
# Owner Group
$web.SiteGroups.Add(“$web Owners”, $web.Site.Owner, $web.Site.Owner, “Use this group to grant people full control permissions to the $web site”)
$ownerGroup = $web.SiteGroups["$web Owners"]
$ownerGroup.AllowMembersEditMembership = $true
$ownerGroup.Update()
The naming of my groups needs to be the list title and not the web name as I have above.
I create a new library like this:
PS > $spWeb = Get-SPWeb -Identity http://SPServer
PS > $listTemplate = [Microsoft.SharePoint.SPListTemplateType]::DocumentLibrary
PS > $spWeb.Lists.Add("My Documents","My Doc Library",$listTemplate)
Clearly this is not automated at all and no faster than just using the GUI to make each new library and adding in the site groups. Can anyone help get me started on a script that would iterate through a list of names create a library and create 3 groups on the site for each new library?
Thanks!!
This should get you on the right track I believe.
Add-PSSnapin "Microsoft.SharePoint.PowerShell"
$Lists = #("My Documents", "My Docs", "Testing")
$Groups = #("Owners", "Members", "Visitors")
$listTemplate = [Microsoft.SharePoint.SPListTemplateType]::DocumentLibrary
$Web = Get-SPWeb "Your_URL"
$Lists | ForEach-Object {
$ListName = $_
$Description = "$_ Description"
$Web.Lists.Add($ListName, $Description, $listTemplate)
$Groups | % {
$GroupName = "$ListName $_"
$Web.SiteGroups.Add($GroupName, $Web.Site.Owner, $Web.Site.Owner, "Group $GroupName created by automatic process")
$group = $Web.SiteGroups["$GroupName"]
if ( !$GroupName -contains "Visitors")
{
$group.AllowMembersEditMembership = $true
} else
{
$group.AllowMembersEditMembership = $false
}
$group.Update()
}
}
I am logged in on domain Y and the AD with the User I wish to move is located in domain X (windows 2003 server without ADAM)
How would one move user X from an OU to another OU within the same domain through the System.DirectoryServices Namespaces method?
This is how far I've gotten:
$user = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($context, $idtype, $sam)
Doesn't state here: UserPrincipal
I haven't had to do it without either the QAD cmdlets or the ADAM cmdlets for some time, so this is untested and from memory, but I think something like:
$root = [adsi]''
$searcher = New-Object System.DirectoryServices.DirectorySearcher($root)
$searcher.Filter = "(&(ObjectClass=User)(Name=SomeUser))"
$userObject = $searcher.FindOne()
$path = $userObject.Properties.ADSPath
$targetOU = [adsi]("LDAP://OU=Target,DC=SomeDomain,DC=com")
$ADUser = [adsi]($path)
$ADUser.PSBase.moveto($targetOU)
Here is an other solution :
# MoveObject
$OuDest=[ADSI] "LDAP://mach:389/ou=Commerciaux,dc=societe,dc=fr"
$objUODest.MoveHere("LDAP://cn=Mickey,ou=Ventes,dc=societe,dc=fr", “cn=Mickey")
And
# Rename
$Ou=[adsi] "LDAP://mach:389/ou=Ventes,dc=societe,dc=fr"
$Ou.MoveHere("LDAP://cn=PetitMickey,ou=Ventes,dc=societe,dc=fr", "cn=PetitMickeyBis")
If you need to authentify :
$OuDest = New-Object System.DirectoryServices.DirectoryEntry ("LDAP://FQDN name or #IP",$User,$password)