PowerShell V2 script to update Active Directory users from a CSV file. Only specified fields in the CSV that are not missing update the users. The value "<delete>" flags to clear the attribute. Attributes are not updated if the value in the CSV matches the existing value in AD.

Just about any database of users can be exported to a comma delimited (CSV) file. This script ignores missing values in the CSV file. It only considers fields in the CSV file that you specify. And it only updates a user if the new value specified in the CSV file does not match the existing value in Active Directory. This means a comma delimited file can be used to repeatedly update users in bulk. There is no need to ensure that the file only includes new updates. In fact, there is not even a requirement that each user have only one row in the CSV file.

Features of the script:

  1. Users can be identified by sAMAccountName, distinguishedName, SID, or GUID.
  2. The script can update or clear many Active Directory attributes specified by lDAPDisplayName.
  3. The script also supports the following Set-ADUser parameters: AccountExpirationDate, Enabled, Manager, PasswordNeverExpires, and SmartcardLogonRequired.
  4. Any missing entries in the CSV file are skipped.
  5. Any fields in the CSV file that are not identified in the script are ignored.
  6. Will only update an attribute if the new value in the CSV is different from the existing value in Active Directory (case insensitive).
  7. If the value in the CSV is the string "<delete>", any existing value in Active Directory will be cleared.
  8. The script writes a detailed log. All errors are documented in the log file.
  9. You can specify that users will not be updated and the script will just log which users it would update.
  10. The script can update most AD attributes with syntax String, DN, Boolean, Integer, or LargeInteger, as long as you have permissions and the value is valid.

The CSV must have a header line. The field labeled UserID identifies the users in Active Directory. The value in the UserID field can be any of the following: sAMAccountName (pre-Windows 2000 logon name), distinguishedName, SID, or GUID. The remaining fields of the CSV that will be used to update users are specified in the script by the array $Fields. These fields must be identified by either the LDAPDisplayNames of the Active Directory attributes or the names of the supported Set-ADUser parameters. The $Fields array should not include the field named UserID. Any fields of the CSV not specified in the array are ignored (except UserID).

All of the updates for each user (one row of the CSV file) are done in one or two PowerShell statements, using the Set-ADUser cmdlet. For each row the script populates the hash table $AttrReplace with the field names and the new values to be passed to the -Replace parameter of the Set-ADUser cmdlet. Similarly, the array $AttrClear is populated with the field names to be cleared for the user using the -Clear parameter. If any supported parameters are specified they are added to the cmdlet.

The script also demonstrates how to construct a PowerShell command as a string. The script appends various parameters to the string as required. A series of conditional statements determine which parameters are needed for every line in the CSV file. The resulting string is then converted into a script block using the Create method of the .NET scriptblock class. The script block is passed to the Invoke-Command cmdlet, which runs the PowerShell command on the local client. However, this technique cannot be used to add the -Replace parameter to the command. The required hash table cannot be converted from a string into a hash table when the string is converted into a script block. A separate Set-ADUser command is required to employ the -Replace parameter.

Each time the Set-ADUser cmdlet is run by the script, there are 7 possible parameters: -Replace, -Clear, -AccountExpirationDate, -Enabled, -Manager, -PasswordNeverExpires, and -SmartcardLogonRequired. We can add all but the first to a string representation of a Set-ADUser command. If the script simply checked which of the 6 remaining parameters were needed and ran separate Set-ADUser commands for each possibility, there would be 32 possible combinations. One combination results in no update for the user. The script would require 31 separate Set-ADUser commands, plus the code to determine which to use for each line of the CSV file. Instead, the script uses a few conditional statements to build the PowerShell command as a string. The string must be converted into a script block before it can be executed by the Invoke-Command cmdlet.

The script writes a detailed log documenting the result of each line in the CSV. The script also logs the number of CSV lines processed, the number of users updated, the number not updated, the number of users not found, and the number of errors raised attempting to update users.

Suggested steps to use the script:

  1. Prepare the CSV file with a header line. The field "UserID" should identify the user.
  2. Modify or verify the variable $CsvFile, the CSV file to be read by the script.
  3. Modify or verify the variable $LogFile, the log file to be appended to by the script.
  4. Update the array $Fields to include the names of the fields in the CSV that will be used to update users.
  5. Modify or verify the value assigned to the variable $MaxErrorsAllowed, the number of errors allowed before the script aborts.
  6. Run the script first with the variable $Update assigned the value $False.
  7. Check the log file for problems or errors. Fix any problems identified.
  8. Run the script with the variable $Update assigned the value $True to update the users.
  9. Check the log file for problems or errors.

Cautions:

  1. Any values in the CSV with embedded commas, such as distinguished names, must be enclosed in quotes.
  2. The comparison with existing values in AD is case insensitive.
  3. The script cannot modify the Relative Distinguished Name (the Common Name of the user).
  4. Any invalid values will raise an error when the Set-ADUser cmdlet is invoked, which will be logged.
  5. For each row of the CSV, any error raised by the Set-ADUser cmdlet updating any attribute or property of a user results in no updates by the cmdlet.
  6. The script cannot add values to or remove values from multi-valued attributes. However, it can replace with one value or clear all existing values of a multi-valued attribute.
  7. Any values of "True", "False", "$True", or "$False" in the CSV file are assumed to apply to boolean attributes. If you assign any of these strings to a string attribute, the value will be converted into "TRUE" or "FALSE".
  8. If the CSV file specifies "<delete>" for the AccountExpirationDate or Manager properties, the corresponding attribute is cleared. The attribute for AccountExpirationDate is accountExpires, while for Manager it is manager. The log file will reflect that an attribute was cleared, not that a parameter was set.
  9. You can specify the sAMAccountName for the Manager of a user in the CSV file. This is a great feature of the -Manager parameter of the Set-ADUser cmdlet. But if you use the CSV file again, the script will see the existing value of the Manager property as the distinguished name of the manager, and will not recognize that the sAMAccountName refers to the same object. The script will update the Manager property of the user again.
  10. Boolean PowerShell properties, like Enabled, PasswordNeverExpires, and SmartcardLogonRequired cannot be cleared. Do not specify "<delete>" for these parameters. However, you can clear boolean AD attributes, like msNPAllowDialin.

An example CSV file follows:

UserID,title,Enabled,manager,sAMAccountName,otherTelephone
srbecker,Temp Contractor,,"cn=Jim Smith,ou=Staff,dc=MyDomain,dc=com",,222-123-4598
jmsmith,"<delete>",False,,,222-123-4567
rmbecker,,,,,"<delete>"
fjohnson,IT Coordinator,True,,NewNTName,
swilliams,Help Desk,,jsmith,,222-456-8765

UpdateUsersCsv.txt <<-- Click here to view or download the program