Get-ADUser Check for conflicting proxyAddresses - powershell

Currently I have a script that creates user accounts.
Note: Not all users have the same UPN (UserPrincipalName)
User accounts are in the following format: <firstinit><lastname>.
If this conflicts, the format will be changed to: <firstinit><middleinit><lastname>
Recently I have ran into an issue where the user's proxyAddress is conflicting with existing users. This is a problem because AD will not catch this.
Issue:
Checking every AD-User's proxy address is very time consuming if not included in the filter. However, when including proxyAddresses in the filter the results are inconsistent. I am assuming this is because the proxyAddresses attribute is an array.
Inconsistent:
Import-Module ActiveDirectory
$FirstLast = "jrider#ChuckNorrisKills.com"
$conflictCheck = Get-ADUser -Properties mail, proxyAddresses -Filter "mail -eq '$FirstLast' -or UserPrincipalName -eq '$FirstLast' -or proxyAddresses -eq `"smtp:'$FirstLast'`"" | measure
if($conflictCheck.Count -gt 0)
{
Write-Host "New user conflicts with existing user" -ForegroundColor Red
}
I have come up with a solution that will resolve me issue. Unfortunately this is very slow (expected):
Import-Module ActiveDirectory
function Test-NewADUser
{
Param(
[Parameter(Mandatory=$true)][string]$firstname,
[Parameter(Mandatory=$true)][string]$lastname,
[Parameter(Mandatory=$false)][string]$middle
)
[bool]$proxExsists = $false
$domain = '#chuckNorrisKills.com'
$FirstLast = $firstname.Substring(0,1)+$lastname+$domain
Get-ADUser -Filter * -Properties proxyAddresses | foreach {
#xpand the proxy address and iterate through it
foreach($address in $_.proxyAddresses)
{
#As you can see this goes through every user
Write-Host "Address: " $address -ForegroundColor Yellow
if($address -eq "smtp:$FirstLast")
{
Write-Host "Found Conflict" -ForegroundColor Red
$proxExsists = $true
}
}
}
}
Test-NewADUser -firstname jack -lastname Rider
Question(s):
Is there a way to expand proxyAddresses and check for conflicts in the -Filter?
If not, should I bother with Jobs, or an alternate way of checking for conflicts?
Thank you in advance for any help

You don't need to expand it, as the proxyAddress filter should be reliable.
So, this should be very straightforward:
function Validate-proxyAddress($email)
{
if (Get-ADUser -Filter "proxyAddresses -eq 'smtp:$email'")
{
return $true
}
elseif (Get-ADUser -Filter "mail -eq '$email'")
{
return $true
}
elseif (Get-ADUser -Filter "UserPrincipalName -eq '$email'")
{
return $true
}
return $false
}
or you can join it all in one like your code, hasn't tested it, so if you get false, the user not exist, should be ok to continue...
Also, you can use -like instead of -eq if you need (in cases where missing the smtp prefix somehow):
"proxyAddresses -like '*$email*'"

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'

ADUser assign specific department if null

I am trying to add users to a department when they are in a specific OU.
But I don't want to overwrite the users / alter them when it is not null. Because I don't want my file to grow.
How should I correct this?
$textfile=get-date -Format "yyyy-MM-dd"
Start-Transcript -Path "c:\results\location A\$textfile.txt"
Write-Host "Assigning / re-assigning users to a OU specific department..." -ForegroundColor Yellow
Get-ADUser -filter * -SearchBase "ou=Users,ou=Location A,ou=organization,dc=fabrikam,dc=com" |
ForEach-Object {
$user = $_
if ($user.Department -ne $null) {
try {
Set-ADUser $user -Department "Location A"
Write-Host $user.Name"moved to department" -BackgroundColor Green -ForegroundColor Black
}
catch {
Write-Host "Error occured" -BackgroundColor Red -ForegroundColor Black
}
}
}
Stop-Transcript
This is a common question about the mysteries of active directory filters. This filter will return objects with null department properties.
get-aduser -filter "department -notlike '*'" -ResultSetSize 5 -property department
as #js2010 pointed out, Get-ADUser will retrieve only a very few subset of AD properties, department, is not one of them, so when you test it, it will be always null. To avoid this add -Properties department parameter to Get-ADUser. (You should prefer his filter too, just add the searchbase you want)
But there is another problem if you want to test this after as you did, your condition is reverted : you are testing to replace only values that are already defined, -eqwill be better ;) as #iRon said, you should prefer $null -eq $user.department than $user.department -eq $null (#Theo's one is fine too)

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"
}
}

How to exclude certain users Powershell Password Reset Script

Hey guys need a little help,
I have been rapping my head around how to exclude certain users from a password reset script.
This is the script:
$newPassword = ConvertTo-SecureString -AsPlainText "MyP#ssw0rd" -Force
Import-Csv "C:\users\administrator\desktop\UserCreation.csv" | ForEach-Object {
$samAccountName = $_."samAccountName"
Set-ADAccountPassword -Identity $samAccountName -NewPassword $newPassword -Reset
Set-AdUser -Identity $samAccountName -ChangePasswordAtLogon $false
Write-Host " AD Password has been reset for: "$samAccountName
}
I want to exclude certain samAccountNames from this password reset however I cant quite work it out.
Any help would be much appreciated.
Thanks Guys
You can always set filters in your Set-AdUser comamand.
Like:
Get-ADUser -Filter {(Enabled -eq $true)`
-and (sAMAccountType -ne 805306370)`
-and (cn -ne "Administrator")}`
-and (SamAccountName -like "*-ext*")`
-SearchBase "OU=OUwithUsers,DC=MySubdomain,DC=MyDomain,DC=com"
You can filter your user list like that or you can modify your csv file by deleting/adding users there. You are using a csv file as an import so that one should have the list of the users that you want to change their passwords.
Personally I would clear the csv or create a csv with more filters so I can then import it and finish what I want to do without worrying if I changed someones password without his permission.
can you use an exclusion list like this :
$exclusion_list = "testuser1","testuser2"
$totalList = ("testuser1","testuser2","testuser4")
foreach($item in $totalList){
if( $exclusion_list -contains $item){
"excluding $item"
continue
}
else{
#reset the password
$item
}
}
Hash table version for performance reasons:
$exclusion_list = #{"testuser1"="exclude";"testuser2"="exclude"}
$totalList = ("testuser1","testuser2","testuser4")
foreach($item in $totalList){
if( $exclusion_list[$item]){
"excluding $item"
continue
}
else{
#your code
$item
}
}

Powershell Import-Csv then Get-Aduser results in all users in ad being displayed when a Blank Line appears

I am writing a powershell script to disable users due to the fact that we get a list of them everyday and it is monotonous. I paste the list from the ticket into a csv formatted as Lastname, Firstname then run my script with imports the list, serches ad and ask if you want to disable if it finds them. Here is the code...
# Set variables
$Import = "C:\Scripts\Support Files\Users_To_Disable.csv"
$Export = "C:\Scripts\Support Files\Disabled_Users_Output.txt"
# Import user list
$Users = Import-CSV $Import
foreach ($User in $Users)
{
# Set user variables
$LastName = $User.("Surname")
$FirstName = $User.("GivenName")
# Use user variables from list to search ad
$UserName = (Get-ADUser -Filter "GivenName -like '$FirstName*' -and Surname -like '$LastName*'").SamAccountName
# What to do if it finds nothing
If ($UserName -eq $Null)
{
Write-Host $LastName, $FirstName NA -ForegroundColor Yellow
Write-Output "$LastName, $FirstName NA" | Out-File $Export -Append
}
# What to do if it finds a user
Else
{
# Ask for user input
Write-Host $LastName, $FirstName Found -ForegroundColor Green
Write-Host UserName = $UserName -ForegroundColor Green
DO {
$Disable = Read-Host "Do you want to disable user? (Y/N)"
If($Disable -eq "Y")
{
# Disable the user
Disable-ADAccount -Identity $UserName
# Move the user
Get-ADUser $UserName | Move-ADObject -TargetPath "OU=Disabled - Retention,DC=intranet,DC=sw"
# Add Disabled Users group
Add-ADGroupMember "Disabled Users" -Members "$UserName"
# Set Disable Users as primary group
$Group = Get-ADGroup "Disabled Users" -Properties #("PrimaryGroupToken")
Get-ADUser "$UserName" | Set-ADUser -Replace #{PrimaryGroupID=$Group.PrimaryGroupToken}
# Remove all other groups
$User = Get-ADUser "$UserName" -Properties MemberOf
$Groups = $User.MemberOf |ForEach-Object { Get-ADGroup $_ }
$Groups | ForEach-Object { Remove-ADGroupMember -Identity $_ -Members $User -Confirm:$false }
# Output
Write-Host $LastName, $FirstName Disabled -ForegroundColor Red
Write-Output "$LastName, $FirstName Disabled" | Out-File $Export -Append
Break
}
}
Until ($Disable -eq "N")
}
}
Invoke-Item $Export
All of that works, what is scary is that if there are blank cells above a user then it returns all of the users in ad and asks if you want to disable all of them. In other words if the csv looks like this...
Surname GivenName
User Test
Everything works fine, but if it looks like this...
Surname GivenName
User Test
Pandemonium, well not really but it does ask if you want to initiate a resume generating event, which I don't so how can I build in some safety that would stop it from returning all of ad when there are blanks in the csv before users?
You can eliminate the blank lines by filtering out Null values on your import, which should resolve the problem.
$Users = Import-CSV $Import | Where-Object {$_.Surname}