{"id":64073,"date":"2007-09-07T01:54:00","date_gmt":"2007-09-07T01:54:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/09\/07\/how-can-i-backup-an-event-log-to-a-text-file\/"},"modified":"2007-09-07T01:54:00","modified_gmt":"2007-09-07T01:54:00","slug":"how-can-i-backup-an-event-log-to-a-text-file","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-backup-an-event-log-to-a-text-file\/","title":{"rendered":"How Can I Backup an Event Log to a Text File?"},"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! How can I backup an event log to a text file?<BR><BR>&#8212; IMBDS<\/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, IMBDS. You know, the Scripting Guys have dedicated their lives to helping others. (Well, OK, originally we dedicated our lives to having others help <I>us<\/I>. But when no one seemed very interested in that we changed our minds.) That means that, on those rare occasions when we actually learn something, we make a point of keeping the rest of the world informed as well.<\/P>\n<P>For example, just yesterday we were learned (much to our surprise) that the <A href=\"https:\/\/www.donotcall.gov\/default.aspx\" target=\"_blank\"><B>Do Not Call registry<\/B><\/A> in the US (designed to prevent telemarketers from barraging you with phone calls) has an expiration date: if you register your phone number, that registration is only good for 5 years. (Because, apparently, most people can only go so long before they absolutely <I>have<\/I> to hear from a telemarketer.) For example, the Scripting Guy who writes this column just entered his home phone number into the registry\u2019s online verification tool, and discovered that his registration is due to expire in a year. <\/P>\n<P>Wonderful.<\/P>\n<TABLE class=\"dataTable\" id=\"ELD\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P><B>Note<\/B>. If you want to know the truth, we\u2019re not sure that the Do Not Call registry is all that effective anyway. For example, even though his phone number is registered, the Scripting Guy who writes this column gets several phone calls a day asking him for money.<\/P>\n<P>And those are just from the Scripting Son.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Anyway, we thought everyone should know that the Do Not Call registry is anything but permanent. We also thought people should know that there\u2019s no simple, straightforward way to backup an event log to a text file; as it is, WMI\u2019s BackupEventLog method can only save data using the event log binary format. Of course, that doesn\u2019t mean that you can\u2019t save event log data to a text file; it just means you have to do that using a script like this one instead:<\/P><PRE class=\"codeSample\">strComputer = &#8220;.&#8221;<\/p>\n<p>Set objWMIService = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\cimv2&#8221;)<\/p>\n<p>Set colEvents = objWMIService.ExecQuery _\n    (&#8220;Select * from Win32_NTLogEvent Where LogFile=&#8217;Application'&#8221;)<\/p>\n<p>Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objFile = objFSO.CreateTextFile(&#8220;C:\\Scripts\\Events.txt&#8221;)<\/p>\n<p>For Each objEvent in colEvents\n    strTimeWritten = objEvent.TimeWritten<\/p>\n<p>    dtmTimeWritten = CDate(Mid(strTimeWritten, 5, 2) &amp; &#8220;\/&#8221; &amp; _\n        Mid(strTimeWritten, 7, 2) &amp; &#8220;\/&#8221; &amp; Left(strTimeWritten, 4) _\n            &amp; &#8221; &#8221; &amp; Mid (strTimeWritten, 9, 2) &amp; &#8220;:&#8221; &amp; _\n                Mid(strTimeWritten, 11, 2) &amp; &#8220;:&#8221; &amp; Mid(strTimeWritten, 13, 2))<\/p>\n<p>    dtmDate = FormatDateTime(dtmTimeWritten, vbShortDate)\n    dtmTime = FormatDateTime(dtmTimeWritten, vbLongTime)<\/p>\n<p>    strEvent = dtmDate &amp; vbTab\n    strEvent = strEvent &amp; dtmTime &amp; vbTab\n    strEvent = strEvent &amp; objEvent.SourceName &amp; vbTab\n    strEvent = strEvent &amp; objEvent.Type &amp; vbTab\n    strEvent = strEvent &amp; objEvent.Category &amp; vbTab\n    strEvent = strEvent &amp; objEvent.EventCode &amp; vbTab\n    strEvent = strEvent &amp; objEvent.User &amp; vbTab\n    strEvent = strEvent &amp; objEvent.ComputerName &amp; vbTab<\/p>\n<p>    strDescription = objEvent.Message\n    If IsNull(strDescription) Then\n        strDescription = &#8220;The event description cannot be found.&#8221;\n    End If\n    strDescription = Replace(strDescription, vbCrLf, &#8221; &#8220;)\n    strEvent = strEvent &amp; strDescription<\/p>\n<p>    objFile.WriteLine strEvent\nNext<\/p>\n<p>objFile.Close\n<\/PRE>\n<P>Admittedly, this is a somewhat complicated-looking script. And there\u2019s a good reason for that: some of the things we need to do here <I>are<\/I> somewhat complicated. But don\u2019t fret; we\u2019re going to walk you through the entire thing and explain exactly how it all works.<\/P>\n<P>Just as soon as we answer this phone call from an Unknown Caller.<\/P>\n<P>The script starts out simply enough, connecting to the WMI service on the local computer. And, being the Microsoft Scripting Guys, we know what you\u2019re thinking. And the answer to your question is yes, you <I>can<\/I> run this script against a remote computer; all you have to do is assign the name of that remote computer to the variable strComputer, like so:<\/P><PRE class=\"codeSample\">strComputer = &#8220;atl-dc-01&#8221;\n<\/PRE>\n<P>Ah, that\u2019s no big deal. When you\u2019re a Scripting Guy you\u2019re <I>supposed<\/I> to know about things like that.<\/P>\n<P>After making the connection to the WMI service we then execute the following line of code, a line of code that returns a collection of all the events found in the Application event log:<\/P><PRE class=\"codeSample\">Set colEvents = objWMIService.ExecQuery _\n    (&#8220;Select * from Win32_NTLogEvent Where LogFile=&#8217;Application'&#8221;)\n<\/PRE>\n<TABLE class=\"dataTable\" id=\"EME\" 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>. Needless to say, you aren\u2019t limited to backing up just the Application event log; if you want to, you can back up any (or even all) your event logs. For more information (particularly information about working with the Security event log) see the <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/guide\/sas_log_hdyb.mspx\"><B>Microsoft Windows 2000 Scripting Guide<\/B><\/A>.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>That brings us to these two lines of code:<\/P><PRE class=\"codeSample\">Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objFile = objFSO.CreateTextFile(&#8220;C:\\Scripts\\Events.txt&#8221;)\n<\/PRE>\n<P>As we noted earlier, there\u2019s no built-in method for backing up an event log as a text file; that is, there\u2019s no WMI method like, say, BackupAsTextFile. That means that there\u2019s only one way for us to programmatically save the contents of an event log as a text file: we need to write the information to the text file ourselves. So how do we do that? Well, for starters, we use the preceding two lines of code to create an instance of the <B>Scripting.FileSystemObject<\/B> object, and then create a brand-new text file named C:\\Scripts\\Events.txt.<\/P>\n<P>And then it\u2019s time to do some <I>real<\/I> work. We should probably note that it actually <I>is<\/I> possible to save an event log as a text file \u2026 provided that you open up Event Viewer and do all the work yourself. If you do that, Event Viewer will save the event log as a tab-delimited file. We\u2019ve decided to use this same format: we\u2019re going to save all the events in the Application event log in tab-delimited format. (That is, we\u2019ll separate the individual fields for each event \u2013 things like the event code and the event description \u2013 using tabs.)<\/P>\n<P>To that end, the first thing we do is create a For Each loop that loops us through each of the events in our collection. Inside the loop, we grab the value of the <B>TimeWritten<\/B> property and stash it in a variable named strTimeWritten:<\/P><PRE class=\"codeSample\">strTimeWritten = objEvent.TimeWritten\n<\/PRE>\n<P>Here\u2019s one place where things get a tad bit complicated. As you probably know, WMI stores dates and times using the UTC (Universal Time Coordinate) format; that means the value of the TimeWritten property is going be something like this:<\/P><PRE class=\"codeSample\">20070905121045.578000-420\n<\/PRE>\n<P>Nice, huh? We won\u2019t bother explaining how to decipher a UTC date-time value; you can find a pretty good explanation of that in the <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/guide\/sas_wmi_yakv.mspx\"><B>Scripting Guide<\/B><\/A>. Suffice to say, however, that a value like 20070905121045.578000-420 isn\u2019t quite as intuitive as information like this:<\/P><PRE class=\"codeSample\">9\/5\/2007 12:10 PM\n<\/PRE>\n<P>But how in the <I>world<\/I> do we convert a UTC value to something a human being can read and understand? Why, like this, of course:<\/P><PRE class=\"codeSample\">dtmTimeWritten = CDate(Mid(strTimeWritten, 5, 2) &amp; &#8220;\/&#8221; &amp; _\n    Mid(strTimeWritten, 7, 2) &amp; &#8220;\/&#8221; &amp; Left(strTimeWritten, 4) _\n        &amp; &#8221; &#8221; &amp; Mid (strTimeWritten, 9, 2) &amp; &#8220;:&#8221; &amp; _\n            Mid(strTimeWritten, 11, 2) &amp; &#8220;:&#8221; &amp; Mid(strTimeWritten, 13, 2))\n<\/PRE>\n<P>Again, you can find a complete description of what we\u2019re doing in the Scripting Guide. As a quick summary, all we\u2019re really doing here is grabbing the individual pieces of the UTC value and constructing our own date-time value. For example, the first four digits in a UTC value represent the current year; thus <B>2007<\/B>0905121045.578000-420 indicates that we\u2019re dealing with the year 2007. In turn, that means code like this, which snags the first four characters in our UTC value, also lets us know that we\u2019re dealing with the year 2007:<\/P><PRE class=\"codeSample\">Left(strTimeWritten, 4)\n<\/PRE>\n<P>If you follow the logic of the script all the way through, you\u2019ll see that, eventually, the variable dtmTimeWritten gets assigned a value like this:<\/P><PRE class=\"codeSample\">9\/5\/2007 12:10:45 PM\n<\/PRE>\n<P>Now <I>that\u2019s<\/I> something we can work with.<\/P>\n<P>As it turns out, the tab-delimited file format used by Event Viewer separates the date (9\/5\/2007) from the time (12:10:45 PM). That\u2019s fine; because of that, we next use the <B>FormatDateTime<\/B> function and the VBScript constants vbShortDate and vbLongTime to store the date in a variable named dtmDate and the time in a variable named dtmTime:<BR><\/P><PRE class=\"codeSample\">dtmDate = FormatDateTime(dtmTimeWritten, vbShortDate)\ndtmTime = FormatDateTime(dtmTimeWritten, vbLongTime)\n<\/PRE>\n<P>Once we\u2019ve taken care of the date and time, our next step is to begin constructing the first line of the text file (which will correspond to the information in the first event recorded in the event log). That\u2019s what this block of code is for:<\/P><PRE class=\"codeSample\">strEvent = dtmDate &amp; vbTab\nstrEvent = strEvent &amp; dtmTime &amp; vbTab\nstrEvent = strEvent &amp; objEvent.SourceName &amp; vbTab\nstrEvent = strEvent &amp; objEvent.Type &amp; vbTab\nstrEvent = strEvent &amp; objEvent.Category &amp; vbTab\nstrEvent = strEvent &amp; objEvent.EventCode &amp; vbTab\nstrEvent = strEvent &amp; objEvent.User &amp; vbTab\nstrEvent = strEvent &amp; objEvent.ComputerName &amp; vbTab\n<\/PRE>\n<P>As you can see, there\u2019s nothing too fancy here. In the first line, we assign the date (represented by the variable dtmDate) and a tab character (the VBScript constant vbTab) to a variable named strEvent. (Why a tab character? Because we want each field to be separated by a tab.) In line 2, we assign strEvent the current value of strEvent <I>plus<\/I> the value of the variable dtmTime <I>plus<\/I> another tab character. We then repeat this process several times, tacking the values of WMI properties such as <B>SourceName<\/B> and <B>Type<\/B> to the value of strEvent.<\/P>\n<P>That brings us to this block of code:<\/P><PRE class=\"codeSample\">strDescription = objEvent.Message\nIf IsNull(strDescription) Then\n    strDescription = &#8220;The event description cannot be found.&#8221;\nEnd If\nstrDescription = Replace(strDescription, vbCrLf, &#8221; &#8220;)\nstrEvent = strEvent &amp; strDescription\n<\/PRE>\n<P>Perhaps the most important property of an event log event is the <B>Message<\/B> property; the Message property, as you doubtless know, provides a (more or less) detailed description of the event. Unfortunately, however, the Message property can potentially cause havoc with our script. So what do we do about <I>that<\/I>? That\u2019s easy: we take steps to defuse these problems before they occur.<\/P>\n<P>What kind of problems are we talking about? Well, for one thing, the Message property often includes one or more carriage return-linefeed characters; in other words, the value of the Message property might look like this:<\/P><PRE class=\"codeSample\">Security policy in the Group policy objects has been applied successfully.<\/p>\n<p>For more information, see Help and Support Center at http:\/\/go.microsoft.com\/fwlink\/events.asp.\n<\/PRE>\n<P>What\u2019s wrong with that? Well, in a tab-delimited file, all the information for a single event must fit on one line; that\u2019s not going to be the case if the Message includes a carriage return-linefeed character. Consequently, we use the <B>Replace<\/B> function to replace any carriage return-linefeed characters (vbCrLf) with a blank space:<\/P><PRE class=\"codeSample\">strDescription = Replace(strDescription, vbCrLf, &#8221; &#8220;)\n<\/PRE>\n<P>That\u2019s great, but, in turn, this introduces another problem. For some events the Message property doesn\u2019t actually <I>have<\/I> a value. In Event Viewer, that\u2019s no problem; in a case like that, Event Viewer displays a message similar to this:<\/P><PRE class=\"codeSample\">The description for Event ID ( 0 ) in Source ( iPod Service ) cannot be found. The local computer may not have the\nnecessary registry information or message DLL files to display messages from a remote computer. You may be \nable to use the \/AUXSOURCE= flag to retrieve this description; see Help and Support for details. The following \ninformation is part of the event: Service started.\n<\/PRE>\n<P>But that works only in Event Viewer; that information does <I>not<\/I> get passed to the Message property. Instead, the value of the Message property comes back as Null.<\/P>\n<P>Is that a problem? As a matter of fact, it is; running the Replace function against a Null value is a recipe for disaster. (Assuming, of course, that you consider a script that crashes to be a disaster.) Therefore, before we call the Replace function we execute this block of code:<\/P><PRE class=\"codeSample\">If IsNull(strDescription) Then\n    strDescription = &#8220;The event description cannot be found.&#8221;\nEnd If\n<\/PRE>\n<P>All we\u2019re doing here is using the <B>IsNull<\/B> function to determine whether the Message property (which is stored in the variable strDescription) happens to be Null. If it\u2019s not, well, no problem. If it <I>is<\/I>, then we simply set the value of strDescription to the generic message \u201cThe event description cannot be found.\u201d<\/P>\n<P>After dealing with any potential Null values, we call the Replace function, then tack the value of strDescription onto the end of our event string:<\/P><PRE class=\"codeSample\">strEvent = strEvent &amp; strDescription\n<\/PRE>\n<P>And then we simply call the <B>WriteLine<\/B> method to write this event to the text file:<\/P><PRE class=\"codeSample\">objFile.WriteLine strEvent\n<\/PRE>\n<P>From there we zip back to the top of our For Each loop and repeat the process with the next event in the collection. After we\u2019ve added all the events to the text file we execute the <B>Close<\/B> method, close the file, and call it a day.<\/P>\n<P>We hope that answers your question, IMBDS. If it doesn\u2019t, don\u2019t bother to send us an email; instead, just give us a call. After all \u2013 sigh \u2013 that\u2019s what everyone else does. Oops; gotta go. The phone\u2019s ringing.<\/P>\n<TABLE class=\"dataTable\" id=\"E4AAC\" 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>. In the true spirit of entrepreneurship, there are companies that will actually call you, on the phone, and (for a small fee) offer to put your phone number on the Do Not Call registry. Only in America \u2026.<\/P><\/TD><\/TR><\/TBODY><\/TABLE><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I backup an event log to a text file?&#8212; IMBDS Hey, IMBDS. You know, the Scripting Guys have dedicated their lives to helping others. (Well, OK, originally we dedicated our lives to having others help us. But when no one seemed very interested in that we changed our minds.) That [&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":[343,97,98,3,4,14,5],"class_list":["post-64073","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-backup","tag-event-logs","tag-logs-and-monitoring","tag-scripting-guy","tag-scripting-techniques","tag-text-files","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I backup an event log to a text file?&#8212; IMBDS Hey, IMBDS. You know, the Scripting Guys have dedicated their lives to helping others. (Well, OK, originally we dedicated our lives to having others help us. But when no one seemed very interested in that we changed our minds.) That [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/64073","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=64073"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/64073\/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=64073"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=64073"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=64073"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}