Grabbing lots of data and passing it to CSV from mutiple dependent Get-Aduser queries - powershell

We have users with minor but annoying differences in naming standards that are loosely followed making scripting a pain. The company has been around a while and depending on who was working in IT when the employee was hired the account could follow any naming convention if followed at all.
In one forest we have accounts that start with a-, the manager attribute of that account is the DN of the account owners other/main account without many other common attributes populated. I then need to look up the managers account and grab their SamAccountName. Then I need to add s- to the SamAccountName and do search for that to see if it exists.
Then I need to write the original SamAccountName, the second SamAccountName and the s-SamAccountName and something like a check box if its a valid account name all to a CSV.
without rewriting the script and passing everything to/from a var and then processing that I dont see a way to do it. This script looks up roughly 800 users and processes that three time, so it already takes a while to run without slowing it down with a bunch of var transfers.
$test = get-aduser -ldapFilter "(SamAccountName=a-*)" -Server XXX.int:3268 -Properties manager |
Select -ExpandProperty manager | Get-ADUser -Server XXX.int:3268 |
Select -ExpandProperty samaccountname
$test

You can do something like this to get you started.
$test = get-aduser -ldapFilter "(SamAccountName=a-*)" -Server XXX.int:3268 -Properties manager |
Select-Object SamAccountName,
#{n='Manager';e={Get-ADUser $_.Manager -Server XXX.int:3268 | Select -Expand SamAccountName}},
#{n='s-Manager';e={Get-ADUser "s-$($_.Manager)" -Server XXX.int:3268 | Select -Expand SamAccountName}}
$test
I am not clear if you need to add s- to the manager's or the original account's SamAccountName. The script above adds s- to the manager's SamAccountName.
In scripts where multiple AD lookups are required, sometimes it is best to do one larger lookup and then filter that result for what you need.
Explanation:
The main technique of the script makes use of delayed-script binding with the Select-Object command. Each user object found by the original Get-ADUser command is piped into Select-Object and is accessible by the pipeline variable $_. The hash table select can be updated fairly easily to meet your needs.

Related

Finding out if the same property occurs on multiple AD users

I'm pretty new on Powershell and this is by far the trickiest task I have gotten so far. I want to write a script that shows me if the same personal identity number occurs on multiple AD users.
I have managed to get a list of all AD users and their ID numbers using the Powershell Active Directory module and the following:
Get-ADUser -Filter * -SearchBase "OU=X,DC=X,DC=X,DC=X" -Properties PersonalIdentityNumber | Select-Object Name,PersonalIdentityNumber | Where-Object {$_.PersonalIdentityNumber} | Sort-Object -Property PersonalIdentityNumber
Although, I am not sure where to go from there. I suspect that I will have to use a for or foreach loop in some way, but I have tested a bit and not made any concluions. It will most likely be too heavy to compare every user against all other users, but I think that every user can be compared to the 20 users before or after, since matching ID numbers will probably be on users with the same name.
Any ideas on how to accomplish this?
Use the Group-Object cmdlet to group the users based on the value of the PersonalIdentityNumber property:
$usersWithPIN = Get-ADUser -Filter * -SearchBase "OU=X,DC=X,DC=X,DC=X" -Properties PersonalIdentityNumber | Select-Object Name,PersonalIdentityNumber | Where-Object {$_.PersonalIdentityNumber}
$usersWithSamePINGroups = $usersWithPIN |Group-Object PersonalIdentityNumber |Where-Object Count -gt 1
$usersWithSamePINGroups will now contain zero or more Group objects with a Count property (the number of users sharing a given PIN), and a Group property containing the user objects in question

AD GUI shows properties that PowerShell returns empty

I want to get a list of all AD Users and their creation time and last logon time. First I used the Active Diretory Users and Computers app and activated the Advanced Features. In the Attribute Editor I can see the properties are called LastLogon and WhenCreated.
So I did this:
$allUsers = Get-ADUser -Filter * -Properties SamAccountName,LastLogon,WhenCreated
$allUsers | select SamAccountName,LastLogon,WhenCreated
However LastLogonand WhenCreated are only filled for 13 of 500 Users. In the Attribute Editor these values are filled for a lot more...
When I query one user only that has these values in the Attribute Editor with Get-ADUser -Identity $User -Properties * I see that the attributes are called LastLogonDateand Created (values are shown empty).
So I searched for those attributes:
$allUsers2= Get-ADUser -Filter * -Properties SamAccountName,LastLogonDate,Created
$allUsers2 | select SamAccountName,LastLogonDate,Created
Then again those 13 have the info the rest doesn't.
Has anyone an idea how I get those values? (I am going to export them with Export-CSV so another way to get those in Excel is ok, too )
As requested my comments as answer.
First attempt:
Add the -Server switch on Get-ADUser and have it query the same Domain Controller you are currently connected to with Active Directory Users and Computers. It may be that you are asking for properties that have not yet been synchronized (especially the lastLogon time stamp which I believe is synced only once every 14 days unless you have specified a different value for the ms-DS-Logon-Time-Sync-Interval attribute on the domain default naming context.)
--> didn't apply because you're running this on the DC itself
Second attempt:
Try ADSI as in $searcher = [adsisearcher]'(&(objectCategory=person)(objectClass=user))'; $searcher.FindAll()
--> same results as with Get-ADUser; still empty values
Third attempt:
Check PowerShell version(s)
--> apparently the DC had PS version 4. With version 5.1 it works
First, look at what properties your cmdlet has:
$a = Get-ADUser -server 'DomenNameTest.en' -Identity 'makarovayu' -Properties *
$a | Get-Member
I recommend copying the received data into a notepad in order to copy the available field names later.
2-Let's declare an array and use the cmdlet to try to collect information on the required fields
$userList = Get-ADUser -server 'DomenNameTest.en' -Properties SamAccountName,Name -Filter * |
#Do not forget that the comanlet has a limitation and can fall off on timeout.See how I work with each property in [select]
Select #{Name = "SamAccountName"; Expression={$_.SamAccountName}},#{Name = "Name"; Expression={$_.Name}} |
#Uploading data to [csv]
Export-Csv -Path "D:\Users\userTest\Desktop\userList.csv" -Append -NoTypeInformation -Encoding Default -Delimiter ';'
Remove-Variable a,userList #Clear the variables

I need a more specific Powershell command to isolate Active Directory names, usernames, and last login date from users on a domain

I'm an IT intern tasked with performing an audit of users on our domain and I'm having some trouble finding the info I need without all of the extra stuff. Is there a way to pull all of this info in one command? If not, can you recommend commands to pull users, usernames, and login info separately in a manner that I can copy-paste in the format I need?
I previously used get-adgroup -filter * and wrote to a file. Are there some options I can add for this filter? I also used a script to get all users, and all groups and their user permissions on separate occasions.
You could try something like:
Get-ADGroup -Filter "Name -like '*Accounting*'" |
Get-ADGroupMember |
Select-Object name, SamAccountName
Or if you need more fields from the user object, then try something like:
Get-ADGroup -Filter "Name -like '*Accounting*'" |
Get-ADGroupMember |
Get-ADUser -Properties Enabled |
Select-Object Name, SamAccountName, UserPrincipalName, Enabled
You'll probably want to export to a spreadsheet, so use Export-Csv for that.

Using PowerShell how can I search and filter an array of exported Active Directory users like I can with Get-ADUser?

I have a PowerShell script that compares the contents of a CSV file with Active Directory. The CSV file contains a list of demographic information of people already in AD. One of the columns is "emplid". The values in this field correspond to the values of the "employeeID" attribute of user objects in AD. So, I currently use this "emplid" property to cross reference AD and find the corresponding user accounts. To do this I use a line similar to this:
$UserAccounts = $ListOfEmloyeeIDs | ForEach-Object {Get-ADUser -Properties * -Filter {employeeID -Eq $_}}
I then use this to add those user accounts to a security group:
$UserAccounts.SamAccountName | ForEach-Object {Add-ADGroupMember -Identity SpecialSecurityGroup -Members $_}
The problem is with the first line. There are thousands of user accounts and the script can take hours to run. This has also led to complaints from the AD admins. What I would like to do is load all active AD users into a variable (which takes less than 2 minutes to run) using:
$ADPeopleActive = Get-ADUser -SearchBase "OU=People,DC=MyAD,DC=com" -Properties EmployeeID -Filter {Enabled -Eq $True}
Then I would like to do my cross reference against this array and build a list of SamAccountNames to feed to something like my second line to populate my security group.
My problem is I can't figure out a way to do this cross reference against an array that I've built the same way I can cross reference with AD using Get-ADuser. Can anyone help?
Something like
$UserAccounts = $ADPeopleActive| Where-Object { $ListOfEmloyeeIDs -contains $_.EmployeeID }
?

Import Member Group attribute from AD to .csv

I am using ActiveRoles Management Shell under Windows XP , Powershell ver 2 for retreiving Group data from AD and exporting it to csv file.Everything works well apart from getting member list it is so long that the program is writing in excel cells under member column System.String[] each time.How can I make it write whole list there , is it possible ? I could actually have only the name of the member don't need whole connection path.Is there a possibility to get from group field member only name ?
get-QADGroup -SearchRoot 'ou=User,ou=Groups,ou=PL,dc=test,dc=com'| Select-Object -property name,sAMAccountName,description,groupType,member|Export-Csv -path Y:\csv\groups.csv
Ok, as Matt suggested you want an expression in your Select statement. I would use something like this:
#{l="Members";e={$_.Members -join ", "}}
Which when inserted into your one-liner looks like:
get-QADGroup -SearchRoot 'ou=User,ou=Groups,ou=PL,dc=test,dc=com'| Select-Object -property name,sAMAccountName,description,groupType,#{l='Members';e={$_.member -join ", "}}|Export-Csv -path Y:\csv\groups.csv -NoTypeInfo
I also added -NoTypeInfo to the export to skip the annoying lead line telling you it's a PSCustomObject or some such and actually just get your data (and headers).
I don't have access to the quest cmdlets so I will provide a solution based on cmdlets from the activedirectory
Get-ADUser -Filter * -SearchBase "OU=Employees,DC=Domain,DC=Local" -Properties memberof |
Select-Object name,#{Name="Groups";Expression={$_.MemberOf |
ForEach-Object{(Get-ADGroup -Identity $_).Name + ";"}}} |
Export-Csv C:\temp\TEST.CSV -Append
To make sense of this by line:
Should be self explanatory. Get all users in the OU defined. You would need to change this to suit your needs.
The select statement appears normal until you reach the calculated property Groups.
What continues from the previous line is cycling through every group that an individual user is a memberof and get the friendly name of the group (MemberOf returns DistinguishedName's). At the end of every group add a ";" as to not interfere with the CSV that will be made later.
Append to a csv file.
For brevity I didnt include all the extra properties that you included in your Select-Object statement. You would obviously need to add those back as the need fits.
Since you have the use the Quest cmdlets you could just change member in your select statement to the following:
#{Name="Groups";Expression={$_.member | ForEach-Object{"$_;"}}}
I cannot test if this will work. It is based on the assumption that member contains a simple name as supposed to a distinguishedname