I am trying to get only AD Objects of type user and then iterate over all them and change AD user object name. So I have done below:
$Users = Get-ADObject -Filter {(ObjectClass -eq "user")} # OR Get-ADObject -Filter 'ObjectClass -eq "user"'
$Users | foreach
{
# Here code to create name based on conditions ($newUserObjectName)
Rename-ADObject -Identity $_ -NewName $newUserObjectName
}
The problem is that Get-ADObject is returning not only users but also computer objects.... I only want user object classes. Also I am not sure If below line of code is correct by setting identity to $_ in order to update the current user in the iteration:
Rename-ADObject -Identity $_ -NewName $newUserObjectName
Why not use Get-ADUser instead of Get-ADObject and just return the DistinguishedName? Obviously, DON'T just run this code :)
$users = (Get-ADUser -Filter *).DistinguishedName #This gets all the users in AD
Foreach($user in $users){
Rename-ADObject -Identity $user -NewName $newUserObjectName
}
The Computer objectClass is derived from the User objectClass. Hence, queries for user class will return both Computers and Users. If you want to filter for Users only, you have to specify ObjectCategory as Person
$Users = Get-ADObject -Filter {(Objectclass -eq "user") -and (objectCategory -eq "Person")}
Use that or you can use the goodole Get-ADuser
Use Get-ADUser and Set-ADUser:
$Users = Get-ADUser -Filter *
$Users | foreach {
# Naming code
Set-ADUser -Identity $_.SamAccountName -SamAccountName $newName
}
This replaces all user's identities to $newName.
Note you can replace -SamAccountName with any other property of an ADUser. for example if you want to replace the display name instead, you would use -Name $newName
Related
When somebody leaves my organization, we remove all AD group memberships apart from the PrimaryGroup which is Domain Users. We often process these in batches, so pull the affected usernames from a CSV file.
I have the following code, and while it does the job of deleting all group memberships, I get an error for each user:
The user cannot be removed from a group because the group is currently the user's primary group
Whilst it does the job, how can I "clean up" the process to avoid this message each time? Is there a way to exclude Domain Users from the groups it removes the user from, or should I do this another way?
$users = Import-Csv "c:\temp\leavers.csv"
foreach ($user in $users) {
Get-ADPrincipalGroupMembership -identity $user.username | foreach {Remove-ADGroupMember $_ -Members $user.username -Confirm:$false}
}
You can use Where-Object for filtering those groups that are not in an array of groups to exclude. In case you only want to filter for 1 specific group, you would use -NE instead of -NotIn in below example.
$groupToExclude = 'Domain Users', 'someOtherGroup'
$users = Import-Csv "c:\temp\leavers.csv"
foreach ($user in $users) {
try {
Get-ADPrincipalGroupMembership -Identity $user.username |
Where-Object Name -NotIn $groupToExclude |
Remove-ADGroupMember -Members $user.username -Confirm:$false
}
catch {
Write-Warning $_.Exception.Message
}
}
If you get the ADUser object before the ADGroup memberships, you can get the PrimaryGroup of the user and ensure that the list of groups to remove from are not its PrimaryGroup:
$users = Import-Csv "c:\temp\leavers.csv"
foreach ($user in $users) {
$primaryGroup = ( Get-ADUser $user.UserName -Properties PrimaryGroup ).PrimaryGroup
Get-ADPrincipalGroupMembership -Identity $user.UserName | Where-Object {
$_ -ne $primaryGroup
} | ForEach-Object {
Remove-ADGroupMember $_ -Members $user.username -Confirm:$False -WhatIf
}
}
Since this has the potential to be a very destructive command, I have included a safeguard in the example above. Remove the -WhatIf parameter from Remove-ADGroupMember to actually perform the removal.
I'd propose a slightly different approach - just drop Get-ADPrincipalGroupMembership altogether. For example:
$users = Import-Csv -Path c:\temp\leavers.csv
foreach ($user in $users) {
# Assuming DN is not in the csv...
$distinguishedName = (Get-ADUser -Identity $user.UserName).DistinguishedName
Get-ADGroup -LdapFilter "(member=$distinguishedName)"
# Alternatively, just pipe memberOf property to Get-ADGroup...
(Get-ADUser -Identity $user.UserName -Property MemberOf).MemberOf |
Get-ADGroup
}
That way you don't have to filter out something you insisted on getting (by using above mentioned cmdlet).
I want to replace AD attribute "userPrincipalName" value according to CSV file header value
here is what csv file(group.csv) contains
sAMAccountName
--------------
test.user1
test.user2
below the script
$data = Import-Csv -Path .\group.csv -Header 'sAMAccountName'
foreach($user in $data){
Get-ADUser -Filter {sAMAccountName -eq "$($user.sAMAccountName)"} | Set-ADUser -Replace #{userPrincipalName="$($user.sAMAccountName)#RES.GROUP"}
}
here I want to replace AD attribute "userPrincipalName" with the value of sAMAccountName from csv file, something like sAMAccountName#RES.GROUP
this script does not work, can anyone please correct it?
Ok, since your comment shows the CSV file indeed does not have a header, I would suggest changing the code to:
$data = Import-Csv -Path .\group.csv -Header 'sAMAccountName'
foreach($user in $data) {
$adUser = Get-ADUser -Filter "SamAccountName -eq '$($user.sAMAccountName)'" -ErrorAction SilentlyContinue
if ($adUser) {
$newUPN = '{0}#res.group' -f $user.sAMAccountName
$adUser | Set-ADUser -UserPrincipalName $newUPN
}
else {
Write-Warning "No user with SamAccountName '$($user.sAMAccountName)' could be found.."
}
}
This way, any mistakes in the file will not make the code quit when a user with that samaccountname cannot be found. Instead, in that case you will see a warning about it and the code will continue with the rest of the data.
It might be worth mentioning that you can use parameter -Server on both the Get-ADUser and Set-ADUser cmdlets to make sure you use the same domain server (DC) to set the new UPN. Otherwise, you can set it on one DC, but are looking at another which doesn't show the change immediately because the servers need time to synchronize..
Now that we have cleared up the question about the CSV and to answer your comment:
If you want to do this as a two-script solution, here's how you can do that
step 1: get all users in the search OU that have a UserPrincipalName ending in '*#test.group'
$searchBase = "OU=Teams,OU=Prod,DC=RES,DC=TEST,DC=GROUP"
Get-ADUser -SearchBase $searchBase -Filter "UserPrincipalName -like '*#test.group'" |
# select ony the SamAccountName and write to CSV with column header
Select-Object SamAccountName | Export-Csv -Path .\group.csv -NoTypeInformation
step 2: read the csv created above and
$searchBase = "OU=Teams,OU=Prod,DC=RES,DC=TEST,DC=GROUP"
$data = Import-Csv -Path .\group.csv
$result = foreach($user in $data) {
$adUser = Get-ADUser -SearchBase $searchBase -Filter "SamAccountName -eq '$($user.sAMAccountName)'" -ErrorAction SilentlyContinue
# if we have a user object AND its UserPrincipalName is not as desired go ahead and change that
if ($adUser) {
if ($adUser.UserPrincipalName -notlike '*#res.test.group') {
$newUPN = '{0}#res.test.group' -f $user.sAMAccountName
$adUser | Set-ADUser -UserPrincipalName $newUPN
# output this user object to be collected in variable $result
$adUser
}
else {
Write-Host "User $($user.sAMAccountName) already has UPN '$($adUser.UserPrincipalName)'"
}
}
else {
Write-Warning "User with SamAccountName '$($user.sAMAccountName)' not found.."
}
}
# now that we have changed some users, create a second csv with all users that were actually changed
if (#($result).Count) {
$result | Select-Object SamAccountName | Export-Csv -Path .\Updatedgroup.csv -NoTypeInformation
}
else {
Write-Host 'No users needed updating'
}
It seems a waste writing only the users SamAccountName property to the csv files.. Especially since Get-ADUser by default already returns these properties: DistinguishedName, Enabled, GivenName, Name, ObjectClass, ObjectGUID, SamAccountName, SID, Surname, UserPrincipalName
I have a csv with the following fields:
User | AD_Manager_ID | Dyn_Manager_ID
abc#mydomain.com | 1234 | 1455
The Dyn_Manager_ID field is the employeeID of another user.
99% of the time it corresponds to an actual user, but sometimes it corresponds to a contact
I can get the contact like this:
Get-ADObject -Filter "employeeID -eq '1455'"
but when I try to Set-ADUser -Manager with that object, it returns a 'Cannot find an object with idenity" error.
Here is the code for regular users (non contacts):
$csvimport = import-csv -Path C:\Users\ME\Desktop\AccountChangesCSV.csv
foreach ($User in $csvimport)
{
Get-aduser -filter "employeeID -eq '$($user.DYN_Mgr_ID)'" | select-object samaccountname -
OutVariable ManagersName
Get-ADUser -Filter "employeeID -eq '$($user.AD_ID)'" | set-aduser -Manager
$ManagersName.samaccountname
}
If someone's manager could be either another user or a contact, then do not use Get-ADUser to find the manager object, but Get-ADObject instead.
If this was a contact, there is no SamAccountName property, but instead, you can use the DistinguishedName or the ObjectGUID
Try
$csvimport = Import-Csv -Path 'C:\Users\ME\Desktop\AccountChangesCSV.csv'
foreach ($user in $csvimport) {
$manager = Get-ADObject -Filter "employeeID -eq '$($user.DYN_Mgr_ID)'" -ErrorAction SilentlyContinue
if ($manager) {
# now update the users Manager property with the DistinguishedName of the manager object
Get-ADUser -Filter "employeeID -eq '$($user.AD_ID)'" |
Set-ADUser -Manager $manager.DistinguishedName # or ObjectGUID instead of DistinguishedName
}
}
This works for both AD user objects and contacts alike
I think this post has the answer: updating an ADUser's Manager with a contact card
This is the code that finally worked for me:
$csvimport = Import-Csv -Path 'C:\Users\ME\Desktop\AccountChangesCSV.csv'
foreach ($user in $csvimport) {
$manager = Get-ADObject -Filter "employeeID -eq '$($user.DYN_Mgr_ID)'" -
ErrorAction SilentlyContinue
if ($manager) {
# now update the users Manager property with the DistinguishedName of the
manager object
$aduser = Get-ADUser -Filter "employeeID -eq '$($user.AD_ID)'"
Set-AdUser -Identity $aduser.SamAccountName -replace
#{manager="$($manager.distinguishedname)"}
}
}
I have the following script - it works except for the departmentNumber. Any ideas?
# Import AD Module
Import-Module ActiveDirectory
# Import CSV into variable $users
$users = Import-Csv -Path C:\users.csv
# Loop through CSV file and update users if they exist
foreach ($user in $users) {
Get-ADUser -Filter "SamAccountName -eq '$($user.samaccountname)'" - Properties * |
Set-ADUser -EmailAddress $($user.EmailAddress) -Title $($user.Title) -Office $($user.Office) -OfficePhone $($user.OfficePhone) -departmentNumber $($user.departmentNumber) }
EDIT:
I tried the following using the "-Add" operator:
Import-Module ActiveDirectory
$users = Import-Csv -Path C:\users.csv
foreach ($user in $users) {
Get-ADUser -Filter "SamAccountName -eq '$($user.samaccountname)'" -Properties * |
Set-ADUser -Add #{departmentNumber = "$($user.departmentNumber)"}
}
And the following, using the "-Replace" operator:
Import-Module ActiveDirectory
$users = Import-Csv -Path C:\users.csv
foreach ($user in $users) {
Get-ADUser -Filter "SamAccountName -eq '$($user.samaccountname)'" -Properties * |
Set-ADUser -Replace #{departmentNumber = "$($user.departmentNumber)"}
}
Still no luck - do I have the syntax messed up?
I'm taking a quick look at the help for Set-ADUser: https://technet.microsoft.com/en-us/library/ee617215.aspx
I see a parameter for -Department, but not one for -DepartmentNumber
Will it work within your company's structure to just use -Department ?
For a custom attribute, you should be able to use the -Add parameter
-Add #{otherTelephone='555-222-1111', '555-222-3333'; otherMobile='555-222-9999' }
In order to use -Add or -Replace, you'll need to use a hashtable as your input instead of a string.
Here's a quick set of commands I used to convert a string into a single item hashtable:
$DeptNo = 'test'
$hash = #{}
$hash.Add('DepartmentNumber',$DeptNo)
$hash
Output from $hash:
Name Value
---- -----
DepartmentNumber test
I think you'll then be able to use -Add $hash to get it to do what you want.
Here is my code that got it working:
Set-ADUser -Identity $samName -Add #{'departmentNumber'="$UserDept"}
It is important to note you can only use -Add if nothing is there
otherwise use -Replace
$UserDept was a number but the quotes make it a string
and the attribute must have single quotes around it.
I'm trying to update the email address listed in AD for all the users in a particular OU. This is the powershell script I'm using, but it's not working properly
Import-Module ActiveDirectory
Get-ADUser -Filter * -SearchBase "OU=OtherOU,OU=SomeOu,DC=Domain,DC=local" | Set-ADUser -email $_.samaccountname#domain.com
I think it's because $_.samaccountname isn't returning anything when I try to do Set-ADUser.
Can anyone point me in the right direction for fixing this? Thanks!
Create a csv file with SamAccountName & email address
"SamAccountName","EmailAddress"
"john","john#xyz.com"
step 1: import to a variable
$users = Import-Csv .\email.csv
step 2: Call the variable
foreach ($user in $users) {
Set-ADUser -Identity $user.SamAccountName -EmailAddress $user.EmailAddress
}
In the current context $_ is null. You need to use Foreach-Object in order for $_ to be available.
Get-ADUser -Filter * ... | Foreach-Object{
Set-ADUser -Identity $_ -Email "$($_.samaccountname)#domain.com"
}
I suspect you'll need to use a subexpression for that:
"$($_.samaccountname)#domain.com"
Assuming username is domain\user1 or user1#domain.com
$user = "user1"
Set-ADUser $user -emailaddress "firtname.lastname#xyz.com"
Get-ADUser -Identity $user -Properties emailaddress
Get-ADUser -Filter * -SearchScope Subtree -SearchBase "OU=OUName,DC=domain,DC=com" |
Foreach-Object { Set-ADUser -Identity $_ -Email "$($_.samaccountname)#domain.com" }
This is from:
https://social.technet.microsoft.com/wiki/contents/articles/33311.powershell-update-mail-and-mailnickname-for-all-users-in-ou.aspx