i am trying to get the following fields from AD using powershell - powershell

Import-Module activedirectory
$Name = "Larry Page"
$Searcher = [ADSISearcher]"(&(objectCategory=person)(objectClass=user)(cn=$Name))"
[void]$Searcher.PropertiesToLoad.Add("sAMAccountName")
$Results = $Searcher.FindAll()
ForEach ($User In $Results)
{
$NTName = $User.Properties.Item("sAMAccountName")
$CompanyName = $User.Properties.Item("company")
$NTName + " " + $CompanyName
[string]$userName = $NTName.properties.name
Get-ADUser "L2371732" -Properties company,PasswordExpired, PasswordLastSet, PasswordNeverExpires
}
This is my code so far. I am trying to substitute $userName for L2371732 in the following line but I am getting a different error so I hard coded the username in the Get-ADUser.
I only wan the fields I specified however I am getting everything (company, distinguishedname,enabled, etc)

Just trying to focus on the title portion of the question.
As per documentation -Properties does the following:
Specifies the properties of the output object to retrieve from the server. Use this parameter to retrieve properties that are not included in the default set.
So you would be seeing what you asked for in addition to the default set. If you don't want those properties you can drop the by piping to Select-Object and ask for only what you need.
$props = 'company', 'PasswordExpired', 'PasswordLastSet', 'PasswordNeverExpires'
Get-ADUser "L2371732" -Properties $props | Select-Object $props
If you wanted a default property returned as well e.g. samaccountname you can add that to the list with no issue.

Related

Exporting last logon date for inactive users via PowerShell

I have a command that will export a list of users who have logged in for 12 months but I am struggling to export the last login date and time.
The command is as follows:
Search-ADAccount –AccountInActive -UsersOnly –TimeSpan 365:00:00:00 –ResultPageSize 2000 –ResultSetSize $null |?{$_.Enabled –eq $True} | Select-Object Name, SamAccountName, DistinguishedName, lastLogon| Export-CSV “C:\Users\Me\Desktop\InactiveUsers.CSV” –NoTypeInformation
But lastLogon is showing a blank in the CSV file.
I am new to PowerShell I understand the command can be made much smoother.
Any help on this is much appreciated.
Search-ADAccount doesn't have an option to pull other attributes from the AD Objects than the default ones, you can use Get-ADUser with an elaborate filter to query the users who haven't logged on for the past year. One option is to query the user's lastLogonTimeStamp attribute however by doing so you're risking not getting accurate results because this attribute is not replicated in real time. To get accurate one must query the user's lastLogon attribute but, since this attribute is not replicated across the Domain, one must query all Domain Controllers to get the latest logon from the user.
For more information on this topic, please check this excellent TechNet Article: Understanding the AD Account attributes - LastLogon, LastLogonTimeStamp and LastLogonDate.
$dateLimit = [datetime]::UtcNow.AddYears(-1).ToFileTimeUtc()
$AllDCs = Get-ADDomainController -Filter *
$logons = #{}
$params = #{
LDAPFilter = -join #(
"(&" # AND, all conditions must be met
"(!samAccountName=krbtgt)" # exclude krbtgt from this query
"(!samAccountName=Guest)" # exclude Guest from this query
"(userAccountControl:1.2.840.113556.1.4.803:=2)" # object is Disabled
"(lastLogon<=$dateLimit)" # lastLogon is below the limit
")" # close AND clause
)
Properties = 'lastLogon'
}
foreach($DC in $AllDCs) {
$params['Server'] = $DC
foreach($user in Get-ADUser #params) {
# this condition is always met on first loop iteration due to ldap filtering condition
if($logons[$user.samAccountName].LastLogon -lt $user.LastLogon) {
$logons[$user.samAccountName] = $user
}
}
}
$logons.Values | ForEach-Object {
[PSCustomObject]#{
Name = $_.Name
SamAccountName = $_.SamAccountName
DistinguishedName = $_.DistinguishedName
lastLogon = [datetime]::FromFileTimeUtc($_.lastLogon).ToString('u')
}
} | Export-CSV "C:\Users\Me\Desktop\InactiveUsers.CSV" -NoTypeInformation

How to handle hyphenated names in powershell when getting active directory info

I'm trying to get the password expiration date in active directory using powershell for users with hyphenated names (IE firstname.last-name) and on the hyphenated names it gives an invalid cmdlet error. How do I query the hyphenated names?
The current command I have is
net user $username /DOMAIN | find "Password expires"
Maybe use the ActiveDirectory module instead of the net commands:
$MaxPwdAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge.Days
Get-ADUser -Filter { Name -like "*-*" } -Properties 'PasswordLastSet', 'DisplayName' |
Select-Object Name,DisplayName,
#{ Name = 'PasswordExpires'; Expression = { $_.PasswordLastSet.AddDays( $MaxPwdAge ) } }
If needed You can change the filter to look at DisplayName instead -Filter { DisplayName -like "*-*" }
You may need to adjust the properties you're retrieving depending on what you want to include in the output. This is just an example but it works, and can be used to plot a path forward. It does seem like you have to calculate the expiration date. But I can work on that and see if there's a better way.
If you want to Query for a specific user:
Get-ADUser Name-Name -Properties 'PasswordLastSet',DisplayName |
Select-Object Name,DisplayName,
#{ Name = 'PasswordExpires'; Expression = { $_.PasswordLastSet.AddDays( $MaxPwdAge ) } }
This assumes the Hyphenated name is a samAccountName. If you need to search by DisplayName you'll have to resort back to filter, even if you are looking for only the one user.
Get-ADUser -Filter { DisplayName -eq "Name-Name" } -Properties 'PasswordLastSet',DisplayName |
Select-Object Name,DisplayName,
#{ Name = 'PasswordExpires'; Expression = { $_.PasswordLastSet.AddDays( $MaxPwdAge ) } }
Note: That you have to change the "Name-Name". Also in the last example I changed to using the -eq operator instead of -like. Obviously this assumes you know exactly what you're looking for. Though you can use -Like with DisplayName or even the surName attribute if you like.

ADUser search: Get-ADUser and DirectorySearcher

With PowerShell, I'm trying to get an ADUser account with Get-ADUser with LdapFilter using the employeeid attribute. I'm using a GC server of the domain as the sourcing server for faster results. However, I'm not getting the matching ADUser account(s). However, I'm able to retrieve results using a DirectorySearcher object. Please refer to the tried code snippets below,
###
#1 DirectorySearcher
$empid = "123456"
$ldapcn = "GC://dc=mydomain,dc=net"
$ldapfilter = "(&(ObjectCategory=Person)(objectclass=user)(employeeid=" + $empid + "))"
$objent = new-object System.DirectoryServices.DirectoryEntry($ldapcn)
$objsearch = new-object System.DirectoryServices.DirectorySearcher
$objsearch.SearchRoot = $objent
$objsearch.SearchScope = "subtree"
$objsearch.Filter = $ldapfilter
$objsearch.pagesize = 1000
$properties = "employeeid","givenname","sn","samaccountname"
$objsearch.propertiestoload.addrange($properties)
$results = $objsearch.Findall()
# Working
# $results contains matching user records
######################################################
#2 Get-ADUser
$empid = "123456"
$Server_AD_GC = (Get-ADDomainController -Server mydomain.net | select -exp hostname) + ":3268"
$ldapfilter = "(&(ObjectCategory=Person)(objectclass=user)(employeeid=" + $empid + "))"
$results = Get-ADUser -LdapFilter $ldapfilter -Properties employeeid, givenname, sn, samaccountname -Server $Server_AD_GC
# NOT WORKING!
# $results DOES NOT CONTAIN matching user records
What am I missing here?! Any help would be highly appreciated.
UPDATE 1
I just verified the Partial Attribute Set (PAS) with the code below and DO NOT SEE employeeid included in the list
$Domain = "mydomain.net"
# $schemaNamingContext = "cn=Schema,cn=Configuration,dc=mydomain,dc=net"
$schemaNamingContext = (Get-ADRootDSE -Server $Domain).SchemaNamingContext
Get-ADObject -SearchBase $schemaNamingContext -LDAPFilter "(isMemberOfPartialAttributeSet=TRUE)" -Properties ldapDisplayName | Select ldapDisplayName | sort ldapDisplayName
For more background, I'm running the 'DirectorySearcher' code block to search the source mydomain.net and running it from a W2012R2 server joined to a trusted domain, say mycaller.net, which is from a different forest. Importantly, the calling trusted domain mycaller.net's PAS CONTAINS employeeid. However, as already said Get-ADUser is unable to fetch the record(s).
Below is a screenshot of results observed with different environments,
Now, if not for a solution, I'd be glad if at least someone is able to reproduce this behavior.
Query:
In my example,
DirectorySearcher's $ldapcn = "GC://DC=mydomain,DC=net"
vs
Get-ADUser's $Server_AD_GC = (Get-ADDomainController -Server $Domain | select -exp hostname) + ":3268"
I expected both to work in a similar fashion. I see that I haven't specified a host for DirectorySearcher but have given one for Get-ADUser. Is this something to be looked into?

Multiple rows in a grid [duplicate]

This question already has answers here:
Export hashtable to CSV with the key as the column heading
(2 answers)
Closed 4 years ago.
I'm trying to list all ad group memberships of specific users. The input would be a string of logins split with a comma 'login1,login2'.
So I go over each user and list their memberships with the username as title. Somehow it only shows the first entry. Also it shows the user groups in one row and I don't know how to change that.
Code below:
$users = $logon -split ','
$q = #()
foreach ($user in $users) {
$usernm = Get-ADUser -Filter 'samAccountName -like $user' | select Name
$useraccess = Get-ADPrincipalGroupMembership $user | Select-Object Name
$userobj = New-Object PSObject
$userobj | Add-Member Noteproperty $usernm.Name $useraccess.Name
$q += $userobj
}
Expected output would be something like:
fullnameuser1 fullnameuser2 list of users goes on...
------------- ------------- ------------------------
adgroup1 adgroup3 ...
adgroup2 adgroup4
... ...
In principle this would also mean that if i typed $q.'fullnameuser1' output would be:
fullnameuser1
-------------
adgroup1
adgroup2
...
Whenever the code is ran, it will only ever add the first user's access, also returning all groups on one row. So somehow I need to go over all the group memberships and add a row for each one.
First and foremost, PowerShell does not expand variables in single-quoted strings. Because of that Get-ADUser will never find a match unless you have a user with the literal account name $user. Also, using the -like operator without wildcards produces the same results as the -eq operator. If you're looking for an exact match use the latter. You probably also need to add nested quotes.
Get-ADUser -Filter "samAccountName -eq '${user}'"
Correction: Get-ADUser seems to resolve variables in filter strings by itself. I verified and the statement
Get-ADUser -Filter 'samAccountName -eq $user'
does indeed return the user object for $user despite the string being in single quotes.
If you want a fuzzy match it's better to use ambiguous name resolution.
Get-ADUser -LDAPFilter "(anr=${user})"
You may also want to avoid appending to an array in a loop, and adding members to custom objects after creation. Both are slow operations. Collect the loop output in a variable, and specify the object properties directly upon object creation.
$q = foreach ($user in $users) {
...
New-Object -Type PSObject -Property {
$usernm.Name = $useraccess.Name
}
}
Lastly, I'd consider using the user's name as the property name bad design. That would be okay if you were building a hashtable (which is mapping unique keys to values), but for custom objects the property names should be identical for all objects of the same variety.
New-Object -Type PSObject -Property {
Name = $usernm.Name
Group = $useraccess.Name
}
Basily query all the users and store it in $users, example:
Get-ADUser -Filter * -SearchBase "dc=domain,dc=local"
And then you can export the results as csv or a table.
To Export as CSV :
Get-ADPrincipalGroupMembership <Username> | select name, groupcategory, groupscope | export-CSV C:\data\ADUserGroups.csv`
To Format the result as Table in the console itslef :
Get-ADPrincipalGroupMembership <Username> | select name, groupcategory, groupscope | Format-Table

How to find *where* in ActiveDirectory an attribute is stored?

I want to use Power Query to extract a list of employee names including attributes such as username, telephone number, office number, etc.
I found an article that shows how to do just that:
http://datapigtechnologies.com/blog/index.php/pull-your-global-address-book-into-excel/
However, my question is: if I wanted to return an attribute that I know that exists, but I haven't a clue where in the Active Directory object/table model it resides, how might one perform a search to find the specific table & attribute that must be queried?
EDIT - Additional Information
"Is this more of a PowerQuery question that a PowerShell question" - I think the answer is both yes and no.
This command:
Get-ADUser <someValidUserName> - Property *
...does indeed output all the attributes for the specified user. However, as far as I can tell there is no indication in the output as to where in the AD object hierarchy each attribute resides.
From the Power Query article linked above, we see several "tables" noted in the Power Query interface to Active Directory. One such table is organizationalPerson which contains an attribute named physicalDeliveryOfficeName. It would seem that the notion of an organizationalPerson "object" isn't exclusive to Power Query, as it seems to correspond to the Ldap-Display-Name as documented here:
https://msdn.microsoft.com/en-us/library/ms683883(v=vs.85).aspx
So what I was hoping for was a means to wildcard search the AD attribute names themselves for the existence of the word "office" anywhere within any attribute name in the AD user hierarchy, and for the search results to return physicalDeliveryOfficeName as a result, including the fact that it resides within organizationalPerson
(Hopefully that makes the question a bit more clear?)
For posterity: Here is a PowerShell script (See Get Class Attributes) that will list all Active Directory classes + class attributes for a specified SamAccountName. From the list of attributes, you can then run something like the following to get the attribute values
#make a list of desired class attributes
$Properties = #('DisplayName', 'SamAccountName', 'mail', 'otherMailbox')
Get-ADUser -Filter * -SearchBase "dc=myDomain,dc=gov" -Properties $Properties | select $Properties
Credit to: http://virot.eu/getting-all-possible-classes-attributes-for-a-ad-object/
Get Class Attributes
#Run on Win 7 machine with PS 4.0 against A.D. running on a Win 2008 R2 domain controller
cls
$attributeList = New-Object System.Collections.ArrayList
$attributeListItem = [ordered]#{}
Import-Module ActiveDirectory
#Get an AD User and request objectClass
$aDObj = Get-ADUser "MyAccountName" -Properties objectClass
#get all class names
$nextClass = $aDObj.ObjectClass
$allClasses = Do
{
$currentClass = $nextClass
$nextClass = Get-ADObject -SearchBase "$((Get-ADRootDSE).SchemaNamingContext)" -Filter {lDAPDisplayName -eq $nextClass} -properties subClassOf | Select-Object -ExpandProperty subClassOf
$currentClass
}
While($currentClass -ne $nextClass)
#Get all attributes
$mandatoryAndOptionalAttributes = 'MayContain','MustContain','systemMayContain','systemMustContain'
ForEach ($class in $allClasses)
{
$classInfo = Get-ADObject -SearchBase "$((Get-ADRootDSE).SchemaNamingContext)" -Filter {lDAPDisplayName -eq $class} -properties $mandatoryAndOptionalAttributes
ForEach ($mandatoryAndOptionalAttribute in $mandatoryAndOptionalAttributes)
{
foreach ($classAttribute in $classInfo.$mandatoryAndOptionalAttribute)
{
$attributeListItem."Mandatory/Optional Attribute" = $mandatoryAndOptionalAttribute
$attributeListItem."Class" = $classInfo.Name
$attributeListItem."Class Attribute" = $classAttribute
$attributeList.add((New-Object PSObject -Property $attributeListItem)) | out-null
}
}
}
$attributeList | out-gridview -title ("All Class Attributes: " + $attributeList.count)