{"id":67943,"date":"2006-02-16T11:26:00","date_gmt":"2006-02-16T11:26:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2006\/02\/16\/how-can-i-determine-which-account-a-script-is-running-under\/"},"modified":"2006-02-16T11:26:00","modified_gmt":"2006-02-16T11:26:00","slug":"how-can-i-determine-which-account-a-script-is-running-under","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-determine-which-account-a-script-is-running-under\/","title":{"rendered":"How Can I Determine Which Account a Script is Running Under?"},"content":{"rendered":"<p><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\"> \n<P>Hey, Scripting Guy! How can I determine which account a script is running under?<BR><BR>&#8212; KW<\/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, KW. You know, it\u2019s been awhile since we started off a column with a bunch of excuses, and that\u2019s been hard on us: after all, making excuses is what we Scripting Guys do best. With that in mind, then, let\u2019s start off with one of our favorite excuses: the script we\u2019re about to show you works only on Windows XP and Windows Server 2003. We\u2019ll show you a way to kind of, sort of do this same thing on Windows 2000, but it\u2019s definitely not as good.<\/P>\n<P>Ah, yes: now <I>that<\/I> felt good.<\/P>\n<P>OK, no more excuses (for now, at least). Instead, let\u2019s talk scripting. Here\u2019s what the script looks like:<\/P><PRE class=\"codeSample\">strComputer = &#8220;.&#8221;\nSet objWMIService = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\cimv2&#8221;)<\/p>\n<p>Set colProcessList = objWMIService.ExecQuery(&#8220;Select * from Win32_Process Where &#8221; &amp; _\n    &#8220;Name = &#8216;cscript.exe&#8217; or Name = &#8216;wscript.exe'&#8221;)<\/p>\n<p>For Each objProcess in colProcessList\n    If InStr(objProcess.CommandLine, &#8220;test.vbs&#8221;) Then\n        colProperties =   objProcess.GetOwner(strNameOfUser,strUserDomain)\n        Wscript.Echo &#8220;This script is running under the account belonging to &#8221; _ \n            &amp; strUserDomain &amp; &#8220;\\&#8221; &amp; strNameOfUser &amp; &#8220;.&#8221;\n    End If\nNext\n<\/PRE>\n<P>As you can see, we begin by connecting to the WMI service on the local computer, although this same script could just as easily be targeted against a remote machine. (Yes, we <I>do<\/I> say that a lot. But that isn\u2019t an excuse, it\u2019s just a statement of fact: almost all WMI scripts work equally well against a remote computer as they do the local computer. Every now and then we do say <I>something<\/I> that isn\u2019t an excuse!) <\/P>\n<P>We then encounter this line of code:<\/P><PRE class=\"codeSample\">Set colProcessList = objWMIService.ExecQuery(&#8220;Select * from Win32_Process Where &#8221; &amp; _\n    &#8220;Name = &#8216;cscript.exe&#8217; or Name = &#8216;wscript.exe'&#8221;)\n<\/PRE>\n<P>You might have already guessed that we need to use the <B>Win32_Process<\/B> class to carry out our task; that\u2019s because Win32_Process is the WMI class that keeps track of all the processes currently running on a computer. Of course, we aren\u2019t interested in <I>all<\/I> the processes running on the computer; we\u2019re only interested in the scripts. Because of that we include a Where clause that restricts the returned information only to instances of the two Windows script hosts: Cscript.exe and Wscript.exe.<\/P>\n<TABLE id=\"ERD\" 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, we could have written this script in a slightly different fashion, and maybe saved a line or two of code in the process. We opted for this approach because it more closely resembles the way we have to do this chore on Windows 2000.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>After issuing the query we set up a For Each loop to walk through the returned collection. In this example we\u2019re trying to determine the owner for a script named Test.vbs. Therefore, we need to check each script to see if it happens to be named Test.vbs. How do we do that? By using this line of code:<\/P><PRE class=\"codeSample\">If InStr(objProcess.CommandLine, &#8220;test.vbs&#8221;) Then\n<\/PRE>\n<P>All we\u2019re doing here is using the <B>InStr<\/B> function to see if the string <I>test.vbs<\/I> can be found anywhere in the <B>CommandLine<\/B> property. And what <I>is<\/I> the CommandLine property? In somewhat simplistic fashion, this is the command string required to start the script from a command prompt. For example, the CommandLine might be something like this:<\/P><PRE class=\"codeSample\">C:\\Scripts\\Test Scripts\\Test.vbs\n<\/PRE>\n<P>We\u2019re checking for <I>test.vbs<\/I> because we\u2019re assuming we don\u2019t have a script named, say, MyTest.vbs. If you\u2019re concerned with this kind of name collision, then we could simply use InStr and test for a string like <I>\\test.vbs<\/I>. That\u2019s something you\u2019ll have to decide for yourself.<\/P>\n<P>If it turns out that our target string can be found in the CommandLine value we then call the <B>GetOwner<\/B> method to find out the \u201cowner\u201d of the process (that is, the name of the account that the script is running under):<\/P><PRE class=\"codeSample\">objProcess.GetOwner(strNameOfUser,strUserDomain)\n<\/PRE>\n<P>With GetOwner, we need to pass along a pair of \u201cout parameters.\u201d An out parameter is nothing more than a variable (which we name ourselves) that the method will fill with a value. Here we\u2019re passing variables named strNameOfUser and strUserDomain; in return, GetOwner will assign those variables the name of the user and the domain of the user who owns the process.<\/P>\n<P>At that point all we have to do is echo back the returned information:<\/P><PRE class=\"codeSample\">Wscript.Echo &#8220;This script is running under the account belonging to &#8221; _ \n    &amp; strUserDomain &amp; &#8220;\\&#8221; &amp; strNameOfUser &amp; &#8220;.&#8221;\n<\/PRE>\n<P>So then why can\u2019t we run this same script on Windows 2000? Actually there\u2019s a good reason for that: the CommandLine property is found only on Windows XP and Windows Server 2003. On other versions of Windows we can\u2019t identify individual scripts; the best we can do is return owner information for any instances of Cscript.exe and Wscript.exe that happen to be running. If there\u2019s only one script running, no problem: that single instance of CScript.exe or Wscript.exe <I>has<\/I> to represent that one script. In turn, that means the owner of the script host process is also the owner of the script process. If you have multiple scripts running, though, that\u2019s a different story. If that\u2019s the case, the best you can do is say, \u201cWell, Ken Myer owns <I>one<\/I> of these scripts, although we don\u2019t know which one. And whichever one he doesn\u2019t own Pilar Ackerman <I>does<\/I> own.\u201d<\/P>\n<P>No, not quite as good. But it is what it is. (And yes, that <I>is<\/I> an excuse. A somewhat lame one, but an excuse nonetheless.)<\/P>\n<P>Here\u2019s what the Windows 2000 solution (OK: semi-solution) looks like:<\/P><PRE class=\"codeSample\">strComputer = &#8220;.&#8221;\nSet objWMIService = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\cimv2&#8221;)<\/p>\n<p>Set colProcessList = objWMIService.ExecQuery(&#8220;Select * from Win32_Process Where &#8221; &amp; _\n    &#8220;Name = &#8216;cscript.exe&#8217; or Name = &#8216;wscript.exe'&#8221;)<\/p>\n<p>For Each objProcess in colProcessList\n    objProcess.GetOwner strNameOfUser,strUserDomain\n    Wscript.Echo &#8220;A script is running under the account belonging to &#8221; _ \n        &amp; strUserDomain &amp; &#8220;\\&#8221; &amp; strNameOfUser &amp; &#8220;.&#8221;\nNext\n<\/PRE><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I determine which account a script is running under?&#8212; KW Hey, KW. You know, it\u2019s been awhile since we started off a column with a bunch of excuses, and that\u2019s been hard on us: after all, making excuses is what we Scripting Guys do best. With that in mind, then, [&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,87,3,5],"class_list":["post-67943","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-operating-system","tag-processes","tag-scripting-guy","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I determine which account a script is running under?&#8212; KW Hey, KW. You know, it\u2019s been awhile since we started off a column with a bunch of excuses, and that\u2019s been hard on us: after all, making excuses is what we Scripting Guys do best. With that in mind, then, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/67943","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=67943"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/67943\/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=67943"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=67943"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=67943"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}