<#

.NOTES

===========================================================================

Created on: 4/21/2015 1:00 PM

Updated on: 4/21/2015 8:00 AM

Created by: CS, or /u/challer on Reddit

Organization: N/A

Version: 0.1

Filepath: N/A

Filename: .\Set-CSUser.ps1

Dependencies: Active Directory Module, Permission to change AD attributes

===========================================================================

.SYNOPSIS

This advanced function is used to set user attribute values in Active

Directory using a Csv, comprised of columns for the UserPrincipalName

and the attribute with the value to be set.

.DESCRIPTION

This advanced function imports data from a Csv file and sets user attribute

values in Active Directory. The Csv file must contain at least two columns:

UserPrincipalName and AttributeName. The domain is determined by splitting

the UserPrincipalName. Windows Server 2012 R2 domain controllers are used

for the Set-ADUser operation.

This function will also run Get-ADUser and export the data to a Csv file

before and after making any changes. These two Csv files and the original

Csv file are then moved into a newly created folder in the same directory

as the original Csv file.

.EXAMPLES

-------------------------- EXAMPLE 1 --------------------------

Set-CSUser -Csv C:\Test.Csv

This command imports the Csv file, runs Get-ADUser on the UPNs, exports the data to

a Csv file, runs Set-ADUser on the UPNs, then runs Get-ADUser on the UPNs again and

finally exports the data to a separate Csv file. The Csv files run before and after

the Set-ADUser operation, in addition to the original Csv file, are then moved into

a folder with the same name as the original Csv file run.

#>

function Set-CSUser{

[CmdletBinding()]

Param

(

[Parameter(Mandatory=$true,

ValueFromPipelineByPropertyName=$true,

Position=0)]

[String]

$Csv

)

<#

This block relies on the Split method and Split-Path Cmdlet to parse out the parent directory and file name from the $Csv variable.

This information is used to create a new folder (Ln 71) to move the three files into (Ln 97). It is also used in the Export-Csv

functions (Ln 89,93). Both this block and the move operation happen outside of the nested ForEach loops which perform the Get-ADUser

and Set-ADUser operations (Ln 93).

#>

$CsvLeaf = $Csv | Split-Path -Leaf | Out-String

$CsvSplit = ($CsvLeaf).Split('.')

$CsvFilename = $CsvSplit[0]

$SourceDirectory = Split-Path -Path $Csv -Parent

New-Item $SourceDirectory'\'$CsvFilename -ItemType Directory | Out-Null

<#

The CSV is imported (Ln 79), then the PSObject properties are stored in variable. To prevent "" values in the imported Csv file, each

PropertyName in Properties must try to store the PropertyName in the Value variable. If it can't, it must be null, so nothing is set.

The updates are then added (Ln 87) to the array referenced earlier (Ln 84). This includes the UserPrincipalName, which we don't want

to set, so it's removed further down (Ln 96).

#>

$Dataset = Import-Csv -Path $Csv

$Properties = $Dataset[0].psobject.Properties.Name

foreach($User in $Dataset){

$Updates = @{}

foreach($PropertyName in $Properties){

if(($Value = $User."$PropertyName")){

$Updates.Add($PropertyName,$Value)

}

}

$UserPrincipalName = $User.UserPrincipalName;

$Split = $UserPrincipalName.Split('@')

$Domain = $Split[1]

$Server = Get-ADDomainController -DomainName $Domain -MinimumDirectoryServiceVersion Windows2012R2 -Discover | Select-Object -ExpandProperty Hostname

$Updates.Remove("UserPrincipalName")

<#

This is where Csv files are exported which include user data before (Ln 102) and after (Ln 106) the Set-ADUser operation takes place (Ln 104).

The parent ForEach loop then ends (Ln 109) and the three Csv files are moved (Ln 111) to the folder created earlier (Ln 73).

#>

Get-ADUser -Filter {UserPrincipalName -eq $UserPrincipalName} -Server $Server -Properties * | Export-Csv -Append -Force "$SourceDirectory\$CsvFilename-before.csv"

Get-ADUser -Filter {UserPrincipalName -eq $UserPrincipalName} -Server $Server | Set-ADUser -Replace $Updates

Get-ADUser -Filter {UserPrincipalName -eq $UserPrincipalName} -Server $Server -Properties * | Export-Csv -Append -Force "$SourceDirectory\$CsvFilename-after.csv"

}

Move-Item "$Csv","$SourceDirectory\$CsvFilename-before.csv","$SourceDirectory\$CsvFilename-after.csv" -Destination "$SourceDirectory\$CsvFilename"