{"id":63833,"date":"2007-10-10T10:25:00","date_gmt":"2007-10-10T10:25:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/10\/10\/hey-scripting-guy-how-can-i-search-multiple-ous-in-active-directory\/"},"modified":"2007-10-10T10:25:00","modified_gmt":"2007-10-10T10:25:00","slug":"hey-scripting-guy-how-can-i-search-multiple-ous-in-active-directory","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-search-multiple-ous-in-active-directory\/","title":{"rendered":"Hey, Scripting Guy! How Can I Search Multiple OUs in Active Directory?"},"content":{"rendered":"<p><H2><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"> <\/H2>\n<P>Hey, Scripting Guy! I have an HTA that searches Active Directory for user accounts and then displays those user names. We have 10 OUs in Active Directory, but I only want to retrieve the users from three of those OUs. How do I do that?<BR><BR>&#8212; DP<\/P><IMG border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" border=\"0\" alt=\"Script Center\" align=\"right\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" height=\"288\"><\/A> \n<P>Hey, DP. Here\u2019s a little secret for you: it\u2019s very easy to tell when a writer is getting lazy and isn\u2019t even trying any more. How can you tell that? Because they will inevitably start off an article by using some tired old clich\u00e9, like the old \u201cI\u2019ve got some good news for you and some bad news for you\u201d routine. Just something everyone should watch out for; you know how the Scripting Guys feel about lazy writers who don\u2019t even try anymore. Now, as for your question about searching Active Directory, well, we\u2019ve got some good news for you and some bad news for you. Let\u2019s go over the bad news first. You want to search Active Directory for user accounts, but you only want to retrieve the accounts found in 3 of your 10 OUs. Well, guess what? You can\u2019t do that. (At least not very easily.) That\u2019s because, oddly enough, Active Directory does not have a property that specifies the OU where a user account (or any other object) resides. In theory, we could write a complicated wildcard-based query that <I>might<\/I> do the trick, but we can\u2019t do anything as simple and straightforward as this hypothetical Where clause:<\/P><PRE class=\"codeSample\">Where OU=&#8217;Finance&#8217; OR OU=&#8217;Research&#8217; OR OU=&#8221;Shipping&#8217;\n<\/PRE>\n<P>It just can\u2019t be done.<\/P>\n<P>Anyway, sorry about the bad news, DP. See you all tomorrow!<\/P>\n<P>Oh, right. As the Scripting Editor has \u2026 helpfully \u2026 pointed out, any time you do the old good news-bad news routine it\u2019s customary to tell people the good news as well. (Unfortunately, that\u2019s also a lot more work, which is why we didn\u2019t tell you the good news in the first place. Besides, we\u2019d always heard that no news <I>was<\/I> good news.) But, as you know, the Scripting Editor\u2019s word is law. Therefore, DP, the good news is that we can still retrieve users from a specified set of OUs; we just have to perform multiple searches in order to do so. (But don\u2019t worry; Active Directory searches \u2013 particularly searches targeted towards a single OU \u2013 are pretty darn fast.) And there\u2019s even <I>better<\/I> news: we\u2019ll also show you an HTA that displays <I>all<\/I> your OUs in a list box, lets you select as many (or as few) of those OUs as you wish, and then retrieves information about the user accounts found in each of the selected OUs.<\/P>\n<P>We agree: that\u2019s also the best news that <I>we\u2019ve<\/I> heard all week.<\/P>\n<P>But, then again, we work at Microsoft, so we don\u2019t have much of a chance to hear <I>really<\/I> good news. (Scripting Guys advice: Don\u2019t <I>ever<\/I> say the letters MTPS in front of the Scripting Editor. Trust us.)<\/P>\n<P>At any rate, here\u2019s the code:<\/P><PRE class=\"codeSample\">&lt;SCRIPT Language=&#8221;VBScript&#8221;&gt;<\/p>\n<p>    Const ADS_SCOPE_SUBTREE = 2\n    Const ADS_SCOPE_ONELEVEL = 1<\/p>\n<p>    Set objConnection = CreateObject(&#8220;ADODB.Connection&#8221;)\n    Set objCommand =   CreateObject(&#8220;ADODB.Command&#8221;)\n    objConnection.Provider = &#8220;ADsDSOObject&#8221;\n    objConnection.Open &#8220;Active Directory Provider&#8221;\n    Set objCommand.ActiveConnection = objConnection<\/p>\n<p>    objCommand.Properties(&#8220;Page Size&#8221;) = 1000<\/p>\n<p>    Sub Window_onLoad\n        objCommand.Properties(&#8220;Searchscope&#8221;) = ADS_SCOPE_SUBTREE \n        objCommand.CommandText = _\n            &#8220;SELECT Name, ADsPath FROM &#8216;LDAP:\/\/dc=fabrikam,dc=com&#8217; WHERE &#8221; &amp; _\n                &#8220;objectCategory=&#8217;organizationalUnit&#8217; ORDER By Name&#8221;  \n        Set objRecordSet = objCommand.Execute<\/p>\n<p>        objRecordSet.MoveFirst<\/p>\n<p>        strHTML = &#8220;&lt;select size = &#8217;20&#8217; name=&#8217;OUList&#8217; style=&#8217;width:300px&#8217;&gt;&#8221;<\/p>\n<p>        Do Until objRecordSet.EOF  \n            Set objOption = Document.createElement(&#8220;OPTION&#8221;)\n            objOption.Text = objRecordSet.Fields(&#8220;Name&#8221;).Value\n            objOption.Value = objRecordSet.Fields(&#8220;ADsPath&#8221;).Value\n            MyOUs.Add(objOption)\n            objRecordSet.MoveNext\n         Loop<\/p>\n<p>    End Sub<\/p>\n<p>    Sub SearchForUsers\n        For i = 0 to (MyOUs.Options.Length &#8211; 1)\n            If (MyOUs.Options(i).Selected) Then\n                strSearchOU = MyOUs.Options(i).Value \n                objCommand.Properties(&#8220;Searchscope&#8221;) = ADS_SCOPE_ONELEVEL <\/p>\n<p>                objCommand.CommandText = _\n                    &#8220;SELECT Name FROM &#8216;&#8221; &amp; strSearchOU &amp; &#8220;&#8216; WHERE objectCategory=&#8217;user'&#8221;  \n                Set objRecordSet = objCommand.Execute<\/p>\n<p>                If objRecordSet.RecordCount &gt; 0 Then\n                    objRecordSet.MoveFirst\n                    Do Until objRecordSet.EOF\n                        strNames = strNames &amp; objRecordSet.Fields(&#8220;Name&#8221;).Value &amp; &#8220;&lt;BR&gt;&#8221;\n                        objRecordSet.MoveNext\n                    Loop\n                End If\n            End If\n        Next\n        UserList.InnerHTML = strNames\n    End Sub<\/p>\n<p>&lt;\/SCRIPT&gt;<\/p>\n<p>&lt;body&gt;\n    &lt;select size=&#8221;10&#8243; name=&#8221;MyOUs&#8221; style=&#8221;width:400&#8243; multiple&gt;&lt;\/select&gt;&lt;p&gt;\n    &lt;input type=&#8221;button&#8221; value=&#8221;Get Users&#8221; onClick=&#8221;SearchForUsers&#8221;&gt;&lt;p&gt;\n    &lt;div id=&#8221;UserList&#8221;&gt;&lt;\/div&gt;\n&lt;\/body&gt;\n<\/PRE>\n<P>You\u2019re right: this <I>is<\/I> a big, long chunk of code, isn\u2019t it? But don\u2019t worry; we\u2019ll explain how it all works.<\/P>\n<TABLE id=\"EBE\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. Well, except for the parts where we <I>don\u2019t<\/I> explain how it all works. For example, we won\u2019t talk much about the basic fundamentals of searching Active Directory; for that, we recommend you take a peek at our two-part <I>Tales From the Script<\/I> series <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/tales\/sg0405.mspx\"><B>Dude, Where\u2019s My Printer?<\/B><\/A> And we won\u2019t spend a lot of time discussing the process by which we create a dynamic list box for displaying OUs; after all, we <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/sept07\/hey0920.mspx\"><B>already have a column<\/B><\/A> that discusses the process for creating dynamic list boxes. And \u2013 well, you get the idea.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Let\u2019s start by looking at the HTML objects we\u2019re using in this HTA:<\/P><PRE class=\"codeSample\">&lt;select size=&#8221;10&#8243; name=&#8221;MyOUs&#8221; style=&#8221;width:400&#8243; multiple&gt;&lt;\/select&gt;&lt;p&gt;\n&lt;input type=&#8221;button&#8221; value=&#8221;Get Users&#8221; onClick=&#8221;SearchForUsers&#8221;&gt;&lt;p&gt;\n&lt;div id=&#8221;UserList&#8221;&gt;&lt;\/div&gt;\n<\/PRE>\n<P>As you can see, our HTA consists of three objects:<\/P>\n<TABLE border=\"0\" cellSpacing=\"0\" cellPadding=\"0\">\n<TBODY>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>A multi-select list box named MyOUs<\/B>. How do we know that this is a multi-select list box? Because we added the <B>multiple<\/B> parameter. What is a multi-select list box? That\u2019s simply a list box that allows you to make multiple selections: you can click on as many items as you wish, and our subroutine (which we\u2019ll talk about in a minute or two) will run against each of the selected items.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>A button with the label Get Users<\/B>. When this button is clicked, a subroutine named SearchForUsers is triggered; as the name implies, this is the subroutine that searches for users in the selected OUs. The basic premise here is that you select as many (or as few) OUs from the list box as needed, then click the <B>Get Users<\/B> button; in turn, the SearchForUsers subroutine will grab user account information from the selected OUs and then \u2013 well, good question: what will the subroutine do with that information? (Hint: The answer can be found in the next bullet.)<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>A &lt;DIV&gt; with the ID UserList<\/B>. A &lt;DIV&gt; is nothing more than a named area of an HTA, an area whose contents can be manipulated programmatically. As you can see, right now our &lt;DIV&gt; doesn\u2019t actually have any content. But that\u2019s only temporary; the SearchForUsers subroutine will eventually write the retrieved user names to this portion of the HTA.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>Got all that? Good; now it\u2019s time to talk scripting.<\/P>\n<TABLE id=\"EZF\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. Ah, good question: is talking scripting good news or bad news? Guess we\u2019ll all find out in a minute, won\u2019t we?<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>To begin with, you might have noticed that we started off our HTA with the &lt;SCRIPT&gt; tag, then immediately added in the following lines of code, code that we did <I>not<\/I> include in a subroutine:<\/P><PRE class=\"codeSample\">Const ADS_SCOPE_SUBTREE = 2\nConst ADS_SCOPE_ONELEVEL = 1<\/p>\n<p>Set objConnection = CreateObject(&#8220;ADODB.Connection&#8221;)\nSet objCommand =   CreateObject(&#8220;ADODB.Command&#8221;)\nobjConnection.Provider = &#8220;ADsDSOObject&#8221;\nobjConnection.Open &#8220;Active Directory Provider&#8221;\nSet objCommand.ActiveConnection = objConnection<\/p>\n<p>objCommand.Properties(&#8220;Page Size&#8221;) = 1000\n<\/PRE>\n<P>Why didn\u2019t we put these commands in a subroutine? Well, what we\u2019re doing here is defining a pair of constants (ADS_SCOPE_SUBTREE and ADS_SCOPE_ONELEVEL); creating a pair of objects (<B>ADODB.Connection<\/B> and <B>ADODB.Command<\/B>); and then configuring some of the properties for these objects. We want these constants and objects to be global; that is, we want them to be available to all the subroutines in our HTA. The easiest way to do that is to place the code inside the &lt;SCRIPT&gt; tag, but <I>not<\/I> inside a subroutine. So that\u2019s exactly what we did.<\/P>\n<TABLE id=\"EVG\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. Incidentally, these commands are explained in more detail in our <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/tales\/sg0405.mspx\"><B>Tales From the Script series<\/B><\/A>.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Now we have our two subroutines \u2013 Window_OnLoad and SearchForUsers \u2013 to deal with. To begin with, we should note that we didn\u2019t pick the name Window_OnLoad simply because we liked the way that sounded. (Although it <I>does<\/I> tend to just roll off the tongue, doesn\u2019t it?) Instead, we chose this name because any subroutine with the name Window_OnLoad automatically runs any time an HTA is opened or refreshed. By putting our code for retrieving a list of OU names in a subroutine named Window_OnLoad, we guarantee that each time we start the HTA our list box will be populated with all the OUs in Active Directory.<\/P>\n<P>As for <I>how<\/I> we go about retrieving OU names, well, again, we won\u2019t discuss that in any detail today. Instead, we\u2019ll simply focus on the SQL query we employed:<\/P><PRE class=\"codeSample\">objCommand.CommandText = _\n    &#8220;SELECT Name, ADsPath FROM &#8216;LDAP:\/\/dc=fabrikam,dc=com&#8217; WHERE &#8221; &amp; _\n        &#8220;objectCategory=&#8217;organizationalUnit&#8217; ORDER By Name&#8221;\n<\/PRE>\n<P>As you can see, we\u2019re requesting that the script return the values of two attributes (<B>Name<\/B> and <B>ADsPath<\/B>) for all the objects in the domain (fabrikam.com) that have an <B>objectCategory<\/B> equal to <I>organizationalUnit<\/I>. (In addition, we\u2019re also sorting these objects alphabetically by Name.) How do we know that we\u2019ll get back <I>all<\/I> the OUs in the domain? Because, right before we execute the query, we set the <B>Searchscope<\/B> to ADS_SCOPE_SUBTREE:<\/P><PRE class=\"codeSample\">objCommand.Properties(&#8220;Searchscope&#8221;) = ADS_SCOPE_SUBTREE\n<\/PRE>\n<P>When we do that, our script searches not only the specified container (fabrikam.com) but also any and all sub-containers (e.g., any and all OUs and sub-OUs). Because we started the search in our Active Directory root, the script will methodically search the entire directory service, and bring back each of the OUs it finds lurking in there.<\/P>\n<P>Once we get back a recordset containing all the OU names we then use this block of code to add each OU to the list box:<\/P><PRE class=\"codeSample\">Do Until objRecordSet.EOF  \n    Set objOption = Document.createElement(&#8220;OPTION&#8221;)\n    objOption.Text = objRecordSet.Fields(&#8220;Name&#8221;).Value\n    objOption.Value = objRecordSet.Fields(&#8220;ADsPath&#8221;).Value\n    MyOUs.Add(objOption)\n    objRecordSet.MoveNext\nLoop\n<\/PRE>\n<P>Without going into too much detail, for each record (OU) in our recordset we create an instance of the <B>Option<\/B> object. We assign the OU Name to the <B>Text<\/B> property (the label displayed in the list box) and the ADsPath to the <B>Value<\/B> property (the actual information to be used by our SearchForUsers subroutine). Once that\u2019s done we call the <B>Add<\/B> method to add this new option to the list box.<\/P>\n<P>Isn\u2019t that a lot of work just to get our HTA up and running? Well, sure; the bad news is that there <I>is<\/I> a little bit of prep work required to get things going here. But if there\u2019s bad news that can only mean one thing: there must be some good news as well. And the good news is that we\u2019re now ready to start searching for user accounts.<\/P>\n<P>Before we can do that, of course, we need to figure out which OUs we\u2019re supposed to search. The easiest way to do that? By executing this block of code:<\/P><PRE class=\"codeSample\">For i = 0 to (MyOUs.Options.Length &#8211; 1)\n    If (MyOUs.Options(i).Selected) Then\n        strSearchOU = MyOUs.Options(i).Value\n<\/PRE>\n<P>What we\u2019ve done here is set up a For Next loop that runs from 0 to the <B>Length<\/B> of the list box, minus 1. Why 0? Because, in a VBScript collection, the first item always has the index number 0. And why the number of items <I>minus 1<\/I>? Well, suppose we selected three items in the list box. The first item has the index number 0; the second item has the index number 1; and the third item has the index number 2. The last item in a collection always has an index number 1 less than the total number of items in that array.<\/P>\n<P>Crazy, but that\u2019s how it works.<\/P>\n<P>For each item in the list box we check to see if the <B>Selected<\/B> property is True; if it is, that means that this OU was selected and needs to be searched. To carry out that search we grab the Value property (which just happens to be the ADsPath for the OU) and stash that information in a variable named strSearchOU.<\/P>\n<P>Now we have two other chores to carry out. First, we need to set the SearchScope to ADS_SCOPE_ONELEVEL:<\/P><PRE class=\"codeSample\">objCommand.Properties(&#8220;Searchscope&#8221;) = ADS_SCOPE_ONELEVEL\n<\/PRE>\n<P>Why? Because this constant tells the script to search <I>only<\/I> the specified OU; it will not search any child OUs. That\u2019s how we manage to limit a search to a single OU.<\/P>\n<P>Second, we need to define our SQL query:<\/P><PRE class=\"codeSample\">objCommand.CommandText = _\n    &#8220;SELECT Name FROM &#8216;&#8221; &amp; strSearchOU &amp; &#8220;&#8216; WHERE objectCategory=&#8217;user'&#8221;\n<\/PRE>\n<P>In this query, we\u2019re simply searching the selected OU, retrieving the Name of every object that has an objectCategroy equal to <I>user<\/I>. Needless to say, that\u2019s going to bring back a recordset containing information about each user in the OU. And then for each user in that recordset we add the user name and a &lt;BR&gt; tag (the HTML equivalent of the carriage return-linefeed character):<\/P><PRE class=\"codeSample\">strNames = strNames &amp; objRecordSet.Fields(&#8220;Name&#8221;).Value &amp; &#8220;&lt;BR&gt;&#8221;\n<\/PRE>\n<P>What if we selected more than one OU in the list box? That\u2019s fine; after we finish with the first OU we loop around and continue looking for more selected items. If we find one, we repeat this process using <I>that<\/I> OU.<\/P>\n<P>When we\u2019ve finished with all the items in the list box we then use this line of code to write the user names to our &lt;DIV&gt;:<\/P><PRE class=\"codeSample\">UserList.InnerHTML = strNames\n<\/PRE>\n<P>That should do it, DP. The bad news is that this isn\u2019t a very fancy HTA; you\u2019ll undoubtedly need to do some additional work to ensure that the returned information is displayed in a coherent fashion. (Incidentally, here\u2019s <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/topics\/activex\/spreadsheet.mspx\"><B>one cool way<\/B><\/A> to do that.) The good news is that even though this <I>is<\/I> a bit of a workaround, at least it enables you to retrieve user accounts from three different OUs, even if it does require three separate searches.<\/P>\n<P>Oh, and the even <I>better<\/I> news? That\u2019s right: we\u2019re finally done for today! See you all tomorrow.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I have an HTA that searches Active Directory for user accounts and then displays those user names. We have 10 OUs in Active Directory, but I only want to retrieve the users from three of those OUs. How do I do that?&#8212; DP Hey, DP. Here\u2019s a little secret for you: it\u2019s [&hellip;]<\/p>\n","protected":false},"author":595,"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,5],"class_list":["post-63833","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-scripting-guy","tag-searching-active-directory","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I have an HTA that searches Active Directory for user accounts and then displays those user names. We have 10 OUs in Active Directory, but I only want to retrieve the users from three of those OUs. How do I do that?&#8212; DP Hey, DP. Here\u2019s a little secret for you: it\u2019s [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63833","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\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=63833"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63833\/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=63833"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=63833"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=63833"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}