{"id":55823,"date":"2008-04-09T00:55:00","date_gmt":"2008-04-09T00:55:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/04\/09\/hey-scripting-guy-how-can-i-retrieve-all-the-values-in-a-registry-key\/"},"modified":"2008-04-09T00:55:00","modified_gmt":"2008-04-09T00:55:00","slug":"hey-scripting-guy-how-can-i-retrieve-all-the-values-in-a-registry-key","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-retrieve-all-the-values-in-a-registry-key\/","title":{"rendered":"Hey, Scripting Guy! How Can I Retrieve All the Values in a Registry Key?"},"content":{"rendered":"<p><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" height=\"34\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/> <\/p>\n<p>Hey, Scripting Guy! Do you have a script that will enable me to enumerate all the values in a registry key?<br \/>&#8212; DG<\/p>\n<p><img decoding=\"async\" height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\" \/><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" height=\"34\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/><a href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><img decoding=\"async\" class=\"farGraphic\" title=\"Script Center\" height=\"288\" alt=\"Script Center\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" align=\"right\" border=\"0\" \/><\/a> <\/p>\n<p>Hey, DG. You know, this past weekend the Scripting Guy who writes this column went out to buy doughnuts, a process that took much longer than it should have. Why did it take so long just to buy doughnuts? Because the woman in line in front of him insisted on grilling the clerk about the nutritional value of each and every doughnut in the display case. \u201cSo,\u201d she mused at one point. \u201cWhat would you say is your healthiest option?\u201d<\/p>\n<p>Look, lady, you\u2019re in a <i>doughnut shop<\/i>, for crying out loud; your healthiest option would be to turn tail and run. Healthiest option? Good heavens, just walking into that shop probably took a year or two off your life. <\/p>\n<p>Sheesh.<\/p>\n<p>Anyway, the doughnut store clerk \u2013 who was far more patient and understanding than the Scripting Guy who writes this column \u2013 recommended the Blueberry Cake. Just for the heck of it, the Scripting Guy who writes this column looked up the nutritional value of a Blueberry Cake doughnut versus a traditional glazed doughnut. (Did he do all that on company time? Um, he \u2026 doesn\u2019t remember where, or how, he found this information \u2026.)<\/p>\n<p>Here\u2019s what he came up with:<\/p>\n<table class=\"dataTable\" id=\"ECD\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>&#8211;<\/b><\/p>\n<\/td>\n<td class=\"\">\n<p class=\"lastInCell\"><b>Blueberry Cake<\/b><\/p>\n<\/td>\n<td class=\"\">\n<p class=\"lastInCell\"><b>Glazed<\/b><\/p>\n<\/td>\n<\/tr>\n<tr class=\"evenRecord\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Calories<\/b><\/p>\n<\/td>\n<td class=\"\">\n<p class=\"lastInCell\">290<\/p>\n<\/td>\n<td class=\"\">\n<p class=\"lastInCell\">210<\/p>\n<\/td>\n<\/tr>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Total Fat<\/b><\/p>\n<\/td>\n<td class=\"\">\n<p class=\"lastInCell\">16 grames<\/p>\n<\/td>\n<td class=\"\">\n<p class=\"lastInCell\">10 grams<\/p>\n<\/td>\n<\/tr>\n<tr class=\"evenRecord\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Calories From Fat<\/b><\/p>\n<\/td>\n<td class=\"\">\n<p class=\"lastInCell\">140<\/p>\n<\/td>\n<td class=\"\">\n<p class=\"lastInCell\">90<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>In other words, the Blueberry Cake is actually a <i>less<\/i> healthy option than the glazed doughnut. Does that mean that the clerk made an honest mistake, or was he trying to get the lady to eat a Blueberry Cake doughnut, hoping maybe that she would drop dead on the spot and then never come back in just to ask silly questions about which doughnut is the healthiest option? Beats us; all the Scripting Guy who writes this column wanted to do was get his dozen doughnuts (all cake doughnuts) and go home. <\/p>\n<p>The truth is, if you\u2019re looking for healthy options the doughnut shop is not the best place to look. Instead, the best place to look is the Script Center, where we have all sorts of healthy options, like a script that can enumerate all the values (and the values of those values) found in a registry key. Enjoy this in good health:<\/p>\n<pre class=\"codeSample\">Const HKEY_CURRENT_USER = &amp;H80000001\n\nConst REG_SZ = 1\nConst REG_EXPAND_SZ = 2\nConst REG_BINARY = 3\nConst REG_DWORD = 4\nConst REG_MULTI_SZ = 7\n \nstrComputer = \".\"\n \nSet objRegistry = GetObject(\"winmgmts:\\\\\" &amp; strComputer &amp; \"\\root\\default:StdRegProv\")\n \nstrKeyPath = \"Software\\Microsoft\\Internet Explorer\\Main\"\nobjRegistry.EnumValues HKEY_CURRENT_USER, strKeyPath, arrValueNames, arrValueTypes\n \nFor i = 0 to UBound(arrValueNames)\n    strText = arrValueNames(i)   \n    strValueName = arrValueNames(i)\n\n    Select Case arrValueTypes(i)\n        Case REG_SZ\n            objRegistry.GetStringValue HKEY_CURRENT_USER,strKeyPath, strValueName,strValue \n            strText = strText &amp; \": \"  &amp; strValue\n        Case REG_DWORD\n            objRegistry.GetDWORDValue HKEY_CURRENT_USER,strKeyPath, strValueName, intValue    \n            strText = strText &amp; \": \"  &amp; intValue\n        Case REG_MULTI_SZ\n            objRegistry.GetMultiStringValue HKEY_CURRENT_USER,strKeyPath, strValueName,arrValues  \n            strText = strText &amp; \": \"\n            For Each strValue in arrValues\n                strText = strText &amp; \"   \" &amp; strValue \n            Next  \n        Case REG_EXPAND_SZ\n            objRegistry.GetExpandedStringValue HKEY_CURRENT_USER,strKeyPath, strValueName,strValue    \n            strText = strText &amp; \": \"  &amp; strValue\n       Case REG_BINARY\n            objRegistry.GetBinaryValue HKEY_CURRENT_USER,strKeyPath, strValueName,arrValues    \n            strText = strText &amp; \": \"\n            For Each strValue in arrValues\n                strText = strText &amp; \" \" &amp; strValue \n            Next  \n        End Select \n\n    Wscript.Echo strText\nNext\n<\/pre>\n<p>So how does that script, useful as it might be, make you <i>healthy<\/i>? Hey, what do we look like: doctors? We can\u2019t explain how the script makes you healthy; it just does.<\/p>\n<p>Or at least it doesn\u2019t making you any <i>less<\/i> healthy.<\/p>\n<p>As far as we know, anyway.<\/p>\n<p>You know what? Let\u2019s set all this medical mumbo-jumbo aside for a moment and see if we can figure out how this all works. As you can see, we start out by defining a whole bunch of constants. We\u2019ll use HKEY_CURRENT_USER to tell the script which registry hive we want to work with; we\u2019ll use the other constants to determine the data type of the individual registry values we run into. For example, in WMI a registry value that has a data type of 1 happens to be a value with the REG_SZ data type. Consequently, we assign the value 1 to the constant REG_SZ:<\/p>\n<pre class=\"codeSample\">Const REG_SZ = 1\n<\/pre>\n<p>Seems reasonable \u2013 and healthy \u2013 enough, doesn\u2019t it?<\/p>\n<p>After defining all our constants we next connect to the WMI service on the local computer. And yes, we <i>can<\/i> run this very same script against a remote computer; all we have to do is assign the name of that remote machine to the variable strComputer:<\/p>\n<pre class=\"codeSample\">strComputer = \".\"\n<\/pre>\n<p>While we\u2019re at it you should take a closer look at our WMI connection string:<\/p>\n<pre class=\"codeSample\">Set objRegistry = GetObject(\"winmgmts:\\\\\" &amp; strComputer &amp; \"\\root\\default:StdRegProv\")\n<\/pre>\n<p>Keep two things in mind when it comes to this connection string. First, note that we connect to the <b>root\\default<\/b> namespace. That\u2019s a little unusual; when writing WMI scripts we typically connect to the root\\cimv2 namespace. Note also that we bind directly to the <b>StdRegProv<\/b> class; that\u2019s because all the registry methods are \u201cstatic\u201d methods, which means that they operate against the class as a whole rather than individual instances of the class.<\/p>\n<table class=\"dataTable\" id=\"EYF\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Note<\/b>. Don\u2019t worry too much about all that. We\u2019re just trying to show off a little. Speaking of which, did you know that in 1998 Winchell\u2019s Doughnuts created a doughnut that weighed over 5,000 pounds, and measured 95 feet in diameter? Sadly enough, however, this doughnut never made it onto the regular menu.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>After we connect to the WMI service we use this line of code to assign the desired registry path (within the HKEY_CURRENT_USER hive) to a variable named strKeyPath:<\/p>\n<pre class=\"codeSample\">strKeyPath = \"Software\\Microsoft\\Internet Explorer\\Main\"\n<\/pre>\n<p>As soon as that\u2019s done we can use the <b>EnumValues<\/b> method to retrieve a collection of all the registry values found within that registry key:<\/p>\n<pre class=\"codeSample\">objRegistry.EnumValues HKEY_CURRENT_USER, strKeyPath, arrValueNames, arrValueTypes\n<\/pre>\n<p>This is the part where things start to get a little goofy. To begin with, we need to note that the EnumValues method will return the names and data types of all the values found in a given registry key. (But not the values found in any subkeys of that registry key; you\u2019ll have to write a <a href=\"http:\/\/technet.microsoft.com\/en-us\/magazine\/cc160952.aspx\" target=\"_blank\"><b>recursive function<\/b><\/a> to do that.) For example, our sample script will tell us that the Main registry key includes a registry value named <i>Anchor Underline<\/i>, and that Anchor Underline has a data type of REG_SZ. That\u2019s cool, but is Anchor Underline set to <i>yes<\/i>, or is Anchor Underline set to <i>no<\/i>? Well, that\u2019s something EnumValues <i>won\u2019t<\/i> tell us. We\u2019re going to have to figure that out for ourselves.<\/p>\n<p>But don\u2019t despair; as long as we know the value names and data types figuring out the actual values isn\u2019t too terribly difficult. (A little cumbersome, perhaps, but not too terribly difficult.) You might have noticed that when we called EnumValues we supplied the method with four parameters:<\/p>\n<table class=\"\" cellSpacing=\"0\" cellPadding=\"0\" border=\"0\">\n<tbody>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p><b>HKEY_CURRENT_USER<\/b>, the constant that tells the script which registry hive to work with.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p><b>strKeyPath<\/b>, the variable that tells the script which registry key to work with.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p><b>arrValuesNames<\/b>, an \u201cout\u201d parameter that EnumValues will fill with the names of each value found in the registry key. An out parameter is simply a parameter that holds data returned by a method. We give EnumValues a variable name, and EnumValues returns the names of all the registry values and assigns that information to our out parameter.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p><b>arrValueTypes<\/b>, another out parameter, this one designed to hold the data types of each value found in the registry key.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>So what do we do with all the information returned by EnumValues? Well, to begin with, we set up a For Next loop that walks us through the array of value names (arrValueNames):<\/p>\n<pre class=\"codeSample\">For i = 0 to UBound(arrValueNames)\n<\/pre>\n<p>Inside that loop, we take the name of the first registry value and assign it to a pair of variables:<\/p>\n<pre class=\"codeSample\">strText = arrValueNames(i)   \nstrValueName = arrValueNames(i)\n<\/pre>\n<p>We\u2019re going to use the variable strText to hold both the name of each registry value and \u2013 as soon as we\u2019ve retrieved it \u2013 the value of each registry value. Meanwhile, we\u2019ll use strValueName to represent this particular value when we try to retrieve, well, the value of that value.<\/p>\n<table class=\"dataTable\" id=\"E2H\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Note<\/b>. Is it possible to use the word <i>value<\/i> more times in a single sentence? Let\u2019s hope not.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>Any time we need to read from the registry the Scripting Guys always use WMI rather than Windows Script Host. Why? Well, it\u2019s not because WMI is easier to use; in fact, WMI is considerably more difficult to use than WSH. That\u2019s because WMI requires you to use a different method for each registry data type. Have a value with the data type REG_SZ? Then you need to use the GetStringValue method. Have a value with the data type REG_DWORD? The you need to use the GetDWORDValue method. By contrast, WSH enables you to read <i>any<\/i> data type using a single method: RegRead.<\/p>\n<p>So then why do we always use WMI rather than WSH? One reason and one reason only: WMI lets us read the registry off a remote computer. WSH doesn\u2019t allow for that.<\/p>\n<p>At any rate, the fact that, with WMI, different data types require different methods explains this next line of code:<\/p>\n<pre class=\"codeSample\">Select Case arrValueTypes(i)\n<\/pre>\n<p>What we\u2019re doing here is examining the data type of the first registry value. Let\u2019s assume that this value has the data type REG_SZ (remember, we defined a constant named REG_SZ way back at the beginning of the script). In that case, we\u2019re going to use the <b>GetStringValue<\/b> method to read the value from the registry and then add the value to the variable strText:<\/p>\n<pre class=\"codeSample\">Case REG_SZ\n    objRegistry.GetStringValue HKEY_CURRENT_USER,strKeyPath, strValueName,strValue\n       strText = strText &amp; \": \"  &amp; strValue\n<\/pre>\n<p>Needless to say, if our value has a different data type then we\u2019ll use a different method. You might note as well that both GetMultiStringValue and GetBinaryValue return data in the form of an array. That means we need to set up a For Each loop to get at all the values in that array:<\/p>\n<pre class=\"codeSample\">Case REG_MULTI_SZ\n    objRegistry.GetMultiStringValue HKEY_CURRENT_USER,strKeyPath, strValueName,arrValues  \n    strText = strText &amp; \": \"\n        For Each strValue in arrValues\n            strText = strText &amp; \"   \" &amp; strValue \n        Next\n<\/pre>\n<p>After echoing back the value of strText, it\u2019s back to the top of the loop, where we repeat the process with the next name in the array arrValueNames. When all is said and done we should have output that looks something like this:<\/p>\n<pre class=\"codeSample\">NoUpdateCheck: 1\nNoJITSetup: 1\nDisable Script Debugger: no\nShow_ChannelBand: No\nAnchor Underline: yes\nCache_Update_Frequency: Once_Per_Session\nDisplay Inline Images: yes\n<\/pre>\n<p>Etc., etc.<\/p>\n<p>That should do it, DG; let us know if you have any questions. Incidentally, did you notice that researchers have now decided that the old maxim that everyone should drink 8 glass of water each day no longer, well, no longer holds any water? According to an editorial in the <a href=\"http:\/\/www.asn-online.org\/press\/pdf\/2008-Media\/Water%20Study.pdf\" target=\"_blank\"><b><i>Journal of the American Society for Nephrology<\/i><\/b><\/a> (of course we subscribe to this; doesn\u2019t everybody?) this misconception is due, in part, to a misreading of a 1945 report from the Food and Nutrition Board, which stated:<\/p>\n<table class=\"dataTable\" id=\"EFBAC\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\">A suitable allowance of water for adults is 2.5 liters daily in most instances. An ordinary standard for diverse persons is 1 milliliter for each calorie of food. Most of this quantity is contained in prepared foods.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>If you read all three sentences in that paragraph you\u2019ll see that you can get most of your daily allowance of water just by eating. But, Americans being Americans, who could be bothered to read all three sentences? People had a tendency to read just the first sentence and ignore the rest. Thus was born the myth that people need to drink 8 glasses of water a day.<\/p>\n<table class=\"dataTable\" id=\"EOBAC\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Note<\/b>. OK, so there\u2019s actually a little more to the story than that, but we can\u2019t be bothered to write down all the details. Hey, what do we look like: professional writers?<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>So why do we mention the 8-glasses-of-water-a-day thing? Well, health care practitioners were wrong when they said we needed 8 glasses of water a day. So does that mean that, instead of 8 glasses of water, we\u2019re supposed to have 8 <i>doughnuts<\/i> a day? Let\u2019s just say that the Scripting Guys are keeping our fingers crossed.<\/p>\n<p>Well, OK: keeping our <i>pudgy<\/i> fingers crossed.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! Do you have a script that will enable me to enumerate all the values in a registry key?&#8212; DG Hey, DG. You know, this past weekend the Scripting Guy who writes this column went out to buy doughnuts, a process that took much longer than it should have. Why did it take [&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":[31,26,3,5],"class_list":["post-55823","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-operating-system","tag-registry","tag-scripting-guy","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! Do you have a script that will enable me to enumerate all the values in a registry key?&#8212; DG Hey, DG. You know, this past weekend the Scripting Guy who writes this column went out to buy doughnuts, a process that took much longer than it should have. Why did it take [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55823","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=55823"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55823\/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=55823"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=55823"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=55823"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}