Giving myself a fun little project today I thought, but now it's grown into an issue and the solution eludes me. I have a massive .Csv file with all our employees sAMAccountName and telephoneNumber attributes. I would like to update all of the telephone numbers in our active directory. I was poking around some of my old scripts, taking parts and pieces that would work for this my first iteration got me too here.
$Users = Import-Csv -Path C:\Results\EmployeeExtsTest.csv
ForEach ($User in $Users) {
$User = $User.sAMAccountName
$telephoneNumber = $User.telephoneNumber
Get-ADUser -Identity $User | Set-ADUser -telephoneNumber $telephoneNumber
}
That's when I discovered that PowerShell doesn't have a -telephoneNumber attribute. So I did some digging and then arrived here.
$Users = Import-Csv -Path C:\Results\EmployeeExtsTest.csv
ForEach ($User in $Users) {
$User = $User.sAMAccountName
$telephoneNumber = $User.telephoneNumber
Get-ADUser -Identity $User | Set-ADUser -Add #{telephoneNumber=$telephoneNumber}
}
I tested it out with my user at first and I keep getting the following.
Set-ADUser : Cannot validate argument on parameter 'Add'. The argument is null or an element of the argument collection contains a null value.
At line:6 char:50
+ ... -Identity $User | Set-ADUser -Add #{telephoneNumber=$telephoneNumber}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Set-ADUser], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.SetADUser
I know that it's reading my .Csv correctly because I can call it just fine. It outputs the following.
sAMAccountName telephoneNumber
-------------- ---------------
zgroven 1121
I know this solution "should" be easy but it's completely escaping me!
To expand on #PaulWain answer. Active Directory Users and Computers displays Telephone Number, the AD Attribute is telephoneNumber, but Set-ADUser oddly uses the parameter OfficePhone for setting it. Another quirk due to OfficePhone being a "special" field, when clearing with Set-ADUser you actually have to use telephoneNumber as the field. e.g.:
$Users = Import-Csv -Path C:\Results\EmployeeExtsTest.csv
ForEach ($UserEntry in $Users) {
$User = Get-ADUser -Filter "samAccountName -like '$($UserEntry.sAMAccountName)'" -Properties *
#Check to see if the user exists
if($User)
{
#Check to see if the Office Phone number has been cleared in CSV
if ([string]::IsNullOrEmpty($UserEntry.telephoneNumber))
{
#Clear the user's OfficePhone (telephoneNumber) in Active Directory
Set-ADUser -Identity $User -Clear telephoneNumber
}
else
{
#Update the user in Active Directory
Set-ADUser -Identity $User -OfficePhone $UserEntry.telephoneNumber
}
}
else
{
Write-Host "User $($UserEntry.sAMAccountName) does not exist in Active Directory"
}
}
One thing I add to my script is to use the -Filter parameter on my Get-ADUser that way I can verify the user exists without Get-ADUser throwing an error. See my answer for more information "Determine If Users Are In Active Directory With PowerShell":
The other method is to modify all of the properties all at once, and then use the Set-ADUser -Instance parameter to set them all at once (note: OfficePhone/telephoneNumber are special and have to be cleared manually like the above code, other fields can be manually cleared/set blank):
$Users = Import-Csv -Path C:\Results\EmployeeExtsTest.csv
ForEach ($UserEntry in $Users) {
$User = Get-ADUser -Filter "samAccountName -like '$($UserEntry.sAMAccountName)'" -Properties *
#Check to see if the user exists
if($User)
{
#Check to see if the Office Phone number has been cleared in CSV
if ([string]::IsNullOrEmpty($UserEntry.telephoneNumber))
{
#Clear the user's OfficePhone (telephoneNumber) in Active Directory
Set-ADUser -Identity $User -Clear telephoneNumber
}
else
{
#Modify Local instance of the user's properties
$User.OfficePhone = $UserEntry.telephoneNumber
}
#Modify Local instance of other user's properties
$User.GivenName = $UserEntry.GivenName
$User.Surname = $UserEntry.Surname
#..... etc.....
#Update the user in Active Directory
Set-ADUser -Instance $User
}
else
{
Write-Host "User $($UserEntry.sAMAccountName) does not exist in Active Directory"
}
}
I believe that you are being misled by what is displayed and what the actual name of the property is, due to behind-the-scenes aliasing.
Try using this instead:
set-aduser $user -OfficePhone $telephoneNumber
The final script that got me through this is here
$Users = Import-Csv -Path C:\Results\EmployeeExts.csv
ForEach ($U in $Users) {
$User = $U.sAMAccountName
$telephoneNumber = $U.telephoneNumber
Set-ADUser $User -OfficePhone $telephoneNumber
}
Because I work for a school district I will be adding on more to this in the future to look for employees that are missing. As it stands now this script just updated nearly 1000 AD accounts perfectly (aside from the missing employees that have left). I want to thank all of you for helping in giving me pieces of this answer. You've made me better at my job.
Special thanks to #PaulWain and #HAL9256
Related
I'm trying to import manager attribute to active directory for set of users using the following CSV file template
GivenName Surname DisplayName Department Title mail MobilePhone Manager SamAccountName
John Smith John Smith IT IT Manager john#example.com 1234 Mark Ebert JohnS
I used the below script and but it throws out an error.What i'm thinking it is due to manager attribute required to be in distinguished name format and **but i cannot change the csv manager column name as it comes from a different program.**The manager name in the CSV file shows in first name and last name format. What i need is to import the data on it to AD like the way it is.Any alternative methods available for this scenario.Here is the example script i used.
# Import AD Module
Import-Module ActiveDirectory strong text
$users = Import-Csv -Path C:\temp\MergedTo_AD.csv
foreach ($user in $users)
{Get-ADUser -Filter "SamAccountName -eq '$($user.samaccountname)'" | Set-ADUser -GivenName $($User.GivenName) -Surname $($User.Surname) -DisplayName $($User.DisplayName) -title $($User.title) -EmailAddress $($User.EmailAddress) -MobilePhone $($User.MobilePhone) $User -manager $ID }
If your CSV looks like this:
GivenName,Surname,DisplayName,Department,Title,mail,MobilePhone,Manager,SamAccountName
John,Smith,John Smith,IT,IT Manager,john#example.com,1234,Mark Ebert,JohnS
Joe,Bloggs,Joe Bloggs,Marketing,Administrative Assistant,joe#example.com,87954,,JoeB
Then you can see that in the second example the Manager property is empty.
To best deal with columns that could be empty, use Splatting for properties that are present in the CSV, while omitting empty fields:
Something like this:
$users = Import-Csv -Path C:\temp\MergedTo_AD.csv
foreach ($user in $users) {
# first try and find the user object in AD
$adUser = Get-ADUser -Filter "SamAccountName -eq '$($user.SamAccountName)'" -Properties Manager -ErrorAction SilentlyContinue
if ($adUser) {
# we have a valid user. create a splatting Hashtable to use with Set-ADUser
# Leave out the Manager for now, as we first need to make sure we can actually find a DN for this property.
$userProps = #{
# take out any properties you do not want to (re) set
GivenName = $user.GivenName
Surname = $user.Surname
DisplayName = $user.DisplayName
Title = $user.Title
EmailAddress = $user.mail
MobilePhone = $user.MobilePhone
}
# try and get the manager object from the $user.Manager column which may or may not have been set
if (![string]::IsNullOrWhiteSpace($user.Manager)) {
# try and find an AD user with the given DisplayName. You could also try with the `Name` property
$manager = Get-ADUser -Filter "DisplayName -eq '$($user.Manager)'" -ErrorAction SilentlyContinue
if ($manager) {
# add the 'Manager' entry to the Hashtable for properties to set
$userProps['Manager'] = $manager.DistinguishedName
}
else {
Write-Warning "Could not find '$($user.Manager)' in AD.."
}
}
else {
Write-Warning "Manager column for user '$($user.SamAccountName)' is empty.."
}
# here we set the properties to the user according to the CSV file
Write-Host "Updating user properties for '$($user.SamAccountName)'"
$adUser | Set-ADUser #userProps
}
else {
Write-Warning "User '$($user.SamAccountName)' could not be found.."
}
}
I'm not a scripting expert at all.I amended the script as below as per your suggestion.
# Import AD Module
Import-Module ActiveDirectory
$users = Import-Csv -Path C:\temp\MergedTo_AD.csv
{Get-ADUser -Filter "SamAccountName -eq '$($user.samaccountname)'" $FirstName,$LastName = (-split $User.Manager).Trim() $ID = (Get-ADUser -LDAPFilter "(&(GivenName=*$FirstName*)(SurName=*$LastName*))").SamAccountName (Get-ADUser -LDAPFilter "(&(GivenName=*$FirstName*)(SurName=*$LastName*))").SamAccountName| Set-ADUser -GivenName $($User.GivenName) -Surname $($User.Surname) -DisplayName $($User.DisplayName) -title $($User.title) -EmailAddress $($User.EmailAddress) -OfficePhone $($User.OfficePhone) -MobilePhone $($User.MobilePhone) -manager $($User.manager) }
I'm getting below error
Get-ADUser : The search filter cannot be recognized
At C:\Temp\PowershellScript-Users Import.ps1:5 char:128
+ ... im() $ID = (Get-ADUser -LDAPFilter "(&(GivenName=*$FirstName*)(SurNam ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-ADUser], ADException
+ FullyQualifiedErrorId : ActiveDirectoryServer:8254,Microsoft.ActiveDirectory.Management.Commands.GetADUser
I've reviewed the code and the reason it fails is because you cannot add the manager using the variable '$ID' is that it has no reference, nor does it resolve to the managers active directory user account. Your choices are either add the managers Distinguished Name to your csv file or stick it in your code to resolve the managers Distinguished Name.
#Import CSV File to set variable for the user’s logon name of whom manager’s field needs to be filled + delimiter
$users = Import-Csv -Delimiter ";" -Path "C:\temp\MergedTo_AD.csv"
foreach ($user in $users) {
#The Managers AD Sam Account Name
$ManagersaMACCount = "saMACcount"
#The Managers AD Distinguished Name
$ManagerID = (Get-ADUser -identity $ManagersaMACCount).DistinguishedName
#Example of Setting User's Manager Attribute -Example below
#Get-aduser -identity $user | Set-ADUser -Manager $ManagerID
#Using your code to filter AD Sam Accounts Based on column samaccountname in the csv file
Get-ADUser -Filter "SamAccountName -eq '$($user.samaccountname)'" `
#Pipe Set Users GivenName Based on column GivenName
| Set-ADUser -GivenName $($User.GivenName) `
#Set Users Surname Based on column Surname
-Surname $($User.Surname) `
#Set Users Display Name Based on column DisplayName
-DisplayName $($User.DisplayName) `
#Set Users Title Based on column Title
-title $($User.title) `
#Set Users Email Address Based on column EmailAddress
-EmailAddress $($User.EmailAddress) `
#Set Users Mobile Phone Based on column MobilePhone
-MobilePhone $($User.MobilePhone) `
#Set Users Manager Based on the Distinguished Name Attribute In Active Directory
-manager $ManagerID
}
I am looking for assistance in creating/completing a Powershell script that grabs a user's samAccountName from a .csv file, disables that user in a specific domain, e.g. "foo.bar", and then prepends their AD display name with a single character. This is a bulk disable script, and it has to add that single character to the front/beginning of their display name.
What I have so far is:
Import-Module ActiveDirectory
$Server = read-host "Enter Domain to query/domain controller"
Import-Csv "C:\Temp\samAccountNames.csv" | ForEach-Object {
$samAccountName = $_."samAccountName"
Get-ADUser -Server $Server -Identity $samAccountName | Disable-ADAccount
}
Now, what I need to do is to prepend the display name with the '#' character.
(e.g. "Doe, John" becomes "#Doe, John")
You need to check if the user can be found at all first, then update the displayname and disable the account
Import-Module ActiveDirectory
$characterToPrepend = '#' # the character you want to prepend the DisplayName with
$Server = Read-Host "Enter Domain to query/domain controller"
Import-Csv "C:\Temp\samAccountNames.csv" | ForEach-Object {
$ADUser = Get-ADUser -Server $Server -Filter "SamAccountName -eq '$($_.samAccountName)'" -Properties DisplayName -ErrorAction SilentlyContinue
if ($ADUser) {
# test if the user is not already disabled
if (!$ADUser.Enabled) {
Write-Host "User '$($_.samAccountName)' is already disabled"
}
else {
$newDisplayName = $characterToPrepend + $ADUser.DisplayName
# set the new displayname and disable the user
$ADUser | Set-ADUser -DisplayName $newDisplayName -Enabled $false
}
}
else {
Write-Warning "User '$($_.samAccountName)' does not exist"
}
}
I'm using -Filter to get the user rather than the -Identity parameter because the latter will throw an exception when a user with that SamAccountName could not be found
I'm trying to set a new company value for users from a CSV.
I read that you get the error when not setting the server in my Set-AdUser command.
At line:18 char:18
+ ... $query | Set-ADUser -Server tstdc01 -Company "New Company"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (CN=testUser\, H...DC=domain,DC=local:ADUser) [Set-ADUser], ADReferralException
+ FullyQualifiedErrorId : ActiveDirectoryServer:8235,Microsoft.ActiveDirectory.Management.Commands.SetADUser
--------------------------------------------------------------------------------------------------------
Import-Module ActiveDirectory
$users = Import-Csv -Path "pathToCsv.csv" -Encoding UTF8 -Delimiter ";"
$setUsers = #()
$domain = "domain.local:3268"
foreach ($user in $users) {
$samAccountName = $user.samAccountName
$query = Get-ADUser -Filter {Samaccountname -eq $samAccountName} -Server $domain
if ($query) {
$query | Set-ADUser -server tstdc01-Company "New Company"
$setUsers += $query
}
}
As Santiago implied this looks like an issue of cross domain or forest communication. And/or you are passing a user from one domain and attempting to set it in another.
See here, and a link here
An aside, a few pointers; You don't need to filter for samAccountName when you already have the samAccountName, the query can be something like:
$setUsers =
Get-ADUser $samAccountName -Server $domain |
ForEach-Object{
Set-ADUser $_ -Server tstdc01 -Company "New Company" -PassThru
}
Also note: you should avoid += I don't know how big a job this is, but it can degrade performance as it causes the creation of a new array and a copy of the existing array. Repeated many times that can cause big performance issues. There are a number of ways to address that, but the preferred approach is to let PowerShell gather the results for you. So above assign the $setUsers variable to the output of the loop. Add -PassThru to output the object that was set.
Update:
With the point regarding += demonstrated, #SantiagoSquarzon pointed out we don't even need the loop anymore:
$setUsers =
Get-ADUser $samAccountName -Server $domain |
Set-ADUser -Server tstdc01 -Company "New Company" -PassThru
I'm not so good at PowerShell. I have this script which worked before that I've have used to update the manager attribute in Active Directory, however, now after just replacing the file its no longer working
$Users = Import-CSV C:\Documents\Managers.csv
ForEach ($User in $Users) {
$user= Get-ADUser -Filter "displayname -eq '$($Users.EmployeeFullName)'"|select -ExpandProperty samaccountname
$manager=Get-ADUser -Filter "displayname -eq '$($Users.'Line Manager Fullname')'"|select -ExpandProperty DistinguishedName
Set-ADUser -Identity $user -Replace #{manager=$manager}
}
when running the script it returns:
Set-ADUser : Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again.
At line:6 char:22
+ Set-ADUser -Identity $user -Replace #{manager=$manager}
+ ~~~~~
+ CategoryInfo : InvalidData: (:) [Set-ADUser], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.SetADUser
the "EmployeeFullName" and "Line Manager FullName" format in the .csv is set as i.e. joe bloggs, see below CSV file example.
EmployeeFullname Line Manager Fullname
---------------- ---------------------
Kieran Rhodes Tracey Barley
Lewis Pontin Tracey Barley
Lizzy Wilks Rodney Bennett
I also noticed if I remove and try to retype "$Users.EmployeeFullName" it no longer picks up the "EmployeeFullName" from the csv file.
Anyone know what I'm doing wrong here please?
Below would be an example:
$Users = Import-CSV C:\Documents\Managers.csv
ForEach ($User in $Users) {
$user = Get-ADUser -Filter "displayname -eq '$($User.EmployeeFullName)'"
$manager = (Get-ADUser -Filter "displayname -eq '$($User.'Line Manager Fullname')'").DistinguishedName
Set-ADUser -Identity $User -Replace #{manager=$manager}
}
Note: you don't need to dig down to the samAccountName property because Set-ADUser will take the full fidelity object for the -Identity argument. You also don't need to use Select... -ExpandProperty you can just parenthetically dot reference the distinguishedName property.
Also you can use the instancing capability in the AD cmdlets:
$Users = Import-CSV C:\Documents\Managers.csv
ForEach ( $User in $Users )
{
$User = Get-ADUser -Filter "displayname -eq '$($User.EmployeeFullName)'" -Properties Manager
$Manager = (Get-ADUser -Filter "displayname -eq '$($User.'Line Manager Fullname')'").DistinguishedName
$User.Manager = $Manager
Set-ADUser -Instance $User
}
In this case you call back the Manager property set it with a simple assignment statement than give the $User variable as the argument to the -Instance parameter of Set-ADUser
In my organization, we spend a large amount of time changing user home folder paths, based on users changing roles, etc. I have written a very simple powershell script that sets the homedir path from a csv.:
Import-Csv C:\Dir\homedir.csv | ForEach-Object {
Set-ADUser $_.SamAccountName –HomeDirectory $_.HomeDirectory
}
What I would like for this to also do, is to check the users for the presence of a -profilepath (roaming profile) and change that (if present) to "$_.HomeDirectory"\Profile (all roaming profiles follow this construct). If not present, it would simply skip down to the next user and perform the work as required.
I've played around with if statements, and really done more harm than good. Anyone got a lifeline they can throw me?
Hard to tell where you're getting stuck, but I assume it's in the 'properties' bit. ProfilePath is not pulled by default when you issue the command Get-ADUser. Something like this should do the trick:
Import-Csv C:\Dir\homedir.csv | ForEach-Object {
$user = Get-ADUser $_.SamAccountName -Properties 'ProfilePath'
if($user.ProfilePath -ne $null)
{
$profilepath = $_.HomeDirectory + "\Profile"
Set-ADUser $user –ProfilePath $profilepath
}
Set-ADUser $_.SamAccountName –HomeDirectory $_.HomeDirectory
}
You need to specify -Properties ProfilePath if you want the Get-ADUser command to return the profile path.
$user = Get-ADUser $_.SamAccountName -Properties ProfilePath
If ($user.ProfilePath -ne $null) {
Set-ADUser $_.SamAccountName -ProfilePath "$($_.HomeDirectory)\Profile"
}