{"id":5127,"date":"2012-08-14T00:01:00","date_gmt":"2012-08-14T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2012\/08\/14\/the-ins-and-outs-of-using-dsquery-with-windows-powershell\/"},"modified":"2012-08-14T00:01:00","modified_gmt":"2012-08-14T00:01:00","slug":"the-ins-and-outs-of-using-dsquery-with-windows-powershell","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/the-ins-and-outs-of-using-dsquery-with-windows-powershell\/","title":{"rendered":"The Ins and Outs of Using DSQuery with Windows PowerShell"},"content":{"rendered":"<p><b>Summary<\/b>: Microsoft Scripting Guy, Ed Wilson, talks about using DSQuery to return results for use in Windows PowerShell.<\/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! &nbsp;I like using the DSQuery tool to search Active Directory Domain Services (AD DS). Can I use that tool with Windows PowerShell?<\/p>\n<p><span class=\"Apple-tab-span\"> <\/span>&mdash;WS<\/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 WS,<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Yes, it is possible, but I think that there are problems with using the DSQuery tool from within Windows PowerShell. The problems come from the nature of the DSQuery tool itself, and not from within Windows PowerShell. If you are good at using <b>DSQuery<\/b> and <b>DSGet<\/b>, you might not have any problems, but personally, I think there are easier methods. I wrote a Hey, Scripting Guy! Blog called <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2010\/12\/02\/query-active-directory-without-writing-a-script.aspx\" target=\"_blank\">Query Active Directory Without Writing a Script<\/a>; and in that blog, I discuss different methods of querying AD DS. You can refer to that blog for additional information about the tools.<\/p>\n<h2>The bad thing about DSQuery<\/h2>\n<p>The bad thing about it is not so much a limitation of <b>DSQuery<\/b>, as it is a limitation of all such command-line utilities. It returns strings; therefore, if the output is not exactly to my liking, I have to do string manipulation&mdash;and personally, I hate string manipulation. I have always hated string manipulation&mdash;from the VBScript days, and even back into the days of CPM. String manipulation simply is not &ldquo;my thing.&rdquo;<\/p>\n<p>Another bad thing about <b>DSQuery<\/b> is that it is not installed by default, and the only way to get it on my laptop running Windows 8 is to download and to install the Remote Server Administration Tools (RSAT), which is yet to be released. A bad thing about the RSAT is that it is version specific, and even service pack specific. In Windows 7, I had to uninstall the RSAT, install Service Pack 1, then reinstall the RSAT. Of course, I did not find that out until after the service pack installation failed. So, I am always a little leery of installing extra stuff that I really do not need on my computers.<\/p>\n<p>Of course, by using Windows PowerShell remoting, I do not need to install the RSAT on my computer only to use <b>DSQuery<\/b>. I can easily use the <b>Invoke-Command<\/b> cmdlet to perform the remote query on a server (by default all domain controllers will have <b>DSQuery<\/b> installed with their admin tools). I first store the credentials that I need in a variable I call <b>$cred<\/b>. I use the <b>Get-Credential<\/b> cmdlet to obtain the <b>credential<\/b> object. Next, I use the <b>Invoke-Command<\/b> cmdlet to specify the remote server from which to process the query, and I pass the credentials. I store the returned array of strings in the <b>$computers<\/b> variable, and I then display the strings. The commands are shown here.<\/p>\n<p style=\"padding-left: 30px\">$cred = get-credential iammred\\administrator<\/p>\n<p style=\"padding-left: 30px\">$computers = invoke-command -cn dc3 {dsquery computer} -cred $cred<\/p>\n<p style=\"padding-left: 30px\">$computers<\/p>\n<p>The commands and the associated output are shown in the image that follows.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1106.HSG-8-14-12-01.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1106.HSG-8-14-12-01.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>The strings are included in the output. To obtain only the computer name itself requires further processing. One way to get the computer name would be to use a regular expression and pick out the stuff following the first <b>CN=<\/b> that occurs before a comma. That would work, but I like regular expressions even less than I like string manipulation.<\/p>\n<p>Therefore, I can turn the returned strings into <b>ADSPath<\/b> and supply that to the <b>[adsi]<\/b> type accelerator. To do that is not to horribly complicated. First, I need to get the output into a fashion I can pass to the <b>[adsi]<\/b> type accelerator. This is a two-step operation. First I replace the first <b>CN=<\/b><i> <\/i>with <b>LDAP:\/\/CN=<\/b> and store the results back into a variable. This command is shown here.<\/p>\n<p style=\"padding-left: 30px\">$ads = $computers -replace &#8216;^&#8221;CN=&#8217;, &#8216;&#8221;LDAP:\/\/CN=&#8217;<\/p>\n<p>For some reason, it does not seem to like the quotation marks when I pass it to <b>[adsi]<\/b>, so I need to remove them. Here is the command that I use for that.<\/p>\n<p style=\"padding-left: 30px\">$ads = $ads | % {$_ -replace &#8216;&#8221;&#8216;, &#8220;&#8221;}<\/p>\n<p>Now, I can use <b>ADSPath <\/b>to create a <b>DirectoryEntry<\/b> object and retrieve the <b>CN<\/b> property (the basic computer name). This command is shown here.<\/p>\n<p style=\"padding-left: 30px\">$ads | Foreach-Object &nbsp;{([adsi]$_).cn}<\/p>\n<h2>The nice thing about objects<\/h2>\n<p>The nice thing about objects is that they make it easy to access different parts of information. For example, when I use the <b>[adsisearcher]<\/b> type accelerator to find computers from inside AD DS, it returns a <b>SearchResult<\/b> object. This object contains a number of methods, but it also contains two properties. The first property is the <b>Path<\/b><i> <\/i>property, which is a string. The second property, the <b>Properties<\/b><i> <\/i>property contains an additional object. The output from the <b>Get-Member<\/b> cmdlet displays this information.<\/p>\n<p style=\"padding-left: 30px\">[dc3]: PS C:\\&gt; ([adsisearcher]&#8221;objectcategory=computer&#8221;).findall() | get-member<\/p>\n<p>&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; TypeName: System.DirectoryServices.SearchResult<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MemberType Definition<\/p>\n<p style=\"padding-left: 30px\">&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;-<\/p>\n<p style=\"padding-left: 30px\">Equals&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; bool Equals(System.Object obj)<\/p>\n<p style=\"padding-left: 30px\">GetDirectoryEntry Method&nbsp;&nbsp;&nbsp;&nbsp; adsi GetDirectoryEntry()<\/p>\n<p style=\"padding-left: 30px\">GetHashCode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; int GetHashCode()<\/p>\n<p style=\"padding-left: 30px\">GetType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; type GetType()<\/p>\n<p style=\"padding-left: 30px\">ToString&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; string ToString()<\/p>\n<p style=\"padding-left: 30px\">Path&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; System.String Path {get;}<\/p>\n<p style=\"padding-left: 30px\">Properties&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; System.DirectoryServices.ResultPropertyCollection Pr&#8230;<\/p>\n<p>The cool thing about the <b>Properties<\/b><i> <\/i>property is that it contains a collection of default properties and their associated values. The following command stores the <b>Properties<\/b><i> <\/i>collection into a variable.<\/p>\n<p style=\"padding-left: 30px\">$a = ([adsisearcher]&#8221;objectcategory=computer&#8221;).findall() | ForEach-Object {$_.properties}<\/p>\n<p>To obtain only the computer names in Windows PowerShell&nbsp;2.0, I can use the <b>GetEnumerator<\/b><i> <\/i>method and then select only the <b>CN<\/b><i> <\/i>property. In addition, I can create a custom object that contains only the properties I want. First, here is the code to select only the computer names.<\/p>\n<p style=\"padding-left: 30px\">$a.GetEnumerator() | select { $_.cn}<\/p>\n<p style=\"padding-left: 30px\"><b>Note<\/b> &nbsp;&nbsp;I talked about using the <b>GetEnumerator<\/b><i> <\/i>method when working with hash tables in a blog called <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/10\/16\/dealing-with-powershell-hash-table-quirks.aspx\" target=\"_blank\">Dealing with PowerShell Hash Table Quirks<\/a><i>.<\/i><\/p>\n<p>I can sort the information, and return a custom object. This command is shown here.<\/p>\n<p style=\"padding-left: 30px\">$a.GetEnumerator() | sort {$_.operatingsystem} | select {$_.cn, $_.operatingsystem}<\/p>\n<p>Because I am working with Windows PowerShell objects, I can do anything I want to do to them. For example, I can sort and group the output as shown here.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $a.GetEnumerator() | sort {$_.operatingsystem} |<\/p>\n<p style=\"padding-left: 30px\">group {$_.operatingsystem} -NoElement | sort count<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Count Name<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8211; &#8212;-<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 1 OnTap<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 1 Windows 7 Enterprise<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 1 Windows 8 Consumer Pre&#8230;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 1 Windows 8 Pro N<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 1 Windows 8 Release Preview<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 1 Windows Server 2012 Da&#8230;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 1 Windows Server 2012 Re&#8230;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 1 Windows Vista&trade; Enterprise<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 2 Windows 8 Enterprise E&#8230;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 2 Windows 8 Pro<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 2 Windows Server 8 Beta &#8230;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 3 Windows Server&reg; 2008 E&#8230;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 8 Windows 7 Ultimate<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; 11 Windows Server 2008 R2&#8230;<\/p>\n<p>WS, that is all there is to using <b>DSQuery<\/b> to search Active Directory Domain Services. Join me tomorrow for more cool Windows PowerShell stuff.<\/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. Until then, peace.<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using DSQuery to return results for use in Windows PowerShell. &nbsp;Hey, Scripting Guy! &nbsp;I like using the DSQuery tool to search Active Directory Domain Services (AD DS). Can I use that tool with Windows PowerShell? &mdash;WS &nbsp;Hello WS, Microsoft Scripting Guy, Ed Wilson, is here. Yes, it [&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-5127","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: Microsoft Scripting Guy, Ed Wilson, talks about using DSQuery to return results for use in Windows PowerShell. &nbsp;Hey, Scripting Guy! &nbsp;I like using the DSQuery tool to search Active Directory Domain Services (AD DS). Can I use that tool with Windows PowerShell? &mdash;WS &nbsp;Hello WS, Microsoft Scripting Guy, Ed Wilson, is here. Yes, it [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/5127","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=5127"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/5127\/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=5127"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=5127"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=5127"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}