{"id":63763,"date":"2007-10-19T22:37:00","date_gmt":"2007-10-19T22:37:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/10\/19\/hey-scripting-guy-how-can-i-retrieve-a-list-of-unique-users-from-the-security-event-log\/"},"modified":"2007-10-19T22:37:00","modified_gmt":"2007-10-19T22:37:00","slug":"hey-scripting-guy-how-can-i-retrieve-a-list-of-unique-users-from-the-security-event-log","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-retrieve-a-list-of-unique-users-from-the-security-event-log\/","title":{"rendered":"Hey, Scripting Guy! How Can I Retrieve a List of Unique Users from the Security Event Log?"},"content":{"rendered":"<p><H2><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\"> <\/H2>\n<P>Hey, Scripting Guy! How can I retrieve a list of unique users from the Security event log?<BR><BR>&#8212; KM<\/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, KM. Before we tackle your question we should probably address a question sent in by another reader:<\/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>Hey, Scripting Guy! Whatever happened to Monday?<\/P>\n<P>Having been gone on vacation all last week, I was combing through the <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/hsgarch.mspx\"><B>Hey, Scripting Guy! archive<\/B><\/A>, and I find that last week was only four days long.<\/P>\n<P>I&#8217;m familiar with the adage &#8220;time flies when you&#8217;re having fun,&#8221; (and the frogger version &#8220;time&#8217;s fun when you&#8217;re having flies&#8221;) but I hadn&#8217;t realized there had been an anti-leap year calendar adjustment. There was no announcement in the newspapers. Maybe it was lost among all the stories about firing the Univ. of Nebraska A.D. (or as he&#8217;s known in the Cornhusker State, &#8220;The Pope&#8221;).<\/P>\n<P>Even my favorite Internet search engine won&#8217;t reveal the missing column.<\/P>\n<P>What gives?<\/P>\n<P>&#8212; TP<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Hey, TP. Ah, yes The Case of the Missing Monday. (Oh, by the way, nice letter. Although it <I>is<\/I> kind of sad when the letters about a column are funnier and better written than the column itself.) As it turns out, there actually <I>was<\/I> a column last Monday, albeit briefly. Shortly after the column appeared, however, we had to take it down. Why? Well, that particular column mentioned a third-party software company, and we were asked to \u201crework\u201d the article by removing all references to that company.<\/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 class=\"lastInCell\"><B>Note<\/B>. But hey, no big deal; after all, if you write 800+ columns you\u2019re bound to write one sooner or later that <I>someone<\/I> takes issue with. Considering some of the other columns we\u2019ve written, however, we\u2019re just surprised that that one was the one someone took issue with!<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>And in case you\u2019re wondering, no, the Scripting Guys did <I>not<\/I> make a lot of cruel and cutting remarks at the expense of that software company; in fact, we actually had a lot of <I>nice<\/I> things to say about this particular company. (After all, when you get in as much trouble as the Scripting Guys do you can\u2019t afford to make even <I>more<\/I> enemies.) Nevertheless, we have complied with the request, removed everything from the column except the code (and an explanation of how that code works), and <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/oct07\/hey1008.mspx\"><B>reposted the article<\/B><\/A>. Which, in turn, means that not only did Monday actually happen, but we even have a Monday column to prove it. <\/P>\n<P>So does that mean that you\u2019re <I>not<\/I> going crazy, TP? Well, we\u2019re not sure; after all, you <I>do<\/I> live in Nebraska.<\/P>\n<TABLE id=\"E5E\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P><B>Note<\/B>. Which, we hasten to add, has always been the Scripting Guys\u2019 favorite state.<\/P>\n<P>Well, OK: it\u2019s tied for our favorite state with all the other 49 states. What\u2019s that? Even <I>Delaware<\/I>? You know what? We\u2019ll have to get back to you on that one .\u2026<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Anyway, so much for The Case of the Missing Monday. If anyone out there saw the column before it was removed and was offended by the content, well, we sincerely apologize. The truth is, the Scripting Guys never intentionally set out to offend anyone; after all, if we did then today\u2019s column would be all about the University of Nebraska\u2019s football program. <\/P>\n<P>But it\u2019s not. Instead, it\u2019s all about retrieving a list of unique users from the Security event log. (Which is really more a reminder to ourselves than to any of our readers.)<\/P>\n<P>In addition, if any of you thought that Monday really <I>had<\/I> disappeared, well, we apologize for any inconvenience that might have caused. As we noted, the Scripting Guys did <I>not<\/I> make Monday disappear. It would have been a bit ironic if we had; after all, we\u2019ve actually been working on a project to make the week <I>longer<\/I>, primarily by inserting a few extra Saturdays here and there. But now that we think about it, removing Monday might be a little easier. We\u2019ll put that on to the to-do list.<\/P>\n<P>But today\u2019s column isn\u2019t about messing with the space-time continuum, either. Instead, it\u2019s all about retrieving a list of unique users from the Security event log:<\/P><PRE class=\"codeSample\">On Error Resume Next<\/p>\n<p>strComputer = &#8220;.&#8221;<\/p>\n<p>Set objWMIService = GetObject(&#8220;winmgmts:{(Security)}\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\cimv2&#8221;)<\/p>\n<p>Set colEvents = objWMIService.ExecQuery _\n    (&#8220;Select * from Win32_NTLogEvent Where Logfile = &#8216;Security'&#8221;)<\/p>\n<p>Set objDictionary = CreateObject(&#8220;Scripting.Dictionary&#8221;)<\/p>\n<p>For Each objEvent in colEvents\n    If Not objDictionary.Exists(objEvent.User) Then\n        objDictionary.Add objEvent.User, objEvent.User   \n    End If\nNext<\/p>\n<p>For Each strKey in objDictionary.Keys\n    Wscript.Echo strKey\nNext\n<\/PRE>\n<P>OK, let\u2019s see if we can figure out how this script works. To begin with, we connect to the WMI service on the local computer; if we wanted to, however, we could just as easily run this script against a remote computer. (How? By assigning the name of the remote computer to the variable strComputer.) When you make the connection to the WMI service, make sure your GetObject call looks like this:<\/P>\n<P>GetObject(&#8220;winmgmts:<B>{(Security)}<\/B>\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\cimv2&#8221;)<\/P>\n<P>As you can see, we\u2019ve included the <B>Security<\/B> privilege in this script, enclosing it in parentheses and curly braces, and tacking it on immediately after the <B>winmgmts:<\/B> moniker. Why? Well, unlike many of the things the Scripting Guys do, there\u2019s actually a good reason for this: without this privilege the script will not return any data. (You won\u2019t get an error message, but you won\u2019t get back any information, either.) The Security privilege must be present any time you try to access the Security event log. If it isn\u2019t, well, don\u2019t say we didn\u2019t warn you.<\/P>\n<TABLE id=\"ELG\" 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>. Check that: don\u2019t say that we <I>did<\/I> warn you; we don\u2019t want to get in trouble for ordering people around, and for telling them what they can and cannot do in their script. But make sure you use the Security privilege anyway, OK? Pretty please? With sugar on it?<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>After we connect to the WMI service we then use this line of code to return a collection of all the events found in the Security event log:<\/P><PRE class=\"codeSample\">Set colEvents = objWMIService.ExecQuery _\n    (&#8220;Select * from Win32_NTLogEvent Where Logfile = &#8216;Security'&#8221;)\n<\/PRE>\n<P>One thing to keep in mind here: depending on the number of records in your Security event log, this script could take a minute or two (or even more) to complete. The Scripting Guy who writes this column clears his event log about as often as he cleans his gutters; with over 51,000 events in <I>his<\/I> security event log, this script took about 90 seconds to finish.<\/P>\n<P>The gutters will likely require a bit more time and effort.<\/P>\n<P>Sooner or later, though, we <I>will<\/I> get back a collection of all the events in the Security event log. Once we do we next create an instance of the <B>Scripting.Dictionary<\/B> object; we\u2019re going to use this object to keep track of the unique users found in the event log. And then we\u2019re ready to roll up our sleeves and get to work.<\/P>\n<P>To begin with, we set up a For Each loop that loops through all the events in our collection. Inside that loop, the first thing we do is run this line of code:<\/P><PRE class=\"codeSample\">If Not objDictionary.Exists(objEvent.User) Then\n<\/PRE>\n<P>What are we doing here? We\u2019re simply checking to see if the user specified in the event\u2019s <B>User<\/B> property already exists in the Dictionary. If he or she does, then we\u2019re going to loop around and repeat this test with the next event in the collection; after all, because we\u2019re interested only in unique users there\u2019s no need to add this user a second time. (Besides, the Dictionary object doesn\u2019t allow for duplicate items.) If the user <I>isn\u2019t<\/I> in the Dictionary, then we use this line of code to add that user, specifying the value of the User property as both the Dictionary <B>Item<\/B> and <B>Key<\/B>:<\/P><PRE class=\"codeSample\">objDictionary.Add objEvent.User, objEvent.User\n<\/PRE>\n<P>And then it back to the top of the loop to try again with the next event in the collection.<\/P>\n<P>After we exit the loop, we use this block of code to echo back our collection of unique users:<\/P><PRE class=\"codeSample\">For Each strKey in objDictionary.Keys\n    Wscript.Echo strKey\nNext\n<\/PRE>\n<P>That\u2019s going to result in output similar to this:<\/P><PRE class=\"codeSample\">NT AUTHORITY\\NETWORK SERVICE\nNT AUTHORITY\\LOCAL SERVICE\nNT AUTHORITY\\SYSTEM\nFABRIKAM\\kmyer\nNT AUTHORITY\\ANONYMOUS LOGON\nFABRIKAM\\packerman\n<\/PRE>\n<P>And then what? Well, to quote Porky Pig, that\u2019s \u2013 well, maybe it\u2019s best if we don\u2019t go around quoting third-party cartoon animals. So let\u2019s just say, \u201cThat\u2019s all, uh \u2026 people.\u201d <\/P>\n<P>Before we go, however, yes, we know: you\u2019re all <I>dying<\/I> to learn the name of the company mentioned in our original Monday article. As it turns out, that was \u2013 uh, well, never mind. We\u2019re not going to slip up and tell you the name; after all, the Scripting Guys never make the same mistake twice. (Mainly because we make so many <I>other<\/I> mistakes that we never get around to making the same mistake twice.) So, no, we can\u2019t \u2013 and won\u2019t \u2013 tell you the name of the company. But you could always try visiting your favorite Internet search engine and figuring it out for yourself.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I retrieve a list of unique users from the Security event log?&#8212; KM Hey, KM. Before we tackle your question we should probably address a question sent in by another reader: Hey, Scripting Guy! Whatever happened to Monday? Having been gone on vacation all last week, I was combing through [&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":[97,3,63,5],"class_list":["post-63763","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-event-logs","tag-scripting-guy","tag-security","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I retrieve a list of unique users from the Security event log?&#8212; KM Hey, KM. Before we tackle your question we should probably address a question sent in by another reader: Hey, Scripting Guy! Whatever happened to Monday? Having been gone on vacation all last week, I was combing through [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63763","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=63763"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63763\/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=63763"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=63763"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=63763"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}