Find AD user information with DisplayName - powershell

I have a list of displaynames and I need to get their AD informations.
Get-Content "C:\displaynames.txt" |
foreach {
$givenname,$surname = $_ -split ' '
if (Get-ADUser -Filter "surname -eq '$surname' -and givenname -eq '$givenname'"){
Get-ADUser -Filter { displayName -match $_} -Properties EmailAddress, Manager | Select Givenname, Surname, SamAccountName, EmailAddress, Manager}
else {Get-ADUser -Filter { displayName -like "AD Test"} -Properties EmailAddress, Manager | Select Givenname, Surname, SamAccountName, EmailAddress, Manager}
} | Export-Csv -Path C:\result.csv
This works fine, but only if users have no middle names ex. John Moore
If the user has a middle name, it doesn't pick it up.
How can I change the script so it picks up users with middle names ex. John Roger Moore?

As Mathias R. Jessen already commented, you can use the -Filter on property DisplayName directly.
The Filter should be a string, not a scriptblock.
Using -Filter also has the advantage that you can suppress exceptions being thrown, so I would build in a step to confirm that we indeed did find a user with that displayname:
Get-Content "C:\displaynames.txt" | ForEach-Object {
$user = Get-ADUSer -Filter "DisplayName -eq '$_'" -Properties DisplayName, EmailAddress, Manager -ErrorAction SilentlyContinue
if ($user) {
# output the wanted properties as **object**
$user | Select-Object Givenname, Surname, SamAccountName, EmailAddress, Manager
}
else {
# nobody in this domain with a displayname like that..
Write-Warning "User '$_' could not be found.."
}
} | Export-Csv -Path 'C:\result.csv' -NoTypeInformation
Note that the Manager property is in the form of the managers DistinguishedName. If you want to get other properties for the manager, like his/her name, you will have to use Get-ADUser -Identity $user.Manager to get the wanted property there too

The basic question here is how to account for middle names.
PowerShell 5 has some AI-powered cmdlets.
Here, I will quote an example from the documentation.
Example 2: Simplify format of a string
$composers = #("Johann Sebastian Bach", "Wolfgang Amadeus Mozart", "Frederic Francois Chopin", "Johannes Brahms")
$composers | Convert-String -Example "first middle last=last, first"
Bach, Johann
Mozart, Wolfgang
Chopin, Frederic
Brahms, Johannes
The first command creates an array that contains first, middle and last names. Note that the last entry has no middle name.
The second command formats the names according to the example. It puts the last name first in the output, followed by the first name. All middle names removed; entry without middle name is handled correctly.
Convert-String (Microsoft.PowerShell.Utility) - PowerShell | Microsoft Docs

Related

Updating Active Directory users email with Powershell

I need to change a lot of users "email" field on their active directory profile however I cant seem to find the answer Im looking for looking at other posts.
I`m quite new to powershell but I've landed this task to be done at work.
The email address format is in the style of "first name" and "lastname" seperated by a "." with the domain appended on the end naturally.
An example would be John.Doe#domain.com
How would I go about this with powershell with users in 6 different OUs but all under the same root OU?
Kind regards
It depends on how you have the data. If you already have the emails in say a csv with a column titled "OldEmail" and "NewEmail" you could do something like:
$csv = import-csv \\path\to\csv
foreach($user in $csv) {
get-aduser -filter {mail -eq $user.OldEmail} | Set-ADUser -EmailAddress $user.NewEmail
}
You could do something like below, but as always when changing stuff in Active Directory,
try it out on a bunch of testusers first
# enter the root OU DistinguishedName where the sub OU's are here
$rootOU = "OU=Users,DC=yourdomain,DC=com"
# Get a list of user objects that do not have an email address in 'firstname.lastname#yourdomain.com' format.
# you only have to ask for property EmailAddress (LDAP name is 'mail'), because these properties are returned by default:
# DistinguishedName, Enabled, GivenName, Name, ObjectClass, ObjectGUID, SamAccountName, SID, Surname, UserPrincipalName
Get-ADUser -Filter * -SearchBase $rootOU -SearchScope Subtree -Properties EmailAddress |
Where-Object { $_.EmailAddress -ne ('{0}.{1}#yourdomain.com' -f $_.GivenName, $_.Surname) } |
ForEach-Object {
$mail = '{0}.{1}#yourdomain.com' -f $_.GivenName, $_.Surname
Write-Host "Setting up email address $mail for user $($_.SamAccountName)"
$_ | Set-ADUser -EmailAddress $mail
}

Looking up a particular user in a particular group in AD using Powershell

I've been looking online for ways of doing this and I'm at a loss here. I'm looking for a way to look up a particular user within a particular group in AD through powershell. Here's what I've tried.
(Get-ADUser userName –Properties MemberOf).MemberOf
I get a bunch of groups
(Get-ADGroupMember "groupname").name
I get a bunch of usernames
I tried this command but it's taking forever to get results.
(Get-ADGroupMember 'groupname' | Get-ADUser -Property DisplayName | Where-Object { $_.Name -eq 'username'})
Is there a way where I can get a command that both fast and efficient. I'm also looking for their email address and surname and last name.
Thanks in advance
As commented, it is best not use the Name property, but if you have it use the SamAccountName or DistinguishedName of the user you seek to rule out ambiguous names.
$user = Get-ADGroupMember -Identity 'GroupName' |
Where-Object { $_.objectClass -eq 'user' -and $_.SamAccountName -eq 'userSamAccountName' } |
Get-ADUser -Properties DisplayName, EmailAddress, GivenName, Surname # add more properties if you need them
# display the user object on screen
$user
Or do this way:
$user = $null
$member = Get-ADGroupMember -Identity 'TheGroupName' |
Where-Object { $_.objectClass -eq 'user' -and $_.SamAccountName -eq 'TheuserSamAccountName' }
if ($member) {
# add more properties if you need them
$user = Get-ADUser -Identity $member.DistinguishedName -Properties DisplayName, EmailAddress, GivenName, Surname
}
else {
Write-Host "User 'TheuserSamAccountName' is not a member of group 'TheGroupName'"
}
# display the user object on screen
$user
The resulting $user object will also contain these properties:
DistinguishedName, Enabled, Name, ObjectClass, ObjectGUID, SamAccountName, SID, UserPrincipalName
If you don't need all of these properties simply filter them out using
$user | Select-Object DisplayName, EmailAddress, GivenName, Surname

Piping AD-User Information to CSV

I've got some logic/formatting brain block here.
I have a CSV with GivenName and Surname Property to use
I need to pipe that info against the AD User Estate and Return the information on the users in the list with a few properties including their name, Office, SamAccountName and Email address. I've got as far as this:
$employees = import-csv 'c:\employees\employeelist.csv'
$UserInfo = ForEach ($user in $employees) { Get-ADUser -Filter * | `
Where-Object { $_.GivenName -like
$employee.GivenName -and $_.Surname -like $employee.Surname
}
The information is returned but not in a table form and i can't believe i cant seem to figure how to pipe it to a CSV, it's not working out, it is returned like this:
Reference : 201111
Surname : Smith
GivenName : Name
Effective from : 24-Sep-13
Business Area : Client Ops
Department : ATE
Organisation Unit : ATE Ops
Any Ideas why when i | export-csv i don't get the correct format?
As commented, you are using the wrong variable name in your foreach loop.
($employee should be $user) since that is the variable you define in the loop.
Something like this:
$employees = Import-Csv 'c:\employees\employeelist.csv'
$UserInfo = foreach ($user in $employees) {
Get-ADUser -Filter * -Properties GivenName, Surname, Office, SamAccountName, EmailAddress |
Where-Object { $user.GivenName -eq $_.GivenName -and $user.Surname -eq $_.Surname } |
Select-Object GivenName, Surname, Office, SamAccountName, EmailAddress
}
$UserInfo | Export-Csv -Path 'c:\employees\employees.csv' -NoTypeInformation
As you can see, I'm also naming the properties you want returned, because Get-ADUser by default returns a subset of properties and withour it, you won't get the Office and EmailAddress properties.
Also, I have changed the -like operator into -eq to fetch exact matches.
P.S. Instead of using the Where-Object construction, the code would be more optimized if you use the -Filter like:
$UserInfo = foreach ($user in $employees) {
Get-ADUser -Filter "GivenName -eq '$($user.GivenName)' -and Surname -eq '$($user.Surname)'" -Properties GivenName, Surname, Office, SamAccountName, EmailAddress |
Select-Object GivenName, Surname, Office, SamAccountName, EmailAddress
}

Extracting AD records attributes from a group but need manager's email address as well

I have this script that gets all the members from a security group and then extracts to a file a bunch of their attributes. It works correctly except to pull the manager's email address. The weird thing is though if I run this command to get the manager's email address directly in PowerShell it does return their email address.
Here is the entire script:
Get-ADGroupMember -Identity "ACP Users" -Recursive |
Get-ADUser -Property employeeNumber, SN, Manager, GivenName, Name, Office,
Mobile, emailaddress, Department, Title,
samaccountname, officephone, homephone |
select employeeNumber,SN, GivenName,Manager, Office, Mobile,
emailaddress,Department, Title, samaccountname,
officephone,homephone,enabled |
Select-object #{Name='Empno';Expression={$_."employeeNumber"}},
#{Name='EmployeeName';Expression={$_."GivenName" + ' ' + $_."SN"}},
#{N='Manager';E={(Get-ADUser $_.Manager).Name}},
#{N='ManagerSAM';E={(Get-ADUser $_.Manager).samaccountname}},
#{N='ManagerEmail';E={(Get-ADUser(Get-ADUser $._samaccountname -Properties manager).manager -properties mail).mail}},
#{Name='EmployeeEmail';Expression={$_."emailAddress"}},
#{Name='Office';Expression={$_."Office"}},
#{Name='Title';Expression={$_."Title"}},
#{Name='Department';Expression={$_."Department"}},
enabled |
Export-Csv -Path C:\temp\ACP_Uers.csv -NoTypeInformation
IF I run this part manually in PowerShell it returns an Active Directory user record manually it works just fine:
(Get-ADUser(Get-ADUser chuck.east -Properties manager).manager -Properties mail).mail
File output when ran as the whole script, you can see the email is blank for the manager but it was able to get the manager and manager's sam.
"Empno","EmployeeName","Manager","ManagerSAM","ManagerEmail","EmployeeEmail","Office","Title","Department","enabled"
"8921","Chuck East","Jim Dean","jim.dean",,"Chuck.East#sb.com","East","BSA","IT","True"
Any idea as to why it's not pulling the manager's email?
#{N='ManagerEmail';E={
(Get-ADUser(
Get-ADUser $._samaccountname - Properties manager).manager -properties mail).mail
}
},
You have a typo, $._samaccountname I think. Should be $_.samaccountname
I'm not sure why you departed from the earlier pattern. This should work:
#{N='ManagerEmail';E={
Get-ADUser $_.manager -properties mail).mail
}
},
Of course, you could get the manager object once instead of three times... And per Matt's suggestion, build the object instead of using Select-Object, something like this: (untested... On my phone)
Get-ADGroupMember -identity “ACP Users” -Recursive | get-aduser -Property employeeNumber,SN, Manager, GivenName, Name,Office, Mobile, emailaddress,Department, Title, samaccountname,officephone,homephone | Foreach-Object {
$manager = Get-ADUser $_ -Properties email
$outputData = [ordered] #{
Empno=$_."employeeNumber"
EmployeeName=$_."GivenName" + ' ' + $_."SN"
Manager=$manager.distinguishedName
#etc for the other properties you want
}
New-object psobject -properties $outputData
} | Export-csv -path C:\temp\ACP_Uers.csv -NoTypeInformation

How to run Get-ADPrincipalGroupMembership as a synchronous command?

I'm trying to run a script that gets a user info from the AD. After the employee ID was provided the script gets all the user's groups and prints it as a list. After that it gets more attributes such as SamAccountName, LockedOut etc. Then it checks if the user is member of an "eTips" group.
My problem is that for some reason the output of the scripts shows not in the order that the scripts is written.
This is the code:
$EmpID = Read-Host "Enter Employee ID"
$ShowMemberOf = Read-Host "Want to see all the groups he members of (takes time...)? (y/n)"
if ($ShowMemberOf -eq "y" -or $ShowMemberOf -eq "yes") {
$User = get-aduser -Filter {EmployeeID -like $EmpID} | Select-Object -ExpandProperty SamAccountName
Write-Host "Group list:"
Get-ADPrincipalGroupMembership $User | select name
Write-Host "The rest of the user's info:"
get-aduser -Filter {EmployeeID -like $EmpID} -Properties * | Select-Object SamAccountName, PasswordExpired,
PasswordLastSet, OfficePhone, LockedOut, Enabled, CN
$MemberOfEtips = get-aduser -Filter {EmployeeID -like $EmpID} -Properties MemberOf | Select-Object -ExpandProperty MemberOf | Select-String -Pattern "etips"
if ($?) {
write-host "Member of an eTips group"
}
else {
write-host "NOT member of eTips group"
}
}
else {
Write-Host "The rest of the user's info:"
get-aduser -Filter {EmployeeID -like $EmpID} -Properties * | Select-Object SamAccountName, PasswordExpired,
PasswordLastSet, OfficePhone, LockedOut, Enabled, CN
$MemberOfEtips = get-aduser -Filter {EmployeeID -like $EmpID} -Properties MemberOf | Select-Object -ExpandProperty MemberOf | Select-String -Pattern "etips"
if ($?) {
"Member of an eTips group"
}
else {
"NOT member of eTips group"
}
}
This is the output:
Enter Employee ID: 4449871
Want to see all the groups he members of (takes time...)? (y/n): y
Group list:
The rest of the user's info:
name
----
Domain Users
SMS_USERS
dg_computingl
ManagerUsers
eTips
Member of an eTips group
As you can see the script continues to run even though the "Get-ADPrincipalGroupMembership" cmdlet wasn't complete yet. So the result is I'm getting the group list under the rest of 'the rest of the user's info' instead of under the 'Group list:'.
The second weird this is that because of that, it even doesn't run this part:
get-aduser -Filter {EmployeeID -like $EmpID} -Properties * | Select-Object SamAccountName, PasswordExpired,
PasswordLastSet, OfficePhone, LockedOut, Enabled, CN
It just skips to the part where it checks of the user is part of eTips group.
Please explain what I'm doing wrong here.
Remove Write-Host everywhere you used it, the other commands you use behave like Write-Output, this is why the order looks weird. Just put the strings you want to output on a line of their own, to have the same behavior and appropriate display.
The second Get-ADUser command does run, but I guess it simply does not produce any output, you should check it separately.
I'd rather run the if against $MemberOfEtips than $?, but that may only be a pattern unknown to me.
By default, a majority of PowerShell cmdlets are synchronous (there are specific exceptions, like jobs).