{"id":71003,"date":"2004-11-15T14:20:00","date_gmt":"2004-11-15T14:20:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2004\/11\/15\/can-i-lock-a-workstation-using-a-script\/"},"modified":"2004-11-15T14:20:00","modified_gmt":"2004-11-15T14:20:00","slug":"can-i-lock-a-workstation-using-a-script","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/can-i-lock-a-workstation-using-a-script\/","title":{"rendered":"Can I Lock a Workstation Using a Script?"},"content":{"rendered":"<p><IMG 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\"> \n<P>Hey, Scripting Guy! I know how I can shut down a computer using a script, and I even know how I can log a user off using a script. But is there any way I can <I>lock<\/I> a workstation using a script?<BR><BR>&#8212; TO-R<\/P><IMG height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\"><IMG 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 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> \n<P>Hey, TO-R. Most likely you\u2019re familiar with the Win32Shutdown method found in the WMI class Win32_OperatingSystem; that method allows you to shutdown or reboot a computer, or log off the current user. For example, this script shuts down a computer:<\/P><PRE class=\"codeSample\">Const SHUTDOWN = 1<\/p>\n<p>strComputer = &#8220;.&#8221;\nSet objWMIService = GetObject_\n    (&#8220;winmgmts:{impersonationLevel=impersonate,(Shutdown)}\\\\&#8221; &amp; _\n        strComputer &amp; &#8220;\\root\\cimv2&#8221;)<\/p>\n<p>Set colOperating Systems = objWMIService.ExecQuery _\n    (&#8220;Select * from Win32_OperatingSystem&#8221;)<\/p>\n<p>For Each objOperatingSystem in colOperatingSystems\n    objOperatingSystem.Win32Shutdown(SHUTDOWN)\nNext\n<\/PRE>\n<P>What the Win32Shutdown method won\u2019t let you do is lock a computer; as near as we can tell <I>nothing<\/I> within WMI allows you to lock a computer. In fact, the only way we could figure out how to lock a computer using a script was to write a script that did nothing more than use Rundll32.exe to call the LockWorkStation method of user32.dll: <\/P><PRE class=\"codeSample\">On Error Resume Next<\/p>\n<p>Set objShell = CreateObject(&#8220;Wscript.Shell&#8221;)\nobjShell.Run &#8220;%windir%\\System32\\rundll32.exe user32.dll,LockWorkStation&#8221;\n<\/PRE>\n<P>This works great for the local computer, but doesn\u2019t do you much good if you\u2019re trying to lock a remote computer; you can\u2019t specify a remote computer name when running Rundll32.exe. But that\u2019s OK: if this script only runs locally, then all we have to do is make sure it runs locally <I>on the remote computer<\/I>. Can we do such a thing? You bet we can.<\/P>\n<P>First, save the preceding script &#8211; the one that actually locks the computer &#8211; as Lock_workstation.vbs and &#8211; for simplicity\u2019s sake &#8211; save it to C:\\Scripts. Next, create a second script &#8211; give it any name you want &#8211; and paste this code into it:<\/P><PRE class=\"codeSample\">Const OverwriteExisting = TRUE<\/p>\n<p>Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nobjFSO.CopyFile &#8220;C:\\Scripts\\lock_workstation.vbs&#8221;, _\n    &#8220;\\\\atl-ws-01\\C$\\Scripts\\&#8221;, OverWriteExisting<\/p>\n<p>strComputer = &#8220;atl-ws-01&#8221;\nSet objWMIService = GetObject _\n(&#8220;winmgmts:\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\cimv2:Win32_Process&#8221;)<\/p>\n<p>Error = objWMIService.Create _\n    (&#8220;cscript c:\\scripts\\lock_workstation.vbs&#8221;, null, null, _\n        intProcessID)\n<\/PRE>\n<P>What does this code do? Well, to begin with, it copies our first script &#8211; C:\\Scripts\\Lock_workstation.vbs &#8211; to the C:\\Scripts folder on the remote computer atl-ws-01. Two things to keep in mind here. First, the script assumes that you haven\u2019t disabled the administrative share (C$) on the remote computer; second, it assumes that the folder C:\\Scripts exists in the remote computer. (Of course, there\u2019s no reason why the file has to be copied to C:\\Scripts; you can copy it to any folder you want.)<\/P>\n<P>After the first part of the script executes, the file Lock_workstation.vbs will be sitting in the C:\\Scripts folder on the remote computer. In the second part of the script, we connect to the WMI service on the remote computer, and then call the Create method (which happens to be part of the Win32_Process class). And what exactly do we <I>do<\/I> with the Create method? Well, we simply run the script Lock_workstation.vbs. What\u2019s cool about that, however, is that the Create method will cause the script to run <I>on the remote machine<\/I>. And because the script is running on the remote machine, Rundll32.exe will work, and the remote computer will be locked. Give it a try, and you\u2019ll see for yourself.<\/P>\n<P><B>Note<\/B>. One caveat: this script runs under the security context of the user logged on the remote computer. If that user doesn\u2019t have the right to lock the computer, then the script will fail.<\/P>\n<P>Of course, this is bound to raise at least two questions. Let\u2019s take the easy one first: can you write a script that <I>unlocks<\/I> a workstation? As far as we know, you can\u2019t; in fact, as far as we know the only way to unlock a workstation is to have someone go to the computer, press Ctrl-Alt-Delete and log on. On the bright side, though, you can still run scripts against a locked workstation; after all, a locked computer is still up and running.<\/P>\n<P>The second question is a bit trickier: is there any way to tell whether or not a computer actually <I>is<\/I> locked? Well, there\u2019s no foolproof way, at least not that we\u2019re aware of. But here\u2019s a script that <I>can<\/I> work, as long as:<\/P>\n<P>1. The remote computer is configured to use a screensaver. <\/P>\n<P>2. The workstation is automatically locked any time the screensaver is running. <\/P>\n<P>3. The \u201ctimeout\u201d period has elapsed and the screensaver is actually running. (For example, by default the screensaver doesn\u2019t start up until a computer has been inactive &#8211; or locked &#8211; for ten minutes.)<\/P>\n<P>If all the above are true, this script can tell you if the computer is locked; it does that by grabbing the executable file name for the screen saver, and then checking to see if that executable file is running (by looking at instances of the Win32_Process class). If the screensaver is running then, by definition, the computer must be locked:<\/P><PRE class=\"codeSample\">On Error Resume Next\nHKEY_CURRENT_USER = &amp;H80000001<\/p>\n<p>strComputer = &#8220;crowtrobot2&#8221;<\/p>\n<p>Set objWMIService = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\default:StdRegProv&#8221;)<\/p>\n<p>strKeyPath = &#8220;Control Panel\\Desktop&#8221;\nValueName = &#8220;ScrnSave.exe&#8221;\nobjWMIService.GetStringValue HKEY_CURRENT_USER, strKeyPath, ValueName, strValue\nstrValue = Replace(strValue, &#8220;\\&#8221;, &#8220;\\\\&#8221;)<\/p>\n<p>Set objWMIService = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\cimv2&#8221;)<\/p>\n<p>Set colItems = objWMIService.ExecQuery _\n    (&#8220;Select * From Win32_Process Where ExecutablePath ='&#8221; &amp; strValue &amp; &#8220;&#8216;&#8221;)<\/p>\n<p>If colItems.Count &gt; 0 Then\n    Wscript.Echo &#8220;The computer is locked.&#8221;\nElse\n    Wscript.Echo &#8220;The computer is not locked.&#8221;\nEnd If\n<\/PRE>\n<P>Note that this script isn\u2019t quite as complicated as it looks; the one weird part is this line of code:<\/P><PRE class=\"codeSample\">strValue = Replace(strValue, &#8220;\\&#8221;, &#8220;\\\\&#8221;)\n<\/PRE>\n<P>That\u2019s needed because the ExecutablePath will be something like this:<\/P><PRE class=\"codeSample\">C:\\WINDOWS\\System32\\logon.scr\n<\/PRE>\n<P>However, when you use a path in a WMI query, you have to double up all your slashes, like so:<\/P><PRE class=\"codeSample\">C:\\\\WINDOWS\\\\System32\\\\logon.scr\n<\/PRE>\n<P>That\u2019s what the Replace function is doing: replacing each \\ with \\\\.<\/P>\n<P>Like we said, it\u2019s not exactly foolproof, but it\u2019s the best we\u2019ve been able to come up with so far. If you wanted to make it a little bit <I>more<\/I> bulletproof, you could add code that ensures that the computer is actually using a screensaver (ScreenSaverActive) and that the workstation automatically locks any time the screensaver is running (ScreenSaverSecure). If you wanted to get <I>really<\/I> fancy, you could even determine the screensaver timeout value (ScreenSaverTimeout), pause the script for that amount of time, and <I>then<\/I> check to see if the screensaver is running. <\/P>\n<P>Of course, even that wouldn\u2019t suffice in all cases: after all, this code won\u2019t distinguish between a computer that\u2019s locked and a computer where no one is logged on; it just tells us that the screensaver is running. Is there a way to tell whether or not any one is logged on to a computer? We\u2019re not really sure, to tell you the truth, but that\u2019s something we\u2019re looking into.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I know how I can shut down a computer using a script, and I even know how I can log a user off using a script. But is there any way I can lock a workstation using a script?&#8212; TO-R Hey, TO-R. Most likely you\u2019re familiar with the Win32Shutdown method found in [&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":[16,47,3,5],"class_list":["post-71003","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-desktop-management","tag-general-management-tasks","tag-scripting-guy","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I know how I can shut down a computer using a script, and I even know how I can log a user off using a script. But is there any way I can lock a workstation using a script?&#8212; TO-R Hey, TO-R. Most likely you\u2019re familiar with the Win32Shutdown method found in [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/71003","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=71003"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/71003\/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=71003"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=71003"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=71003"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}