{"id":55383,"date":"2008-06-11T02:05:00","date_gmt":"2008-06-11T02:05:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/06\/11\/hey-scripting-guy-how-can-i-get-a-script-to-pick-up-where-it-left-off-after-a-reboot\/"},"modified":"2008-06-11T02:05:00","modified_gmt":"2008-06-11T02:05:00","slug":"hey-scripting-guy-how-can-i-get-a-script-to-pick-up-where-it-left-off-after-a-reboot","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-get-a-script-to-pick-up-where-it-left-off-after-a-reboot\/","title":{"rendered":"Hey, Scripting Guy! How Can I Get a Script to Pick Up Where It Left Off After a Reboot?"},"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 would like to write a script, with a number of sequential actions, that can continue where it left off after a reboot. How can I do that?<br \/>&#8212; GS<\/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, GS. By the way, what are you doing at 10:00 AM Eastern Daylight Time today? Nothing? Great; then we\u2019ll see you at the Orange County Convention Center for our 10:00 instructor-led lab <i>Windows PowerShell for VB<\/i><i>Scripter<\/i><i>s<\/i>. Should be fun, huh?<\/p>\n<table id=\"ECD\" 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, we understand that you might not be able to make it for the 10:00 lab; after all, this <i>is<\/i> kind of short notice. But hey, no problem; after all, we\u2019ll be repeating the lab at 1:00 PM this afternoon. And yes, that means that you have <i>two<\/i> chances to see the Scripting Guys in person, which is two more chances than most people ever get.<\/p>\n<p>Or ever want.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>At the moment the Scripting Guys are gathering up their things and preparing to head down to the Orange County Convention Center. (Well, if you want to get technical, Scripting Guy Jean Ross is gathering up <i>her<\/i> things and preparing to head down to the Orange County Convention Center. Meanwhile, Scripting Guy Greg Stemp has snuck back down to the hotel\u2019s breakfast buffet for more chocolate-filled croissants.) Will this instructor-led lab stand as the most exciting thing to ever happen to the city of Orlando? Well, that\u2019s a bit hard to say; after all, Orlando <i>is<\/i> the home to everything from Disney World to Universal Studios to Sea World. But yes, yes it will.<\/p>\n<p>Of course, we realize that some of you aren\u2019t going to be able to make it to our instructor-led lab. If you\u2019re one of those people, well, the heck with you. You don\u2019t want to come to our instructor-led lab? Fine; then we\u2019re not going to <i>your<\/i> instructor-led lab. Take <i>that<\/i>, wise guy!<\/p>\n<p>Could we put you on hold for a second here? OK, Scripting Guy Jean Ross has pointed out a minor typo in the preceding paragraph. As it turns out, that paragraph <i>should<\/i> read, \u201cOf course, we realize that some of you aren\u2019t going to be able to make it to our instructor-led lab. If you\u2019re one of those people, well, that\u2019s fine; we understand. And, as it turns out, you won\u2019t be missing all that much anyway; after all, we\u2019ve updated our <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/topics\/winpsh\/convert\/default.mspx\"><b>VBScript to Windows PowerShell Conversion Guide<\/b><\/a> as part of the TechEd festivities, and those updates (new sections on the FileSystemObject and Windows Script Host) are available online. In addition, we\u2019re also planning to show you a script that can continue \u2013 from the proper spot in the code \u2013 following a required reboot of the computer.\u201d<\/p>\n<p>That\u2019s what we <i>meant<\/i> to say.<\/p>\n<table id=\"EUE\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td>\n<p><b>Note<\/b>. Is that <i>really<\/i> what we meant to say? Hey, who cares? As long as they keep these chocolate-filled croissants coming we\u2019re willing to say pretty much <i>anything<\/i>. For example, \u201cJean Ross is a far better and far more valuable Scripting Guy than Greg Stemp.\u201d<\/p>\n<p>See? Like we said, pretty much <i>anything<\/i>.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>So what <i>about<\/i> a script that can continue, from the proper spot in the code, following a reboot of the computer? Well, try this one on for size:<\/p>\n<pre class=\"codeSample\">Const HKEY_CURRENT_USER = &amp;H80000001\n \nstrComputer = \".\"\n \nSet objRegistry = GetObject(\"winmgmts:\\\\\" &amp; strComputer &amp; \"\\root\\default:StdRegProv\")\n\nstrKeyPath = \"Software\\My Scripts\"\nstrValue = \"Test Script\"\n \nobjRegistry.GetStringValue HKEY_CURRENT_USER,strKeyPath,strValue,strScriptStatus\n\nIf IsNull(strScriptStatus) Then\n    strScriptStatus = \"Run\"\n    objRegistry.CreateKey HKEY_CURRENT_USER,strKeyPath\n    objRegistry.SetStringValue HKEY_CURRENT_USER,strKeyPath,strValue,strScriptStatus\n    Wscript.Echo \"The script is running for the first time.\"\n    strNewKeyPath = \"Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\"\n    strNewValue = \"Test Script\"\n    strScriptPath = \"cmd.exe \/k cscript.exe C:\\Scripts\\Test.vbs\"\n    objRegistry.SetStringValue HKEY_CURRENT_USER,strNewKeyPath,strNewValue,strScriptPath\n    Wscript.Quit\nEnd If\n\nWscript.Echo \"The script is running for the second time.\"\nobjRegistry.DeleteKey HKEY_CURRENT_USER,strKeyPath\n<\/pre>\n<p>Yes, this is sort of an odd-looking little script, isn\u2019t it? Does any of it make sense, and, more important, does it actually work? Let\u2019s find out.<\/p>\n<p>As you can see, we kick things off by defining a constant named HKEY_CURRENT_USER and setting the value to &amp;H80000001; we\u2019ll need this constant to tell the script which registry hive we want to work with.<\/p>\n<table id=\"ESF\" 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>. Does that mean this script is going to work with the registry? Hold on a second and we\u2019ll check on that \u2026 yes, as a matter of fact this script <i>is<\/i> going to work with the registry.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>After defining the constant we connect to the WMI service on the local computer; in particular we connect to the <b>default<\/b> namespace and the <b>StdRegProv<\/b> class:<\/p>\n<pre class=\"codeSample\">Set objRegistry = GetObject(\"winmgmts:\\\\\" &amp; strComputer &amp; \"\\root\\default:StdRegProv\")<\/pre>\n<p>Once that\u2019s done we go ahead and assign values to a pair of variables. The variable strKeyPath is assigned a path within the HKEY_CURRENT_USER portion of the registry; to be more specific, it gets assigned the path <b>Software\\My Scripts<\/b>. Meanwhile, the variable strValue is assigned the name of a registry value (<b>Test Script<\/b>) within that registry path.<\/p>\n<p>Why do we bother with all that? Because we can then use the <b>GetStringValue<\/b> method to read the value of Test Script from the registry:<\/p>\n<pre class=\"codeSample\">objRegistry.GetStringValue HKEY_CURRENT_USER,strKeyPath,strValue,strScriptStatus<\/pre>\n<p>As you can see, we simply call GetStringValue, passing along the constant HKEY_CURRENT_USER; the variable strKeyPath; the variable strValue; and an \u201cout parameter\u201d named strScriptStatus. What\u2019s an out parameter? Well, when you call a method you usually supply information to that method; any information you supply to a method is known as an \u201cin parameter.\u201d Every now and then, however, a method will actually return information back to <i>you<\/i>; in that case, you\u2019re dealing with an out parameter. When working with the GetStringValue method, we supply a variable name (strScriptStatus) and GetStringValue responds by assigning the value of the registry item in question (Software\\My Scripts\\Test Script) to that variable.<\/p>\n<p><i>That\u2019s<\/i> what an out parameter is.<\/p>\n<p>Of course, some of you might be panicking a bit by now. \u201cWait a second, Scripting Guy who writes that column,\u201d you\u2019re thinking. \u201cI don\u2019t even <i>have<\/i> a registry value named Software\\My Scripts\\Test Script!\u201d That\u2019s fine; in fact, we don\u2019t <i>want<\/i> you to have a registry value named Software\\My Scripts\\Test Script.<\/p>\n<p>Don\u2019t worry; we\u2019re going to explain what we mean by that. The first time this script runs it uses the GetStringValue method to retrieve the value of Software\\My Scripts\\Test Script. If this registry value doesn\u2019t exist, well, no problem; in that case our out parameter \u2013 strScriptStatus \u2013 will simply be assigned a Null value. More importantly, our script will know that this is the first time it has run on this computer. This is how we keep track of where we are; that is, is this script running before the required reboot or after the required reboot? If the registry value Software\\My Scripts\\Test Script doesn\u2019t exist then that means we must be running <i>before<\/i> the reboot. Otherwise that value <i>would<\/i> exist.<\/p>\n<p>Let\u2019s assume that strScriptStatus <i>is<\/i> Null, something we verify using this line of code:<\/p>\n<pre class=\"codeSample\">If IsNull(strScriptStatus) Then<\/pre>\n<p>What do we do now?<\/p>\n<p>Well, for one thing, we execute these three lines of code:<\/p>\n<pre class=\"codeSample\">strScriptStatus = \"Run\"\nobjRegistry.CreateKey HKEY_CURRENT_USER,strKeyPath\nobjRegistry.SetStringValue HKEY_CURRENT_USER,strKeyPath,strValue,strScriptStatus\n<\/pre>\n<p>In the first line we\u2019re simply assigning a new value (<i>Run<\/i>) to the variable strScriptStatus. After making that assignment we use the <b>CreateKey<\/b> method to create the registry key Software\\My Scripts. Once that\u2019s done we use the <b>SetStringValue<\/b> method to both create the registry value Test Script and to assign it the value of the variable strScriptStatus.<\/p>\n<p>You\u2019re right: we <i>did<\/i> manage to accomplish quite a bit in just three lines of code, didn\u2019t we? Cool.<\/p>\n<p>As it turns out, our next line of code is just filler material:<\/p>\n<pre class=\"codeSample\">Wscript.Echo \"The script is running for the first time.\"\n<\/pre>\n<p>All we\u2019re doing here is echoing back the fact that the script is running for the first time. Like we said, this is just filler material; in a <i>real<\/i> script you\u2019d use this space to carry out all the tasks that need to be carried out before the computer reboots. We didn\u2019t want to distract anyone from the main purpose of this sample script, so we didn\u2019t include any tasks other than echoing back a simple little message.<\/p>\n<p>As soon as all our tasks are complete we then run this block of code:<\/p>\n<pre class=\"codeSample\">strNewKeyPath = \"Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\"\nstrNewValue = \"Test Script\"\nstrScriptPath = \"cmd.exe \/k cscript.exe C:\\Scripts\\Test.vbs\"\nobjRegistry.SetStringValue HKEY_CURRENT_USER,strNewKeyPath,strNewValue,strScriptPath\n<\/pre>\n<p>Here&nbsp;we\u2019re adding a new value to the Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce registry key; by design, anything that appears in this key will automatically run the next time the user logs on. (However, it will run only one time, then be deleted from the key.) We\u2019re simply creating a new value named Test Script, and assigning it a command that induces our script (Test.vbs) to run the next time the user logs on:<\/p>\n<pre class=\"codeSample\">strScriptPath = \"cmd.exe \/k cscript.exe C:\\Scripts\\Test.vbs\"<\/pre>\n<table id=\"EVAAC\" 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 wondering about the syntax, we\u2019re calling Cmd.exe with the <b>\/k<\/b> parameter; that causes a command window to open up and remain open even after the script finishes running. We then call Cscript.exe (to ensure that the script runs under the CScript script host) followed by the path to the script itself.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>From there we simply exit the script; in a real script, however, this is the spot where you would put in the code that causes the computer to reboot.<\/p>\n<p>So what happens when the computer <i>does<\/i> reboot? (Or, in our test scenario, what happens the <i>second<\/i> time you run the script?) Well, as it did the first time around, the script checks the value of Software\\My Scripts\\Test Script. This time, of course, Test Script will actually <i>have<\/i> a value. Therefore, we skip the If Then statement and instead run these two lines of code:<\/p>\n<pre class=\"codeSample\">Wscript.Echo \"The script is running for the second time.\"\nobjRegistry.DeleteKey HKEY_CURRENT_USER,strKeyPath\n<\/pre>\n<p>Again, line 1 is just filler; this is the spot where you\u2019d put the commands you want to execute after the reboot. And then, just to clean things up, we delete the registry key Software\\My Scripts. Doing that enables us to rerun the entire script if need be. If you want the script to run once \u2013 and <i>only<\/i> once \u2013 on a computer then you might leave the registry key in place and, instead, change the value of Test Script to <i>Don\u2019t run<\/i>. You can then modify the script so that it simply terminates if the variable strScriptStatus is equal to <i>Don\u2019t run<\/i>.<\/p>\n<p>But we\u2019ll let you deal with that one yourself. Right now it\u2019s time for the Scripting Guys to head down to the Convention Center. See you all tomorrow!<\/p>\n<p>You know what? We\u2019ll just grab a couple more chocolate-filled croissants. <i>Then<\/i> we\u2019ll head down to the Convention Center.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I would like to write a script, with a number of sequential actions, that can continue where it left off after a reboot. How can I do that?&#8212; GS Hey, GS. By the way, what are you doing at 10:00 AM Eastern Daylight Time today? Nothing? Great; then we\u2019ll see you at [&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":[2,3,4,5],"class_list":["post-55383","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-running","tag-scripting-guy","tag-scripting-techniques","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I would like to write a script, with a number of sequential actions, that can continue where it left off after a reboot. How can I do that?&#8212; GS Hey, GS. By the way, what are you doing at 10:00 AM Eastern Daylight Time today? Nothing? Great; then we\u2019ll see you at [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55383","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=55383"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55383\/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=55383"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=55383"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=55383"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}