0
votes

I was trying to get all properties containing the string "home" from an AD User (HomeDirectory, HomeDrive etc.). I can make that work by doing the following based off of this post:

Get-ADUser -Identity MyUser -Properties * | Select-Object -Property "*home*"

However, this will bog down the system if I'm doing it in a for-loop since it will fetch all properties first, and then after that filter out the ones that match the string "home" anywhere in the property name.

Is there a way to do this filtering already in the Get-ADUser call to reduce the amount of information being sent? I guess the more generic question would be: is there a way in Powershell to fetch only properties of an object that matches a specific string pattern?

2

2 Answers

1
votes

You can create this pattern yourself by calling get-aduser -id myuser -properties * | % { $_.propertynames -match "home" } - doing this ONCE you can store the outcome into an array then supply this to further get-aduser calls.

$proplist=get-aduser -id myuser -properties * | % { $_.propertynames -match "home" }
get-aduser -properties $proplist
1
votes

Another approach could be to first get an array of all LDAP attribute names from the AD Schema:

function Get-ADUserAttributeNames {
    # First, get all AD user attributes defined in the Active Directory schema
    $searchBase    = (Get-ADRootDSE).SchemaNamingContext
    $schemaAttribs = (Get-ADObject -SearchBase $searchBase -Filter "name -like 'user'" -Properties MayContain,SystemMayContain |
                     Select-Object @{Name = 'Attribs'; Expression = {$_.maycontain + $_.systemmaycontain}}).Attribs

    # Next, get all created user attributes. These are not defined in the schema, but calculated when asked for
    $flagsAttribs = (Get-ADObject -SearchBase $searchBase -LDAPFilter '(systemFlags:1.2.840.113556.1.4.803:=4)' -Properties systemFlags).Name

    return ($schemaAttribs + $flagsAttribs) | Sort-Object
}
$userAttribs = Get-ADUserAttributeNames

In subsequent calls, use the returned $userAttribs array like this:

$homeAttribs = $userAttribs | Where-Object { $_ -like '*home*' }
Get-ADUser -Filter * -Properties $homeAttribs

Some explanation

This approach retrieves the list of LDAP user attribute names from the AD Schema itself, so there is no need to probe a known user. The returned attribs apply to any user object in your AD environment.

With Vesper's good answer you do need a user that you know exists, but that's no problem of course since you can simply use your own SamAccountName.

The reason I've emphasized LDAP is that Ldap attribute names are not always as self-descriptive as you would like, sometimes just one character and on other occasions ridiculously long.. That is why PowerShell maps most common atribute names to more friendly (and also case-insensitive) names.

Some examples:

LDAP                        PowerShell
----                        ----------
l                           City
o                           Organization
cn                          Name
physicalDeliveryOfficeName  Office
facsimileTelephoneNumber    Fax
wWWHomePage                 HomePage
nTSecurityDescriptor        CannotChangePassword

PowerShell in some cases also changes the format of an attribute to an easier to use format like with Enabled which returns a Boolean value from computing the LDAP userAccountControl (bit mask not 2) or PasswordLastSet which returns a DateTime object from ldap's pwdLastSet attribute.

The AD Schema can be extended with more attributes. Sometimes software does that (like Exchange that extends the schema with lots of msExch* atributes) but you (as administrator) can add new properties too. The list you get with above function is therefore quite, but not completely static and can change over time.