Tag Archives: [adsisearcher]

Working with type accelerators in PowerShell

Type accelerators are a great way in PowerShell to access .Net classes without having to write their full names. In essence they are aliases for .Net classes. If you have worked with PowerShell then you probably have used a type accelerator without knowing.

To get the list of available type accelerators the following command can be executed:

1
[psobject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Get

Depending on your version of PowerShell this will generate an output similar to this:

2016-02-26 (2)

Using the Get-TypeAccelerator function we can also display the available Type Accelerators in an easier to view way:

TypeAcc

It is useful for quickly defining objects without the complete notation of the class, for example compare the following two examples:

1
2
[System.Management.Automation.PSObject]@{'Property'='PowerShell Object'}
[pscustomobject]@{'Property'='PowerShell Object'}

Two type accelerators I use a lot are the [adsi] and [adsisearcher] Type Accelerators, this allows me to access and manipulate Active Dirclectory objects without relying on additional PowerShell modules. Here are some examples of querying Active Directory:

1
2
([adsisearcher]'samaccountname=jaap').FindOne()
[adsi]'LDAP://CN=Jaap,OU=AdminUsers,DC=JaapBrasser,DC=Com'

This allows for very short lines of code and used appropriately this can improve the readability of your code. Another few examples of type accelerators are the following:

1
2
3
4
[ipaddress]'8.8.8.8'
[version]'1.0.2.123'
[regex]::Replace('Type','e','e Accelerator')
[void] (Get-Process)

For more information on the different type and how to use them to define objects, queries or to access data you can view its article on MSDN. For example by executing the following code:

1
Start-Process -FilePath "http://social.msdn.microsoft.com/Search/en-US?query=$([psobject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Get.wmisearcher.ToString())"

There are a number of ways to use Type Accelerators in PowerShell, do you already use them and if so what are some of your favorite uses of them. Feel free to discuss them below in the comments section.

Share

Active Directory Friday: Find groups with no members

Occasionally groups may become obsolete or are never populated with members. It can be interesting to find out how many groups are in your organization that have no members, as action can be taken on it based on the output.

Overview of articles in this series
Active Directory Friday: Find groups with no members
Active Directory Friday: Principal group membership
Active Directory Friday: User account group membership

Because of the nature of how group membership is defined this article will be the first in a series of three. In this article I will show how group membership can be determined using an LDAP queries. The next article in this series will go into principal group membership and its implications and the final article will go into constructed attributes and how to work with constructed attributes, specifically the memberof attribute.

In this article I will give a a number of examples that can be used to determine which groups are empty. Using Get-ADGroup the following command can be executed to retrieve memberless groups:

Get-ADGroup -LDAPFilter '(!(member=*))'

Get-ADGroupNotMemberAnything

Alternatively the DirectoryServices.DirectorySearcher object can be used to achieve a similar result:

(New-Object DirectoryServices.DirectorySearcher -Property @{
 Filter = '(&(objectClass=group)(!(member=*)))'
 PageSize = 100
}).FindAll()

The [adsisearcher] type accelerator is another interesting alternative for this purpose, here is an example:

([adsisearcher]'(&(objectClass=group)(!(member=*)))').FindAll()

The problem with the above examples however, is that some groups will show up as being empty, for example the Domain Users group. Next week I will go into Principal group membership, what this is and how to query for this and by doing so generate more accurate results in regards to group membership.

For more information about the topics discussed in this article, please have a look at the following resources:

Active Directory Friday: Find groups with no members
Get-ADGroup
JaapBrasser.com – Active Directory Friday
Free ebook – Active Directory Friday All Articles
DirectoryServices.DirectorySearcher
Share

Free ebook – Active Directory Friday All Articles

ADF-AllArticles

The Active Directory Friday articles have proven to be quite popular among my readers and as a thank you to all my readers I decided to publish the series as an Ebook. The reason for publishing this series as an ebook is to make the content more easily accessible. The ebook is available in PDF, EPUB and MOBI formats to allow for complete portability and free choice for any device to read these articles upon. I have placed this ebook in the Books section of my blog and the download links are available below.

PDF_download Download PDF EPub_logo Download EPUB mobi Download MOBI

The ebook covers the following topics:

  • Creating Active Directory groups using PowerShell
  • Determine the forest functional level
  • Find empty Organizational Unit
  • Use the ANR filter for LDAP Queries
  • Find users with password never expires
  • Change a user’s password
  • Create new OU
  • Determine tombstone lifetime
  • Search for computers accounts
  • List password information for Domain Administrators
  • Get DistinguishedName of current domain
  • Query Group Policy Objects in Active Directory
  • Find user accounts that have not changed password in 90 days

This resource will be updated on a regular basis as new articles are published, to keep the content up-to-date with the latest articles. If you have any requests or feedback for topics to be included in this ebook or the Active Directory Friday series, please leave a comment below.

Active Directory Friday All Articles
Books
Active Directory Friday
PDF_download Download PDF
EPub_logo Download EPUB
mobi Download MOBI
Share

Get-OrphanHomeFolder – New version in TechNet Script Gallery

I received two requests for new functionality in the Get-OrphanHomeFolder script. This script compares the folder names in a specified path to existing samaccountnames. If the script does not find a match it will list the folder as a possible orphaned folder, it also displays if an account is disabled. The script is available for download in the TechNet script library: Get-OrphanHomeFolder.

A simple example of how to use this function is as follows:

.EXAMPLE 
.\Get-OrphanHomeFolder.ps1 -HomeFolderPath \\Server01\Home -FolderSize

Description:
Will list all the folders in the \\Server01\Home path. For each of these folders it will query AD using the foldername, if the query does not return an AD account or a disabled AD account an error will be logged and the size of the folder will be reported

Using more parameters specific folders can be excluded from results and all orphaned folders are moved to another folder:

.EXAMPLE    
.\Get-OrphanHomeFolder.ps1 -HomeFolderPath \\Server02\Fileshare\Home -MoveFolderPath \\Server03\Fileshare\MovedHomeFolders -ExcludePath \\Server02\Fileshare\Home\JBrasser,\\\\Server02\Fileshare\Home\MShajin -UseRobocopy 
 
Description: 
Will list all the folders in the \\Server02\Fileshare\Home folder and will move orphaned folders using robocopy, excluding JBrasser and MShajin, to \\Server03\Fileshare\MovedHomeFolders while displaying results to console 

The complete function is available in the TechNet Script Library. To view this script or to participate in the discussions about this script either comment here or in the TechNet Script Gallery. Because some of the new functionality, specifically the parameter sets and support for common parameter, the latest version of Connect-Mstsc is not compatible with PowerShell 2.0. To remedy this problem I have uploaded a PowerShell 2.0 compatible version as well.

TechNet Script Library
My entries in TechNet Script Gallery
Get-OrphanHomeFolder
Share

Active Directory Friday: Find empty Organizational Unit

As an Active Directory Administrator there are some moments, few and far in between where you might have a moment to yourself. In this article I will give you a short line of code so you can use this moment to find out if you have any empty Organizational Units in your domain. The definition of empty is an OU that does not contain any child objects. By this definition an OU containing another OU would not be considered empty. Because there is no LDAP filter for this we will take a look at how to do this using the Cmdlets and the [adsisearcher] type accelerator.

In the following example I will use Get-ADOrganizationalUnit in combination with an if-statement and Get-ADObject to gather empty OUs:

1
2
3
4
5
Get-ADOrganizationalUnit -Filter * | ForEach-Object {
	   if (-not (Get-ADObject -SearchBase $_ -SearchScope OneLevel -Filter * )) {
      		$_
   	}
}

So lets have a look at what this code does, the first portion is straight forward, gather all OUs using the Get-ADOrganizationalUnit cmdlet and pipe it into the ForEach-Object cmdlet. The if-statement is the interesting part here, I am using the Get-ADObject cmdlet to establish if this OU contains any child object, by setting the SearchBase to that OU and setting the SearchScope to OneLevel. Setting the SearchScope to OneLevel will only return direct child objects of the parent, the OU, without returning the OU itself. Because of this Get-ADObject will not return any objects if the OU is empty.

For more information about the SearchScope parameter and the possible arguments have a look at the following link: Specifying the Search Scope

Because you might not have the ActiveDirectory module loaded in your current PowerShell session it can be useful to know the [adsisearcher] alternative:

1
2
([adsisearcher]'(objectcategory=organizationalunit)').FindAll() | Where-Object {
   -not (-join $_.GetDirectoryEntry().psbase.children) }

This is a slightly different approach to illustrate a different method of gathering empty OUs, here we check the Children property part of the base object that is retrieved. The -join operator is used to ensure the -not does not evaluate the empty System.DirectoryServices.DirectoryEntries object as true.

Using the logic in this post it is also possible to filter for other specific objects contained in the OUs. For example display OUs that only have user objects, display OUs with both user and computer objects and so on.

For more information on this subject please refer to the following links:

Additional resources
Specifying the Search Scope
Get-ADObject
Get-ADOrganizationalUnit

Active Directory Friday: Use the ANR filter for LDAP Queries

ANR or Ambiguous Name Resolution is used to query for objects in Active Directory if the exact identity of an object is not known. A query containing Ambigious Name Resolution will query for all the attributes for example, Given Name, Sur Name, Display Name and samaccountname. For Windows Server 2008 and later versions this is the full list of ANR Attributes included in the search results:

For a full list of all the attributes that are queried please refer to the following TechNet article: ANR Attributes.

  • Display-Name
  • Given-Name
  • Physical-Delivery-Office-Name
  • Proxy-Addresses
  • RDN
  • SAM-Account-Name
  • Surname
  • Legacy-Exchange-DN
  • ms-DS-Additional-Sam-Account-Name
  • ms-DS-Phonetic-Company-Name
  • ms-DS-Phonetic-Department
  • ms-DS-Phonetic-Display-Name
  • ms-DS-Phonetic-First-Name
  • ms-DS-Phonetic-Last-Name

For a full list of all the attributes that are queried please refer to the following TechNet article: ANR Attributes.

An ANR query is useful in a number of scenarios, for example when relying on user input in your script. In this case querying against a samaccountname might fail if the spelling does not match the samaccountname. Similarly an export from a different department or database might be close to what is stored in Active Directory but not an exact match, again this is somewhere where an ANR query might be useful. Something that should be kept in mind is that this is a relatively expensive query and therefore should be avoided when it is not required. In this article we will discuss how to create an ANR filter and what happens exactly in such a query.

In the next example we will be using Get-ADUser cmdlet, which is part of the ActiveDirectory module, in combination with the LDAPFilter parameter in order to execute our query:

1
Get-ADUser -LDAPFilter '(anr=Jaap Brasser)'

This will query against all the attributes in the list as ‘Jaap Brasser*’ and two additionally queries: ‘GivenName=Jaap*’ and ‘SurName=Brasser*’ as well as ‘GivenName=Brasser*’ and ‘SurName=Jaap*’. As a result more than one result might be returned, as different attributes of a user account might overlap or are not unique to a single user account. This is the downside of this method of querying.

In the following example I will use the [adsisearcher] type accelerator to execute the same query:

1
([adsisearcher]'(anr=Jaap Brasser)').FindAll()

Alternatively the DirectorySearcher object can be manually created to execute a query:

$ADSearcher = New-Object DirectoryServices.DirectorySearcher -Property @{
 Filter = '(anr=Jaap Brasser)'
 PageSize = 100
}
$ADSearcher.FindAll()

For more information on this Ambiguous Name Resolution (ANR) have a look at the following resources:

Ambiguous Name Resolution
MSDN Ambiguous Name Resolution
ANR Attributes
KB Ambiguous Name Resolution for LDAP in Windows 2000
Share