{"id":56373,"date":"2008-01-22T22:01:00","date_gmt":"2008-01-22T22:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/01\/22\/hey-scripting-guy-how-can-i-synchronize-a-text-file-of-folder-names-with-the-subfolders-in-a-folder\/"},"modified":"2008-01-22T22:01:00","modified_gmt":"2008-01-22T22:01:00","slug":"hey-scripting-guy-how-can-i-synchronize-a-text-file-of-folder-names-with-the-subfolders-in-a-folder","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-synchronize-a-text-file-of-folder-names-with-the-subfolders-in-a-folder\/","title":{"rendered":"Hey, Scripting Guy! How Can I Synchronize a Text File of Folder Names With the Subfolders in a Folder?"},"content":{"rendered":"<p><img decoding=\"async\" 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\" \/> <\/p>\n<p>Hey, Scripting Guy! I have a script that reads through a text file and then checks a folder to see if all the subfolder names listed in that text file actually exist. (For example, if the parent folder is C:\\Scripts the script might check to see if a folder named Test Folder \u2013 that is, C:\\Scripts\\Test Folder \u2013 actually exists.) This part of the script works pretty well. However, sometimes a folder exists that isn\u2019t listed in the text file. When that happens, I\u2019d like to be prompted with a message box that would let me decide whether or not I wanted the script to add that folder to the text file. How do I do that?<\/p>\n<p>&#8212; SW<\/p>\n<p><img decoding=\"async\" border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\" \/><img decoding=\"async\" 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 decoding=\"async\" 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> <\/p>\n<p>Hey, SW. We know that many people read this column because they want to know if today will be the day when the Scripting Guy who writes this column finally goes too far and writes something that gets him fired.<\/p>\n<table id=\"E2C\" 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>. If you\u2019re one of those people we can save you the trouble of reading the rest of this column; the answer is \u201cNo, not today.\u201d But you might want to circle February 8<sup>th<\/sup> on your calendar. As it turns out, the Scripting Guys have a meeting scheduled for that afternoon, a meeting that could easily push the Scripting Guy who writes this column over the edge.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>Of course, other people read this column because they want the inside scoop on what\u2019s going on in the scripting world. What kind of a scoop? Well, how about this one: although we haven\u2019t officially announced this yet, the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/funzone\/games\/default.mspx\"><b>2008 Winter Scripting Games<\/b><\/a> (February 15<sup>th<\/sup> through March 3<sup>rd<\/sup>) will include several new challenges in addition to the \u201cclassic\u201d events.<\/p>\n<table id=\"EXD\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td>\n<p><b>Note<\/b>. <i>Why<\/i> haven\u2019t we officially announced this yet? Well, let\u2019s just say that one of the two Scripting Guys is a little bit behind in his work, and let it go at that.<\/p>\n<p>And no, surprisingly enough, this time it\u2019s <i>not<\/i> Scripting Guy Jean Ross.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>At any rate, one new challenge is the <b>User Group Challenge<\/b>, sponsored by <a href=\"http:\/\/www.microsoft.com\/technet\/technetmag\/\" target=\"_blank\"><b>TechNet Magazine<\/b><\/a>. When you compete in the Games this year, you\u2019ll have the option to indicate the name of a Microsoft user group that you belong to. Why would you want to do that? Well, the user group that ends up with the most participants (on a percentage basis) will be declared the winner of the User Group Challenge. Big deal? Well, maybe; after all, the winning user group will be awarded a trophy; the winning user group will be featured in a Script Center article; and each member of the group that competes in the Games will be given an individual award (of a to-be-determined nature). That\u2019s <i>kind<\/i> of a big deal, wouldn\u2019t you say?<\/p>\n<p>And yes, of <i>course<\/i> you can cheat. If you want to get together as a group and tackle the Scripting Games events, well, who are we to tell you no? Feel free to work together on your scripts; that\u2019s what user groups are for, right? Just remember, however, that if a dozen of you work together on the scripts <i>all 12 of you must submit separate entries<\/i>. Otherwise you\u2019ll get credit for just 1 entry, and only the person who does the actual submitting will be eligible for all the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/funzone\/games\/games08\/prizes.mspx\"><b>individual prizes<\/b><\/a>. And that would be no fun at all, especially if you\u2019ve seen the list of prizes.<\/p>\n<p>Now, admittedly, not everyone belongs to a user group. However, most people <i>do<\/i> have some allegiance to a country, either because they live there, they were born there, or maybe because that country has really good food. If you <i>do<\/i> have an allegiance of some kind to a country of some kind then you might be interested in the <b>International Challenge<\/b>. In the previous two Scripting Games we\u2019ve given people the option of competing for a country of their choice, and we\u2019ve tallied scores on a per-country basis. This year, however, we\u2019re going one step further: this year the country that has the most entrants (based on the population of that country) will be crowned the International Challenge winner. Even better, during the month of April we\u2019re going to dedicate the entire Script Center to that country. We\u2019re not sure what that means (although we <i>are<\/i> sure that TechNet will freak out when they hear about this) but it will be cool. We promise. <\/p>\n<p>And sure, you can cheat on this one, too: if all the residents of Finland want to get together to work on solutions for the Games, well, the Scripting Guys can\u2019t stop you. (Maybe we could stop some other country, but definitely not Finland.) So what the heck: recruit your compatriots, and show everyone where the best scripters in the world <i>really<\/i> hail from.<\/p>\n<p>Or at least <i>say<\/i> they hail from. To tell you the truth, we still haven\u2019t been able to find Targetopia, VandyLand, or Bmraarykduesn or some of the other countries from the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/funzone\/games\/games07\/countryscores.mspx\"><b>2007 Scripting Games<\/b><\/a> on any map.<\/p>\n<p>And then there was one: the <b>Sudden Death Challenge<\/b>. This name is actually left over from another idea we had and then decided not to follow up on. To be perfectly honest the Sudden Death Challenge has nothing to do with sudden death; we just liked the name so we decided to keep it. <i>(<\/i><i>Ed<\/i><i>itor\u2019s Note: Something else TechNet won\u2019t be very happy about, not to mention the politically-correct-terminology people here at Microsoft.<\/i><i> Don\u2019t be surprised if this name changes at some point in the midst of all this.<\/i><i>)<\/i> With the Sudden Death challenge, we\u2019ll post a sort of mini-event on the opening day of the Games; this event might require you to write a little script, solve a puzzle, or simply know a little something about scripting. The first mini-event will be available for only a day or two, then will be replaced by another mini-event (there will be 10 of these in all). The idea is that you come back every day or two, try your hand at a mini-event, and see how many total Sudden Death points you can accumulate. When the Games are over, we\u2019ll tally the points and award \u2026 something \u2026 to the winner. (Budgets being what they are around here, we haven\u2019t been able to finalize the prize list yet.)<\/p>\n<p>There you have it, folks: the 2008 Winter Scripting Games, coming February 15<sup>th<\/sup> to your favorite Script Center.<\/p>\n<p>Um, yes, that would be <i>this<\/i> Script Center. <\/p>\n<p>Of course, that does leave you with at least one problem: how are you going to pass the time between now and February 15<sup>th<\/sup>? Well, here\u2019s an idea; maybe you can try running the following script, a script that can tell you whether a text file of folder names and a folder full of subfolders are in synch:<\/p>\n<pre class=\"codeSample\">Const ForReading = 1\nConst ForAppending = 8 \nConst FOLDER_PATH = (\"C:\\Scripts\\\") \n\nSet objFSO = CreateObject(\"Scripting.FileSystemObject\") \nSet objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Test.txt\", ForReading)\n\nSet objFolderList = CreateObject(\"Scripting.Dictionary\")\nobjFolderList.CompareMode = vbTextCompare\n\nDo Until objFile.AtEndOfStream \n    strName = objFile.ReadLine \n    objFolderList.Add strName, strName\nLoop\n\nobjFile.Close\n \nSet objExistingFolders = CreateObject(\"Scripting.Dictionary\")\nobjExistingFolders.CompareMode = vbTextCompare\n\nstrComputer = \".\"\n\nSet objWMIService = GetObject(\"winmgmts:\\\\\" &amp; strComputer &amp; \"\\root\\cimv2\")\n\nSet colSubfolders = objWMIService.ExecQuery _\n    (\"Associators of {Win32_Directory.Name='C:\\Scripts'} \" _\n        &amp; \"Where AssocClass = Win32_Subdirectory \" _\n            &amp; \"ResultRole = PartComponent\")\n\nFor Each objSubfolder in colSubfolders\n    strName = objSubfolder.FileName\n    objExistingFolders.Add strName, strName\nNext\n\nFor Each strKey in objFolderList.Keys\n    strFolderName = strKey\n    If Not objExistingFolders.Exists(strFolderName) Then\n        Wscript.Echo \"The folder \" &amp; strFolderName &amp; \" does not exist.\"\n    End If\nNext\n\nFor Each strKey in objExistingFolders.Keys\n    strFolderName = strKey\n    If Not objFolderList.Exists(strFolderName) Then\n        strMessage = \"The folder \" &amp; strFolderName &amp; \" is not in the text file. \"\n        strMessage = strMessage &amp; \"Would you like to add this folder to the text file?\"\n        intReturn = Msgbox(strMessage, vbYesNo, \"Add to Text File\")\n        If intReturn = vbYes Then\n            strNewItems = strNewItems &amp; strFolderName &amp; vbCrLf\n        End If\n    End If\nNext\n\nIf strNewItems &lt;&gt; \"\" Then\n    Set objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Test.txt\", ForAppending)\n    objFile.Write strNewItems\n    objFile.Close\nEnd If\n<\/pre>\n<p>Admittedly, this is kind of a long script (at least for a <i>Hey, Scripting Guy!<\/i> column) so maybe we better get down to business and see if we can explain how the thing works.<\/p>\n<p>As you can see, we start out in pretty straightforward fashion, defining three constants: ForReading and For Appending (which we\u2019ll need when reading from and potentially writing to the text file); and FOLDER_PATH, a constant we copied out of SW\u2019s original script that holds the path for the folder to be checked for subfolders. In this case, that\u2019s C:\\Scripts\\.<\/p>\n<table id=\"EKH\" 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>. Yes, the \\ on the end of the path is important; by including the \\ we can determine complete folder paths for any subfolders simply by tacking the folder name on to the end of this value.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>After defining the constants we create an instance of the <b>Scripting.Dictionary<\/b> object, then use the <b>OpenTextFile<\/b> method to open the file C:\\Scripts\\Test.txt for reading:<\/p>\n<pre class=\"codeSample\">Set objFSO = CreateObject(\"Scripting.FileSystemObject\") \nSet objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Test.txt\", ForReading)\n<\/pre>\n<p>And then we go ahead and read the \u2013 wait, hold on a second: this time we <i>don\u2019t<\/i> just go ahead and read the file. Instead, we create an instance of the <b>Scripting.Dictionary<\/b> object, an instance we give the object reference objFolderList:<\/p>\n<pre class=\"codeSample\">Set objFolderList = CreateObject(\"Scripting.Dictionary\")\n<\/pre>\n<p>Why do we need an instance of the Dictionary object? Well, to tell you the truth, we don\u2019t; we need <i>two<\/i> instances of the Dictionary object. Our task here, as you know, consists of two parts: first we need to read through a text file and see if the folders listed in that file really exist, then we need to loop through a collection of subfolders and see if those folders are listed in the text file. Although there are several different ways we could approach this problem, we decided the easiest solution was to put the folder names in the text file into one Dictionary object, then put the actual subfolder names into another Dictionary object. Thanks to the Dictionary object\u2019s <b>Exists<\/b> method, we can then easily see if the items in Dictionary 1 also appear in Dictionary 2, and vice-versa.<\/p>\n<p>As you\u2019re about to see.<\/p>\n<p>Incidentally, we also set the Dictionary\u2019s <b>CompareMode<\/b> property to the VBScript constant vbCompareText. That ensures that our dictionaries do case-insensitive comparisons; in other words, this makes sure that a folder named <b>Test Folder<\/b> and a folder named <b>test folder<\/b> are considered one and the same.<\/p>\n<p>So how do we get folder names out of the text file and into the Dictionary? Like this:<\/p>\n<pre class=\"codeSample\">Do Until objFile.AtEndOfStream \n    strName = objFile.ReadLine \n    objFolderList.Add strName, strName\nLoop\n<\/pre>\n<p>All we\u2019ve done here is set up a Do Until loop that runs until we reach the end of the text file (that is, until the file\u2019s <b>AtEndOfStream<\/b> property is true). Inside the loop, we use the <b>ReadLine<\/b> method to read in the first folder name, then use the <b>Add<\/b> method to add that folder name to the Dictionary:<\/p>\n<pre class=\"codeSample\">strName = objFile.ReadLine \nobjFolderList.Add strName, strName\n<\/pre>\n<p>As soon as all the folders have been added to the Dictionary we then call the <b>Close<\/b> method and close the text file.<\/p>\n<p>One Dictionary down, one Dictionary to go.<\/p>\n<p>To take care of Dictionary 2, we start out by creating another instance of the Scripting.Dictionary object, giving this instance the object reference objExistingFolders:<\/p>\n<pre class=\"codeSample\">Set objExistingFolders = CreateObject(\"Scripting.Dictionary\")\n<\/pre>\n<p>Now it\u2019s time to retrieve the subfolders of C:\\Scripts. In his original script, SW used the FileSystemObject to retrieve the collection of subfolders. That works great; the only drawback is that it pretty much limits you to running the script on the local computer. If you want to run that script against a remote computer, well, then you have some additional matters to work out. The Scripting Guys don\u2019t like having additional matters to work out; therefore, we decided to use WMI to retrieve all the subfolders of C:\\Scripts:<\/p>\n<pre class=\"codeSample\">strComputer = \".\"\n\nSet objWMIService = GetObject(\"winmgmts:\\\\\" &amp; strComputer &amp; \"\\root\\cimv2\")\n\nSet colSubfolders = objWMIService.ExecQuery _\n    (\"Associators of {Win32_Directory.Name='C:\\Scripts'} \" _\n        &amp; \"Where AssocClass = Win32_Subdirectory \" _\n            &amp; \"ResultRole = PartComponent\")\n<\/pre>\n<table id=\"EUBAC\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td>\n<p><b>Note<\/b>. OK, you\u2019re right: that block of code <i>also<\/i> is designed to work against the local computer. But that\u2019s no big deal; if you want to retrieve this information from a remote machine then simply assign the name of that computer to the variable strComputer. In other words:<\/p>\n<pre class=\"codeSample\">strComputer = \"atl-fs-001\"\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>From here we can populate our second Dictionary object simply by looping through the collection of subfolders, retrieving the value of the <b>FileName<\/b> property, and then adding that value to the Dictionary:<\/p>\n<pre class=\"codeSample\">For Each objSubfolder in colSubfolders\n    strName = objSubfolder.FileName\n    objExistingFolders.Add strName, strName\nNext\n<\/pre>\n<p>That\u2019s pretty cool: we now have two fully-populated Dictionary objects. The only question remaining is this: what exactly are we going to <i>do<\/i> with those Dictionary objects? Well, for starters, we\u2019re going to do this:<\/p>\n<pre class=\"codeSample\">For Each strKey in objFolderList.Keys\n    strFolderName = strKey\n    If Not objExistingFolders.Exists(strFolderName) Then\n        Wscript.Echo \"The folder \" &amp; strFolderName &amp; \" does not exist.\"\n    End If\nNext\n<\/pre>\n<p>What we\u2019re doing here is looping through the keys in our first Dictionary object, the one containing the folder names (just the names, not the complete paths) that we read in from the text file. For each key we store the key name in a variable named strFolderName, then use the <b>Exists<\/b> method to see if that same value exists in our other Dictionary, the one containing the actual subfolders found in C:\\Scripts. If the value does <i>not<\/i> exist in the second Dictionary that means that this particular folder is listed in the text file, but doesn\u2019t actually exist. Hence we echo back a message to that effect:<\/p>\n<pre class=\"codeSample\">The folder Test Folder does not exist.\n<\/pre>\n<p>This, by the way, is what SW\u2019s original script did. <\/p>\n<p>We then do something similar with our second Dictionary checking to see if all the actual subfolders of C:\\Scripts are listed in the text file:<\/p>\n<pre class=\"codeSample\">For Each strKey in objExistingFolders.Keys\n    strFolderName = strKey\n    If Not objFolderList.Exists(strFolderName) Then\n        strMessage = \"The folder \" &amp; strFolderName &amp; \" is not in the text file. \"\n        strMessage = strMessage &amp; \"Would you like to add this folder to the text file?\"\n        intReturn = Msgbox(strMessage, vbYesNo, \"Add to Text File\")\n        If intReturn = vbYes Then\n            strNewItems = strNewItems &amp; strFolderName &amp; vbCrLf\n        End If\n    End If\nNext\n<\/pre>\n<p>Per SW\u2019s wishes, we do a couple things if the subfolder is <i>not<\/i> listed in the text file. To begin with, we use these two lines of code to construct a message informing the user that the folder is not in the text file, then asking if he or she would like the script to add the folder name to that file:<\/p>\n<pre class=\"codeSample\">strMessage = \"The folder \" &amp; strFolderName &amp; \" is not in the text file. \"\nstrMessage = strMessage &amp; \"Would you like to add this folder to the text file?\"\n<\/pre>\n<p>We then use this line of code to display a message box containing a <b>Yes<\/b> button and a <b>No<\/b> button (the VBScript constant <b>vbYesNo<\/b>):<\/p>\n<pre class=\"codeSample\">intReturn = Msgbox(strMessage, vbYesNo, \"Add to Text File\")\n<\/pre>\n<p>If the user clicks <b>Yes<\/b> (that is, <b>If intReturn = vbYes<\/b>) we append the folder name and a carriage return-linefeed (<b>vbCrLf<\/b>) to a variable named strNewItems. If the user clicks <b>No<\/b>, then we simply loop around and repeat the process with the next key in the Dictionary.<\/p>\n<p>When we\u2019ve finished looping through all the keys in the second Dictionary, we check to see if the strNewItems is anything <i>but<\/i> an empty string:<\/p>\n<pre class=\"codeSample\">If strNewItems &lt;&gt; \"\" Then\n<\/pre>\n<p>If that\u2019s true, that means that we have new folder names to add to our text file. Consequently, we execute these three lines of code:<\/p>\n<pre class=\"codeSample\">Set objFile = objFSO.OpenTextFile(\"C:\\Scripts\\Test.txt\", ForAppending)\nobjFile.Write strNewItems\nobjFile.Close\n<\/pre>\n<p>Here we\u2019re simply opening our text file (C:\\Scripts\\Test.txt) for appending. We call the <b>Write<\/b> method to add the value of strNewItems to the end of the file, then call the <b>Close<\/b> method to close the text file once and for all. And that, as they say in movie business, is a wrap.<\/p>\n<p>We hope that takes care of your problem, SW. Incidentally, if any of you are still not sure whether or not you\u2019ll enter this year\u2019s Scripting Games, well, consider this email we recently received from an old friend of ours:<\/p>\n<table id=\"EMEAC\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td>\n<p class=\"lastInCell\">\u201cWe are looking forward to the Games again this year.&nbsp;We\u2019ve already started preparing for them by drinking heavily and polishing our bobbleheads.\u201d<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>There you have it: drinking heavily and polishing their bobbleheads. And remember, those guys are simply <i>training<\/i> for the Games. Imagine how much fun they\u2019ll have once the Games actually begin. See you all February 15<sup>th<\/sup>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I have a script that reads through a text file and then checks a folder to see if all the subfolder names listed in that text file actually exist. (For example, if the parent folder is C:\\Scripts the script might check to see if a folder named Test Folder \u2013 that is, [&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":[3,4,14,5],"class_list":["post-56373","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-scripting-techniques","tag-text-files","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I have a script that reads through a text file and then checks a folder to see if all the subfolder names listed in that text file actually exist. (For example, if the parent folder is C:\\Scripts the script might check to see if a folder named Test Folder \u2013 that is, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/56373","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=56373"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/56373\/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=56373"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=56373"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=56373"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}