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
Related
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)"}
}
}
How can I enable or disable an AD user account from a csv based on an entry. If the status for both say Active, only one account gets enabled instead of both. Same for the disabled status
CSV file:
Samaccountname,Status
john.doe,Active
jane.doe,Disabled
What I have so far:
Import-CSV -Path c:\folder\adaccounts.csv
ForEach ($User in $Users)
{
IF ($User.Status -contains "Disabled")
{
Get-ADUser -Identity $user.samaccountname | Disable-ADAccount
}
elseif ($User.Status -contains "Active")
{
Get-ADUser -Identity $user.samaccountname | Enable-ADAccount
}
At the top of your script you are importing the CSV but it doesn't look like you have assigned it to a variable for your foreach loop
if you assign it to the $Users variable like below, the rest of the script should then go through your CSV as expected.
$Users = Import-Csv -Path c:\folder\adaccounts.csv
-Contains is an operator to test if something can be found in an array of things, not for testing if a string is equal or not to another string.
I would revise your code like this:
Import-CSV -Path 'c:\folder\adaccounts.csv' | ForEach-Object {
# test if a user with that SamAccountName can be found
$user = Get-ADUser -Filter "SamAccountName -eq '$($_.Samaccountname)'" -ErrorAction SilentlyContinue
if ($user) {
# set Enabled if Status is not 'Disabled'
$user | Set-ADUser -Enabled ($_.Status -ne 'Disabled')
}
else {
Write-Warning "User $($_.Samaccountname) does not exist"
}
}
First:
I am complete new to Powershell-Scripting.
Want to change the attribute "preferredLanguage" from some Users via powershell.
The users are written in txt-file
testUser000
testUser001 and so on
My first try was to become a list with users and some attributes:
$users = ForEach ($user in $(Get-Content C:\Temp\users.txt)) {
Get-AdUser $user -Properties Department, Mail, preferredLanguage
}
$users |
Select-Object SamAccountName,Department,Mail, preferredLanguage |
Export-CSV -Path C:\temp\outputUsers.csv -NoTypeInformation
That worked so far:
"SamAccountName","Department","Mail","preferredLanguage"
"tesUser000","dept1","testUser000#domain.com","DE"
"testUser0001","dept2","testUser001#domain.com",
testUser000 has an entry in preferredLanguage
testUser0001 has no entry
That's ok. When I have completed the users.txt, there are more than 100 users without an entry in 'preferredLanguage'
Now I want to change the preferredLanguage and with some investigation in the Internet I made this:
$users = ForEach ($user in $(Get-Content C:\Temp\users.txt)) {
Get-AdUser $user -Properties Department, Mail, preferredLanguage
}
$users |
Set-AdUser $users -Replace #preferredLanguage="DE" |
Select-Object SamAccountName,Department,Mail, preferredLanguage |
Export-CSV -Path C:\temp\outputUsers.csv -NoTypeInformation
When I understand this script right, then it get from my txt-File every user in it with the given attributes then it changes the attribute 'preferredLanguage' from the users in the txt-file and then it select it again then it will save the output in a csv-file.
Maybe someone can look over the script and would be so kind and give me feedback about it or a better way, because Iam too scary to use this script on the AD-Server.
Just a few things:
Get-AdUser $user means you must be sure the user with that identity exists or an exception will be thrown
the syntax for the -Replace operator should be #{preferredLanguage="DE"}
Set-ADUser does not generate any output unless the -PassThru parameter is used.
if you use ForEach-Object, you can do all this in one loop
Try changing the code with this:
(Get-Content C:\Temp\users.txt) | ForEach-Object {
$account = Get-AdUser -Filter "SamAccountName -eq '$_'" -Properties Department, Mail, preferredLanguage -ErrorAction SilentlyContinue
if ($account) {
$account | Set-AdUser -Replace #{preferredLanguage="DE"} -PassThru |
Select-Object SamAccountName,Department,Mail, preferredLanguage
}
else {
Write-Warning "User '$_' does not exist"
}
} | Export-CSV -Path C:\temp\outputUsers.csv -NoTypeInformation
Hope that helps
Any way to block user account in Office365 by EmployeeID instead of UPN?
This is the script I've tried, but it can only block by UPN:
Import-Csv 'C:\BlockedUsers.csv' | ForEach-Object {
$upn = $_."UserPrincipalName"
Set-MsolUser -UserPrincipalName $upn -BlockCredential $true
}
If your csv file contains a column called EmployeeId, you can use that to get the UserPrincipalName property using the Get-AdUser cmdlet:
Import-Csv 'C:\BlockedUsers.csv' | ForEach-Object {
$user = Get-ADUser -Properties EmployeeID -Filter "EmployeeID -eq $($_.EmployeeID)"
if ($user) {
$upn = $user.UserPrincipleName
Set-MsolUser -UserPrincipalName $upn -BlockCredential $true
}
}
Edit
Judging by your comment, it seems the EmployeeID property is not always unique in your organization.
In that case, the below code should be able to handle that
Import-Csv 'C:\BlockedUsers.csv' | ForEach-Object {
$user = Get-ADUser -Properties EmployeeID -Filter "EmployeeID -eq $($_.EmployeeID)"
if ($user) {
foreach ($usr in $user) {
Write-Host "Blocking user $($usr.Name)"
$upn = $usr.UserPrincipleName
Set-MsolUser -UserPrincipalName $upn -BlockCredential $true
}
}
else {
Write-Host "User with EmployeeID $($_.EmployeeID) not found"
}
}
P.S. If your CSV can contain empty values for the EmployeeID column, change the first line into
Import-Csv 'C:\BlockedUsers.csv' | Where-Object {$_.EmployeeID -match '\S'} | ForEach-Object {
to get rid of empty or whitespace-only values.
Edit
If you are sure your CSV contains a column EmployeeId and you are not mistaking that with AD property EmployeeNumber, then perhaps this might work for you.
It uses Get-ADUser to get a collection of user objects that actually have something in their EmployeeId attribute and refines that by comparing to the ones you have read from the CSV using Where-Object.
Both EmployeeId and EmployeeNUmber are AD properties of type String. You can look that up here
# first read the CSV into an array containing only the values from the 'EmployeeID' column
$blockedUserIds = Import-Csv 'C:\BlockedUsers.csv' | Select-Object -ExpandProperty EmployeeId -Unique
# next get an array of user objects that have something in the EmployeeID attribute and only
# leave the users where the attribute can be matched to a value captured in the CSV array above
# use the '#(..)' syntax to force the result to be an array, even if only one item is found
$usersToBlock = #(Get-ADUser -Properties EmployeeID, Name, UserPrincipalName -Filter "EmployeeID -like '*'" |
Where-Object { $blockedUserIds -contains $_.EmployeeID })
# you can also use the '-LDAPFilter' parameter
# $usersToBlock = #(Get-ADUser -Properties EmployeeID, Name, UserPrincipalName -LDAPFilter "(employeeID=*)" |
# Where-Object { $blockedUserIds -contains $_.EmployeeID })
# you now should have an array of user objects that need to be blocked
if ($usersToBlock.Count) {
Write-Host "Blocking $($usersToBlock.Count) users.." -ForegroundColor Green
$usersToBlock | ForEach-Object {
Write-Host "Blocking user $($_.Name)"
Set-MsolUser -UserPrincipalName $($_.UserPrincipleName) -BlockCredential $true
}
}
else {
Write-Warning "No users found with an EmployeeId property that matches any of the values in BlockedUsers.csv"
}
I need to search through all users in AD, find their attribute "mail" and in this attribute replace #hell.com to #heaven.com
I'm stuck at exporting and importing to csv...
Import-Module ActiveDirectory
get-aduser -Filter {samaccountname -like "gmaleev"} -properties * | Select-Object SamAccountName,mail | export-csv -NoTypeInformation d:\1.csv
$impfile = "d:\1.csv"
Import-CSV $impFile
foreach ($user in $users)
{
$sam = $user.samaccountname
$email = $user.mail
write-host "User $sam has mail $mail"
}
It doesn't work, why?
The current issue is that you are running a cmdlet to import the data but not saving it. Your ForEach cmdlet is not processing any data so you should have blank output except that of Import-CSV which should be outputing to console.
Also it seems redundant to export the data to import it again. I will presume that you have a reason for exporting it.
Import-Module ActiveDirectory
$impfile = "d:\1.csv"
$results = Get-AdUser -Filter {samaccountname -like "gmaleev"} -properties * | Select-Object SamAccountName,mail
$results | export-csv -NoTypeInformation d:\1.csv
$results | foreach ($user in $users){
$sam = $user.samaccountname
$email = $user.mail
write-host "User $sam has mail $mail"
}
This should address what you are showing. It will get the same data and save it to the variable $results. Export that data and then piping it to the ForEach to process
Your title suggets that you want to change user attributes. To do that you would need to use Set-Aduser. Depending on what your environment is this might not be the best way to manipulate email attributes.