Hi all, I’m trying to write a script for PowerShell, the script should read from a .csv sheet and update Active Directory if there are any changes. Somehow I don’t get what’s failing, I’m not an expert to be honest.
# Import the CSV file
$csvData = Import-Csv -Path 'C:\mydata.csv'
# Loop through each row in the CSV
foreach ($row in $csvData) {
# Retrieve user information from the CSV
$vorname = $row.'Vorname (bürgerlich)'
$nachname = $row.'Nachname (bürgerlich)'
$abteilung = $row.'Abteilung'
$position = $row.'Position'
$mobil = $row.'Telefonnummer (geschäftlich)'
# Construct the SamAccountName from Vorname and Nachname
$samAccountName = $vorname + ' ' + $nachname
Write-Host "SamAccountName: '$samAccountName'"
# Query Active Directory to retrieve the user object
$user = Get-ADUser -Identity $SamAccountName -Properties Vorname, Nachname, Abteilung, Position, Mobil
# Compare user attributes and update AD if necessary
if ($user) {
if ($user.Vorname -ne $vorname) {
Set-ADUser -Identity $samAccountName -Vorname $vorname -WhatIf
}
if ($user.Nachname -ne $nachname) {
Set-ADUser -Identity $samAccountName -Nachname $nachname -WhatIf
}
if ($user.Abteilung -ne $abteilung) {
Set-ADUser -Identity $samAccountName -Abteilung $abteilung -WhatIf
}
if ($user.Position -ne $position) {
Set-ADUser -Identity $samAccountName -Position $position -WhatIf
}
if ($user.Mobil -ne $mobil) {
Set-ADUser -Identity $samAccountName -Mobil $mobil -WhatIf
}
}
else {
Write-Host "User with SamAccountName '$samAccountName' not found in Active Directory."
}
}
#Press any key before closing the PowerShell window
Write-Host "Press any key to close this window..."
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
Right now I have the following error:
User with SamAccountName ' ' not found in Active Directory.
Hi, thanks for your reply. The account name is somehow a combination of both name and surname, but on the csv file that nomenclature doesn´t appear at all, only name and surname appear. I can take a look and see if I can export the .csv with a proper username on it.
Ok I changed the script as I found another filed for complete name (which is name and surname) in the .csv export. It looks like this now:
# Import the CSV file
$csvData = Import-Csv -Path 'C:\sheet.csv'
# Loop through each row in the CSV
foreach ($row in $csvData) {
# Retrieve user information from the CSV
$vorname = $row.'Vorname (bürgerlich)'
$nachname = $row.'Nachname (bürgerlich)'
$name = $row.'Name (bevorzugt)'
$abteilung = $row.'Abteilung'
$position = $row.'Position'
$mobil = $row.'Telefonnummer (geschäftlich)'
# Construct the SamAccountName from Vorname and Nachname
$samAccountName = $name
Write-Host "SamAccountName: '$samAccountName'"
# Query Active Directory to retrieve the user object
$user = Get-ADUser -Identity $SamAccountName -Properties Vorname, Nachname, Name, Abteilung, Position, Mobil
# Compare user attributes and update AD if necessary
if ($user) {
if ($user.Vorname -ne $vorname) {
Set-ADUser -Identity $samAccountName -Vorname $vorname -WhatIf
}
if ($user.Nachname -ne $nachname) {
Set-ADUser -Identity $samAccountName -Nachname $nachname -WhatIf
}
if ($user.Nname -ne $name) {
Set-ADUser -Identity $samAccountName -Name $name -WhatIf
}
if ($user.Abteilung -ne $abteilung) {
Set-ADUser -Identity $samAccountName -Abteilung $abteilung -WhatIf
}
if ($user.Position -ne $position) {
Set-ADUser -Identity $samAccountName -Position $position -WhatIf
}
if ($user.Mobil -ne $mobil) {
Set-ADUser -Identity $samAccountName -Mobil $mobil -WhatIf
}
}
else {
Write-Host "User with SamAccountName '$samAccountName' not found in Active Directory."
}
}
#Press any key before closing the PowerShell window
Write-Host "Press any key to close this window..."
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
Now at least read from the file, good, but I see some errors:
SamAccountName: 'John Lennon'
Get-ADUser : Mindestens eine Eigenschaft ist ungültig.
Parametername: Vorname
In C:\script.ps1:20 Zeichen:13
+ $user = Get-ADUser -Identity $SamAccountName -Properties Vorname, ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (John Lennon:ADUser) [Get-ADUser], ArgumentException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.ArgumentException,Microsoft.ActiveDirectory.Management.Comm
ands.GetADUser
User with SamAccountName 'John Lennon' not found in Active Directory.
The sAMAccountName of an Active Directory account is a very specific and across the domain a unique attribute. The same goes for the DistinguishedName. I’d recommend using one of them to be able to clearly identify the desired accounts.
The name attribute can exist multiple times in a domain. It only has to be unique across the OU. Using this attribute can lead to errors that are difficult to identify.
Where do you get the input data from? If you get it from someone else you should insist of getting at least one unique attribute. If you create it yourself you should read the sAMAccountName from the AD.
Check your CSV.
There are several fields in AD related to name.
GivenName (First name)
Surname (Last name)
Name (Surname, GivenName)
Samaccountname (Can vary, but generally is a shortened Username)
Eg.,
GivenName - John
Surname - Doe
Name - Doe, John
Samaccountname - Doej, jdoe (really just depends on your naming convenention)
The first 3 names in this scenario are NOT names you can use to find with get-aduser -identity.
So what Olaf said, ask for samaccountname, or if you’re doing it yourself, pull the samaccountname when populating the CSV.
I think the problem is that the .csv doesn´t have Samaccountname field at all. The .csv is exported from our Human Resources portal and though there are a lot of fields to be selected for the export, Samaccountname is none one of them. I tried to do it via email address as is unique as well, but it doesn´t work.
It may have another name. Do they have “logon name” or “windows user name” or something like this?
It does actually. You just have to use the parameter -Filter instead of -Identity.
Depending on your configuration you could use the UserPrincipalName with the parameter -Identity. In most companies this unique AD attribute is set equal to the email address.
Again … The sAMAccountName is a specific attribute in AD and is usually NOT equal to the email address. In most environments I know of it is set equal to the UserPrincipalName.
But since the email address is usually unique in an AD as well you can use a filter like this:
testing several things right now. Main problem is that the .csv file doesn´t have a SamAccountName field at all, as it comes from a Human Resources portal. I tried your both suggestion and they throw the same errors as before. With the one before, I can´t see errors at least, just that “not found in Active Directory” which is funny because is the email address and it´s on AD 100%.
I thought we already agreed on dropping the use of the sAMAccountName!?
You’re using the wrong filter and your code is quite inefficient. In the worst case you’re calling the cmdlet Set-ADUser 6 times for each single user account you have in your input CSV.
Instead you should use a hashtable and splatting. This way you can assemble the desired attribute depending on the existing values in the AD and call Set-ADUser only once.
Outputting verbose information during the runtime with Write-Host slows your code down as well. Either you should use Write-Verbose wich you only enable on demand. Or you simply collect the unavailable accounts in a list and output this list later on or use it to create a response for the department provided that input data.
Here you can read more about hastables and splatting: