{"id":5118,"date":"2012-08-16T00:01:00","date_gmt":"2012-08-16T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2012\/08\/16\/use-powershell-to-query-ad-ds-and-not-use-ldap-dialect\/"},"modified":"2012-08-16T00:01:00","modified_gmt":"2012-08-16T00:01:00","slug":"use-powershell-to-query-ad-ds-and-not-use-ldap-dialect","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-powershell-to-query-ad-ds-and-not-use-ldap-dialect\/","title":{"rendered":"Use PowerShell to Query AD DS and Not Use LDAP Dialect"},"content":{"rendered":"<p><b>Summary<\/b>: Learn how to use the <b>Filter<\/b> parameter and the Windows PowerShell Expression Language on the Active Directory module cmdlets.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Question\" \/>&nbsp;Hey, Scripting Guy! I do not know why you like ADSI so much. The syntax is obscure, and it makes things hard to read. Yesterday&rsquo;s blog that used <b>Get-ADComputer<\/b> could have been so much better if you had left out that stupid ADSI filter. What gives, Scripting Guy? You&rsquo;re not turning developer on me are you?<\/p>\n<p>&mdash;JJ<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Answer\" \/>&nbsp;Hello JJ,<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. No JJ, I am not turning developer on you, but Windows PowerShell is a great way to allow one to get in touch with their &ldquo;inner developer.&rdquo; I have been writing code for a very long time. Back when I bought my first computer (<a href=\"http:\/\/en.wikipedia.org\/wiki\/Osborne_1\" target=\"_blank\">an Osborne<\/a>), if I wanted a program to do something like balance a check book, I had to write it myself. It was a great way to learn programming (if somewhat error prone and slow). Since then, I have written everything from assembly (at the University) through C++. Truly and honestly though, Windows PowerShell is the most fun. Even though I can write code, I do not consider myself a developer. In my heart-of-hearts, I am an IT Pro and <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2010\/08\/28\/change-colors-used-by-the-windows-powershell-ise.aspx\" target=\"_blank\">a hardware geek<\/a>.<\/p>\n<h2>Reuse LDAP queries from other scripting languages<\/h2>\n<p>So what is the deal with using ADSI and LDAP? For one thing, it is standard. My early experience with messaging systems was all <a href=\"http:\/\/en.wikipedia.org\/wiki\/X.500\" target=\"_blank\">X.500<\/a> based, and from there, it is a short hop to LDAP. Familiarity with LDAP dialect permits one to easily use some of the many examples of LDAP dialect and ADO to query Active Directory on the Scripting Guys Script Repository. It is trivial to &ldquo;steal&rdquo; the LDAP query and plug it in to <b>Get-ADComputer<\/b> or <b>Get-ADObject<\/b>, regardless of the native language of the original script. As an example of this, consider the VBScript, <a href=\"http:\/\/gallery.technet.microsoft.com\/scriptcenter\/0f64a5b7-87cb-48d7-8243-0f77c58bd60b\" target=\"_blank\">Search for User Phone Numbers Beginning with 425<\/a><i>, <\/i>on the Scripting Guys Script repository. The essence of this 20 line script is shown here.<\/p>\n<p style=\"padding-left: 30px\">objCommand.CommandText = _<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; &#8220;&lt;LDAP:\/\/dc=fabrikam,dc=com&gt;;(&amp;(objectCategory=User)&#8221; &amp; _<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;(telephoneNumber=425*));Name;Subtree&#8221;&nbsp;&nbsp;<\/p>\n<p>I take the filter portion of the script and I end up with the following LDAP filter.<\/p>\n<p style=\"padding-left: 30px\">&#8220;(&amp;(objectCategory=User)(telephonenumber=425*))&rdquo;<\/p>\n<p>This filter is exactly what I need when I plug it in to the <b>LDAPFilter<\/b> parameter of the <b>Get-ADUser<\/b> cmdlet.&nbsp; In fact, the hard part was already done when I found the LDAP dialect ADO query in the previous VBScript&mdash;not to mention the cool factor of taking a 20-line VBScript and shrinking it to a single Windows PowerShell line as shown here.<\/p>\n<p style=\"padding-left: 30px\">Get-ADUser -LDAPFilter &#8220;(&amp;(objectCategory=User)(telephonenumber=425*))&#8221;<\/p>\n<h2>Query Active Directory without LDAP<\/h2>\n<p>One problem with using the <b>filter<\/b><i> <\/i>parameter instead of an LDAP filter is having to learn a new filter syntax. (Of course, all the examples in <a href=\"http:\/\/en.wikipedia.org\/wiki\/Backus%E2%80%93Naur_Form\">Backus-Naur Form<\/a> do not really help the average IT Pro much with this learning task). Another problem with using the <b>filter<\/b><i> <\/i>parameter is that generally the syntax is more work than the corresponding LDAP filter. For example, the query to find users with phone numbers that begin with 425 is shown here.<\/p>\n<p style=\"padding-left: 30px\">Get-ADUser -Filter {(objectCategory -eq &#8220;User&#8221;) -and (TelephoneNumber-like &#8220;425*&#8221;)}<\/p>\n<p>You can see that the syntax is similar to the LDAP filter, but it uses the Windows PowerShell operators instead of the LDAP operators. In addition, the quotation marks are required.<\/p>\n<p>To rewrite the LDAP query that returns only servers, I would use the command shown here.<\/p>\n<p style=\"padding-left: 30px\">Get-ADComputer -Filter {(objectcategory -eq &#8220;computer&#8221;) -AND (OperatingSystem -like &#8216;*server*&#8217;)}<\/p>\n<p>One thing to keep in mind is that the <b>filter<\/b><i> <\/i>parameter does not support Regular Expressions in the filter. Therefore, I cannot use the following command because it generates an error.<\/p>\n<p style=\"padding-left: 30px\">Get-ADComputer -Filter {(objectcategory -eq &#8220;computer&#8221;) -AND (OperatingSystem -match &#8216;server&#8217;)} -Properties operatingsystem<\/p>\n<p>The command and the error message are shown here.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1803.HSG-8-16-12-01.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1803.HSG-8-16-12-01.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>The following table lists the supported filter operators.<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"319\" valign=\"top\">\n<p><b>Operator<\/b><\/p>\n<\/td>\n<td width=\"319\" valign=\"top\">\n<p><b>Meaning<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"319\" valign=\"top\">\n<p>Eq<\/p>\n<\/td>\n<td width=\"319\" valign=\"top\">\n<p>equal<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"319\" valign=\"top\">\n<p>Le<\/p>\n<\/td>\n<td width=\"319\" valign=\"top\">\n<p>Less than or equal<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"319\" valign=\"top\">\n<p>Ge<\/p>\n<\/td>\n<td width=\"319\" valign=\"top\">\n<p>Greater than or equal<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"319\" valign=\"top\">\n<p>Ne<\/p>\n<\/td>\n<td width=\"319\" valign=\"top\">\n<p>Not equal<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"319\" valign=\"top\">\n<p>Lt<\/p>\n<\/td>\n<td width=\"319\" valign=\"top\">\n<p>Less than<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"319\" valign=\"top\">\n<p>Gt<\/p>\n<\/td>\n<td width=\"319\" valign=\"top\">\n<p>Greater than<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"319\" valign=\"top\">\n<p>Approx.<\/p>\n<\/td>\n<td width=\"319\" valign=\"top\">\n<p>Approximently<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"319\" valign=\"top\">\n<p>Bor<\/p>\n<\/td>\n<td width=\"319\" valign=\"top\">\n<p>Boolean or<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"319\" valign=\"top\">\n<p>Band<\/p>\n<\/td>\n<td width=\"319\" valign=\"top\">\n<p>Boolean and<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"319\" valign=\"top\">\n<p>Recursivematch<\/p>\n<\/td>\n<td width=\"319\" valign=\"top\">\n<p>Recursive match<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"319\" valign=\"top\">\n<p>Like<\/p>\n<\/td>\n<td width=\"319\" valign=\"top\">\n<p>Wild card like<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"319\" valign=\"top\">\n<p>Notlike<\/p>\n<\/td>\n<td width=\"319\" valign=\"top\">\n<p>Wild card not like<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"319\" valign=\"top\">\n<p>And<\/p>\n<\/td>\n<td width=\"319\" valign=\"top\">\n<p>And<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"319\" valign=\"top\">\n<p>Or<\/p>\n<\/td>\n<td width=\"319\" valign=\"top\">\n<p>Or<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"319\" valign=\"top\">\n<p>Not<\/p>\n<\/td>\n<td width=\"319\" valign=\"top\">\n<p>Not<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>JJ, that is all there is to using the <b>filter<\/b><i> <\/i>parameter to query Active Directory and to not use LDAP dialect.&nbsp; Join me tomorrow for more Windows PowerShell cool stuff. Until then, peace.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow.<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Learn how to use the Filter parameter and the Windows PowerShell Expression Language on the Active Directory module cmdlets. &nbsp;Hey, Scripting Guy! I do not know why you like ADSI so much. The syntax is obscure, and it makes things hard to read. Yesterday&rsquo;s blog that used Get-ADComputer could have been so much better [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[7,3,8,45],"class_list":["post-5118","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-scripting-guy","tag-searching-active-directory","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Learn how to use the Filter parameter and the Windows PowerShell Expression Language on the Active Directory module cmdlets. &nbsp;Hey, Scripting Guy! I do not know why you like ADSI so much. The syntax is obscure, and it makes things hard to read. Yesterday&rsquo;s blog that used Get-ADComputer could have been so much better [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/5118","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=5118"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/5118\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=5118"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=5118"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=5118"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}