Adding extension to otherTelephone Property - powershell

I'm hit and miss when it comes to writing PowerShell these days. I currently have a CSV with the following headers - Name, UserName, EXT, UserPrincipleName. I need to add the column data for OtherTelephone into each user's AD profile. I have a basic script going but I wanted to see if I was missing anything or if something needed to be corrected. I've added data to non-array attributes but wasnt sure if it was the same.
$users = Import-csv -path ".\extensions.csv"
foreach ($ext in $users {
Get-ADUser -Fi * -prop othertelephone -searchbase "MyOU" | select name,#{n="othertelephone";e={$_.othertelephone -join ";"}} | Set-aduser $_.userName -add #{othertelephone = $ext}
Thanks. And as always, I appreciate the help.

Since LDAP attribute otherTelephone is a multivalued (string array) property, I would first check to see if perhaps the new extension from the csv is already set for that user.
Then, if it is not, add it to the existing array.
Try
$searchBase = "OU=MyOU, ...."
$users = Import-csv -Path ".\extensions.csv"
foreach ($user in $users) {
# first check, is csv field EXT populated?
if ([string]::IsNullOrWhiteSpace($user.EXT) {
Write-Warning "Empty extension value for user $($user.Name) in the CSV.."
continue # skip this one and proceed with the next
}
# try and find the user using its UserPrincipalName
$adUser = Get-ADUser -Filter "UserPrincipalName -eq '$($user.UserPrincipalName)'" -Properties otherTelephone -Searchbase $searchBase
if ($adUser) {
# test if the new extension has already been set (otherTelephone is an array)
if ($adUser.otherTelephone -contains $user.EXT) {
Write-Host "Extension $($user.EXT) is already set for user $($user.Name).."
}
else {
Write-Host "Adding extension $($user.EXT) to user $($user.Name)"
# add the new extension to whatever is already set
# using -Add or -Replace usually wants strongly typed object arrays
# therefore the cast to [string[]]
[string[]]$extensions = #($user.EXT) + $adUser.otherTelephone
$adUser | Set-ADUser -Replace #{otherTelephone = $extensions}
}
}
else {
Write-Host "User $($user.Name) not found.."
}
}
Please note the property is called UserPrincipalName, not as stated in the question UserPrincipleName.

Related

Filter AD Users if one Property is Filled and one is empty

Im trying to get a list of all ADUsers that have there mail property filled and where the proxyAddresses property is empty.
First i got the ADUsers and allready tried to filter to only get thoose whith filled mail property.
$ADUser = get-adUser -Properties Name,Mail,proxyAddresses -Filter {mail -like '*'}| Where {$_.samAccountname -match "(our naming scheme)"}
then i tried to just put it trough a foreach with an embedded if statement
foreach ($User in $ADUser) {
if(($User).mail -ne $null -and ($User).proxyAddresses -eq $null)
{
$Users += $_.Name
}
}
I double checked the mail statement because i found some ADUsers in $ADUser that dont have the mail property filled.
Since im horribly bad with Powershell or scripting at all, I would guess it's quite a simple mistake.
But nothing gets passed in my $User variable.
It has to be a problem in my If Statement since i can do a
Write-Host $User
inside of the Foreach loop and it will output the $User
I tryed around for a bit now and even when i just plain do:
$Test = get-adUser -Properties proxyAddresses -Filter *
($Test).proxyAddresses |Format-List
I cant find an empty property in the list, im pretty sure there are some with empty propertys but somehow i cant find or match them.
Update:
Found a Workaround instead of filtering in the beginning for ADUsers with set Mail properties i now check for Users withouth something in the proxyAddresses property with:
$ADUser = Get-ADUser -Properties Name,Mail,proxyAddresses -Filter {-not(proxyAddresses -like '*')}
Afterwards i just use the foreach and if loop to check for the mail property.
$result = foreach ($User in $ADUser) {
if($User.mail -ne $null)
{
Write-Output($User).Name
}
else{
}
}
$result | Out-File -FilePath 'C:\temp\proxAddressesFilter.csv'
Sadly i aint sure why it didnt work with the first version, but at least it works now.
Changed which property i check for first, now i only get ADUsers with empty proxyAddresses property and later on check if something is in the mail property.
$ADUser = Get-ADUser -Properties Name,Mail,proxyAddresses -Filter {-not(proxyAddresses -like '*')}
$result = foreach ($User in $ADUser) {
if($User.mail -ne $null)
{
Write-Output($User).Name
}
else{
}
}
$result | Out-File -FilePath 'C:\temp\proxAddressesFilter.csv'

Set-ADuser: Is it possible to use DisplayName to update a user attribute in AD?

I need to update the attribute employeeID for a number of users in AD using powershell. Unfortunately, I don't have their username or samaccountname, only DisplayName. I'm able to get the users using DisplayName as a filter, but it doesn't work when using set-aduser. Is there any way I can use get-aduser to get the samaccountname, then using that to update the user via set-aduser?
Also, please note that it is important that the script doesn't overwrite any existing values.
My current (non-functional) script:
$csv = Import-Csv c:\test\users.csv
foreach ($line in $csv) {
$ADUserObject = Get-ADUser -Filter "DisplayName -eq '$line.displayname'" -Properties employeeID
if ($null -eq $ADUserObject.EmployeeID) {
Set-ADUser -Filter "DisplayName -eq '$line.displayname'" -employeeID $line.employeeid
}
}
The CSV file looks like this:
employeeid,GivenName,Surname,displayname
489900,Angela,Davis,Angela Davis
Any input or suggestions appreciated, thank you!
As commented, this is in fact a duplicate of this question, but since there, the OP did not upvote or accept any of the given answers, I could not mark it as duplicate.
As Mathias R. Jessen explained already, the Filter you are using is wrong. Also, there is no -Filter parameter on Set-ADUser as there is on its counterpart Get-ADUser.
This should do what you want:
Import-Csv -Path 'c:\test\users.csv' | ForEach-Object {
$ADUserObject = Get-ADUser -Filter "DisplayName -eq '$($_.displayname)'" -Properties DisplayName, employeeID -ErrorAction SilentlyContinue
if ($ADUserObject) {
# check if this user already has an EmployeeId filled in
if ($ADUserObject.EmployeeID) {
Write-Host "User $($ADUserObject.DisplayName) already has EmployeeId $($ADUserObject.EmployeeID)"
}
else {
Write-Host "Setting EmployeeID $($ADUserObject.EmployeeID) for user $($ADUserObject.DisplayName)"
$ADUserObject | Set-ADUser -EmployeeID $_.employeeid
}
}
else {
Write-Warning "User $($_.DisplayName) could not be found"
}
}

Disable users from valid list

I've got a list of valid users provided by HR. The formatting was not cool, so I managed to get a new file like I wanted: one column, on each line the samaccountname (1st letter of firstname and name).
My file looks like this:
bgates
sjobs
bmarley
epresley
etc.
I'd like to disable users who are NOT in this list. I guess I have to deal with some if stuff, but I don't know how to.
#HariHaran, i have tried this:
#this part works fine
$list = Import-Csv .\listadnames2.csv -Delimiter ";"
$lol =
ForEach ($user in $list)
{
$user.prenom[0] + $user.nom
}
$lol | Out-File .\samaccountnames.csv
$validusers = Import-Csv .\samaccountnames.csv
$fullusers = Get-ADUser -Filter * -SearchBase "OU=USERS,DC=domain,DC=com" -ResultPageSize 0 -Prop samaccountname | Select samaccountname
foreach ($u in $validusers)
if ($u -match $fullusers) {continue} else
{
Set-ADUser -Identity $($._) -Enabled $false -whatif
}
The users list (samaccountnames.csv) you create in $lol is not a CSV file, but simply a text file with all constructed usernames each on a separate line.
Therefore you should read the file using
$validusers = Get-Content .\samaccountnames.csv instead of $validusers = Import-Csv .\samaccountnames.csv.
Then you'll have an array of samaccountnames to work with.
Next, I wonder why you use -ResultPageSize 0.. The default setting is 256 objects per page, so I can only imaging you could need this value to be higher than this default, not less.
(see the docs)
Taken from the part where you read the samaccountnames file, I think this will do the job:
$validusers = Get-Content .\samaccountnames.csv
# property 'SamAccountName' is returned by default as are
# 'DistinguishedName', 'Enabled', 'GivenName', 'Name', 'ObjectClass', 'ObjectGUID', 'SID', 'Surname' and 'UserPrincipalName'
# get the user objects from AD and loop through them to see if they need to be set disabled
Get-ADUser -Filter * -SearchBase "OU=USERS,DC=domain,DC=com" | ForEach-Object {
# the $_ automatic variable now holds an AD user object
# or use if($_.SamAccountName -notin $validusers). Only for PowerShell version 3.0 and up
if ($validusers -notcontains $_.SamAccountName) {
$_ | Set-ADUser -Enabled $false -WhatIf
}
}

List user details from Username

I am trying to create a script that will check a list of user names and show the user full name and some attribute settings from AD. Basically I have been sent a list of usernames which are just numbers and management want to know the users full name for each username. they also want to know want division they work for.
Below is the script I have created which doesn't work.
$csv = Import-Csv "C:\temp\users.csv"
foreach ($user in $csv) {
$name = $user.myid
Get-ADUser -Filter {EmployeeID -eq $name} -Properties * |
Get-ADUser -Division $user.Programme
} | Export-Csv "C:\Temp\Results.csv"
So I'm working under the assumption that there is a column named myid in your csv file that contains the id you need to be looking up. Assuming that is the case you'll need to make a few changes here. You'll need to remove the second get-aduser as it is not really doing anything for you, and there is no -division switch available to the get-aduser cmdlet, if you need to restrict your results to just a few settings you can do that using the -properties switch and piping to select as shown below. Keep in mind that none of this will matter if the users do not have the "employeeid" and "division" properties set on their AD accounts, which is fairly rare in my experience but if your company does as a matter of policy when creating accounts should be fine. If you replace the get-aduser line in your script with this it should get the account of any user with an EmployeeID property that matches the one in your spreadsheet and then output that person's full name, division, and employeeid to your CSV file.
Get-ADUser -Filter {EmployeeID -eq $name} -Properties "displayname","division","employeeid" | Select-Object "employeeid","displayname","division"
When in doubt, read the documentation. Get-ADUser doesn't have a parameter -Division. You need to select the properties you want in the output file. Also, foreach loops don't pass output into the pipeline. You need a ForEach-Object loop if you want to pass the output directly into Export-Csv:
Import-Csv 'C:\temp\users.csv' |
ForEach-Object {
$name = $_.myid
Get-ADUser -Filter "EmployeeID -eq $name" -Properties *
} |
Select-Object SamAccountName, DisplayName, Division |
Export-Csv 'C:\Temp\Results.csv' -NoType
Otherwise you need to collect the output in a variable:
$users = foreach ($user in $csv) {
$name = $user.myid
Get-ADUser -Filter "EmployeeID -eq $name" -Properties *
}
$users | Export-Csv 'C:\Temp\Results.csv' -NoType
or run the loop in a subexpression:
$(foreach ($user in $csv) {
$name = $user.myid
Get-ADUser -Filter "EmployeeID -eq $name" -Properties *
}) | Export-Csv 'C:\Temp\Results.csv' -NoType
This is a generic code structure that can be adapted for data collection / enumeration and production of CSV files, tailored to your scenario. We use similar at my workplace. It contains some error handling - the last thing you'd want is inaccurate results in your CSV file.
# Create an array from a data source:
$dataArray = import-csv "C:\temp\users.csv"
# Create an array to store results of foreach loop:
$arrayOfHashtables = #()
# Loop the data array, doing additional work to create our custom data for the CSV file:
foreach($item in $dataArray)
{
try
{
$ADObject = Get-ADUser -Filter { EmployeeID -eq $item.MyID } -Properties DisplayName,Division -ErrorAction Stop
}
catch
{
Write-Output "$($item.MyID): Error looking up this ID. Error was $($Error[0].Exception.Message)"
}
if($ADObject)
{
# Create a hashtable to store information about a single item:
$hashTable = [ordered]#{
EmployeeID=$item.myID
DisplayName=$ADObject.DisplayName
}
# Add the hashtable into the results array:
$arrayOfHashtables += (New-Object -TypeName PSObject -Property $hashTable)
}
else
{
Write-Output "$($item.MyID): No result found for this ID."
}
}
# If the results array was populated, export it:
if($arrayOfHashtables.Count -gt 0)
{
$arrayOfHashtables | Export-CSV -Path "C:\Temp\Results.csv" -Confirm:$false -NoTypeInformation
}
As mentioned elsewhere, division isn't a property on an AD object so you might need to lookup this data elsewhere. If you can do that with another line of PowerShell inside your foreach loop, you could add this to your hashtable object like so:
$hashTable = [ordered]#{
EmployeeID=$item.myID
DisplayName=$ADObject.DisplayName
Division=$DivisionFromOtherSource
}

PowerShell Active Directory Loop Through All User Properties

I'm currently working on some PowerShell to update Active Directory User Attributes. The script will read the updated attributes from a CSV.
What I would like to achieve is to iterate through users and compare each user attribute against the value stored in the CSV. If the CSV attribute value doesn’t match the user's Active Directory attribute I would like to update the value in Active Directory
At present I can select a user and display the all the properties using the following:
Get-ADUser -Filter "UserPrincipalName -eq '$($upn)'" -Properties * -SearchBase 'DC=core,DC=com'
What I'm struggling on is the ability to loop through all the properties for each user and compare them against the CSV values for that user.
Here is the snippet I'm working from:
# Import CSV into variable $users
$users = Import-Csv -Path 'C:\PowerShell\AD\UserUpdates.csv'
# Loop through each user
foreach ($user in $users) {
#Search in specified OU and Update existing attributes
$userproperties = Get-ADUser -Filter "UserPrincipalName -eq '$($user.UserPrincpalName)'" -Properties * -SearchBase 'DC=core,DC=com'
}
Does anyone know a way of looping through all the user profile attributes for a user?
Any help or guidance would be greatly appreciated?
UPDATE
Ok working on this a bit further, I have made progress but I don't think it's the cleanest way of accomplishing this.
$userproperties = Get-ADUser -Filter "UserPrincipalName -eq '$($upn)'" -Properties * -SearchBase 'DC=core,DC=com' | Select-Object Name,Created, LastLogon,GivenName,SurName,DisplayName,DistinguishedName,UserPrincipleName
This allows me to select items such as the following:
$userproperties.DisplayName
But with this approach I need to list out every attribute I wish to work with. I would prefer to be able to loop across all properties. Maybe I can put all the properties I wish to utulise into an array and loop through that?
this is a way to cycle into the properties of an object (an AD user in this case):
$user = Get-ADUser -Filter "UserPrincipalName -eq '$($user.UserPrincpalName)'" -Properties * -SearchBase 'DC=core,DC=com'
$user | gm | ? membertype -eq property | select -expa name | % { $user.$_ }
in the foreach-object (%) you can add the logic you need to update some proeprty
It's not too hard to loop through all the properties of one entry in the CSV file. The trick is to transform the hashtable you get from looping through the imported
csv data into a PS object, as follows:
# Import CSV into variable $users
$users = Import-Csv -Path 'C:\PowerShell\AD\UserUpdates.csv'
# Loop through each user
foreach ($user in $users) {
#Obtain attributes from corresponding ADuser.
$userproperties = Get-ADUser -Filter '
"UserPrincipalName -eq '$($user.UserPrincpalName)'" `
-Properties * -SearchBase 'DC=core,DC=com'
#Search in specified OU and Update existing attributes
foreach ($prop in $user.psobject.properties) {
Set-variable -name $prop.name -value $prop.value
# Instead of doing a set-variable, you could set the corresponding attribute
# in the appropriate AD.
}
}
Set-ADUser has a -Replace parameter that accepts a hash table of properties and values that you can use to update multiple properties at once. Rather than looping through each property for each user, you can just build that hash table and then do a single update operation. You can make it a little more efficient by just returning the AD User properties you're checking from your CSV. That list of properties can be had by simply getting a property list from the first object in the collection created from your imported CSV file.
# Import CSV into variable $users
$CSVusers = Import-Csv -Path 'C:\PowerShell\AD\UserUpdates.csv'
#Get the list of properties to check
$Properties = $CSVusers[0].psobject.properties.name
# Loop through each user
foreach ($CSVuser in $CSVusers) {
$UpdateProperties = #{}
#Search in specified OU and Update existing attributes
$ADUser = Get-ADUser -Filter "UserPrincipalName -eq '$($CSVuser.UserPrincpalName)'" -Properties $Properties -SearchBase 'DC=core,DC=com'
#Create a hash table of properties that need updated
Foreach ($Property in $Properties)
{
if ($CSVUser.$Property -ne $ADUser.$Property)
{ $UpdateProperties[$Property] = $CSVuser.$Property }
}
#Update user
if ( $UpdateProperties.Count -gt 0 )
{ Set-ADUser $ADUser.DistinguishedName -Replace $UpdateProperties }
}