Just a short, simple blog for Bob to share his thoughts.
28 December 2005 • by Bob • Random Thoughts
Okay, it's a couple of days late because I took the past few days off to celebrate Christmas with my family, but I wanted to make sure that I wished everyone a Merry Christmas...! [:)]
Веселое Рождество!
Christmas Alegre!
¡Feliz Navidad!
Frohe Weihnachten!
Joyeux Noël!
Καλά Χριστούγεννα!
Natale allegro!
Vrolijke Kerstmis!
01 December 2005 • by Bob • IIS, Scripting
One of the great utilities that ships with IIS is the CONVLOG.EXE application, which converts W3C or MS Internet Standard log files to NCSA format, where they can be processed by any of the applications that only parse NCSA log file information. The trouble is, what happens when you already have NCSA log files and you want W3C log files? You can't use the CONVLOG.EXE application, it only works in the opposite direction.
With that in mind, I wrote the following Windows Script Host (WSH) script that will read the current directory and convert all NCSA-formatted log files to W3C format. To use this code, just copy the code into notepad, and save it with a ".vbs" file extension on your system. To run it, copy the script to a folder that contains NCSA log files, (named "nc*.log"), then double-click it.
Option Explicit Dim objIISLog Dim objFSO Dim objFolder Dim objFile Dim objOutputFile Dim strInputPath Dim strOutputPath Dim strLogRecord Set objFSO = WScript.CreateObject("Scripting.FileSystemObject") Set objFolder = objFSO.GetFolder(".") For Each objFile In objFolder.Files strInputPath = LCase(objFile.Name) If Left(strInputPath,2) = "nc" And Right(strInputPath,4) = ".log" Then strOutputPath = objFolder.Path & "\" & "ex" & Mid(strInputPath,3) strInputPath = objFolder.Path & "\" & strInputPath Set objIISLog = CreateObject("MSWC.IISLog") objIISLog.OpenLogFile strInputPath, 1, "", 0, "" Set objOutputFile = objFSO.CreateTextFile(strOutputPath) objIISLog.ReadLogRecord objOutputFile.WriteLine "#Software: Microsoft Internet Information Services 5.0" objOutputFile.WriteLine "#Version: 1.0" objOutputFile.WriteLine "#Date: " & BuildDateTime(objIISLog.DateTime) objOutputFile.WriteLine "#Fields: date time c-ip cs-username s-ip s-port cs-method cs-uri-stem cs-uri-query sc-status cs(User-Agent)" Do While Not objIISLog.AtEndOfLog strLogRecord = BuildDateTime(objIISLog.DateTime) strLogRecord = strLogRecord & " " & FormatField(objIISLog.ClientIP) strLogRecord = strLogRecord & " " & FormatField(objIISLog.UserName) strLogRecord = strLogRecord & " " & FormatField(objIISLog.ServerIP) strLogRecord = strLogRecord & " " & FormatField(objIISLog.ServerPort) strLogRecord = strLogRecord & " " & FormatField(objIISLog.Method) strLogRecord = strLogRecord & " " & FormatField(objIISLog.URIStem) strLogRecord = strLogRecord & " " & FormatField(objIISLog.URIQuery) strLogRecord = strLogRecord & " " & FormatField(objIISLog.ProtocolStatus) strLogRecord = strLogRecord & " " & FormatField(objIISLog.UserAgent) objOutputFile.WriteLine strLogRecord objIISLog.ReadLogRecord Loop objIISLog.CloseLogFiles 1 objIISLog = Null End If Next Function FormatField(tmpField) On Error Resume Next FormatField = "-" If Len(tmpField) > 0 Then FormatField = Trim(tmpField) End Function Function BuildDateTime(tmpDateTime) On Error Resume Next tmpDateTime = CDate(tmpDateTime) BuildDateTime = Year(tmpDateTime) & "-" & _ Right("0" & Month(tmpDateTime),2) & "-" & _ Right("0" & Day(tmpDateTime),2) & " " & _ Right("0" & Hour(tmpDateTime),2) & ":" & _ Right("0" & Minute(tmpDateTime),2) & ":" & _ Right("0" & Second(tmpDateTime),2) End Function
I hope this helps!
11 November 2005 • by Bob • Military, Opinion
As an honorably-discharged veteran, it should come as no surprise that an opinion piece with a title of "Why America needs to be Defeated in Iraq" would catch my attention. When I first read this ludicrous pile of drivel from a gentleman whom I shall henceforth refer to as "
After a bit of time had passed, I pondered more about the context of
Mr. McVeigh's vicious manifestation of domestic terrorism was responsible for the deaths of 168 innocent men, women, and children. However, for Mr. McVeigh, those people's fates were secondary to his cause. He believed that his principles were more important than his victims' lives. In the same way,
On the one hand,
History has had more than its fair share of sociopaths who fail to take responsibility for their murderous actions, and
It is ironic that
To be clear, I do not mind when someone exercises their freedom of speech. I do not mind when someone protests the war. (I have my own misgivings about the directions we are taking - or not taking.) I do not mind when someone calls the President a "war-monger." I do not mind when someone wants our troops out of the Middle East, and organizes a
However, I damn sure mind when some hypocritical,
I'll get off my soapbox now.
UPDATE: This post is one of several that I had written that I later discovered had never been set to "public."
04 October 2005 • by Bob • IIS, Scripting, IIS 6
Note: I originally wrote the following script for a friend, but as every good programmer often does, I kept the script around because I realized that it could come in handy. I've found myself using the script quite often with several of the servers that I manage, so I thought that I'd share it here.
When managing a large web server with dozens of web sites, it's hard to keep track of all the host headers that you have configured in your settings. With that in mind, I wrote the following script that lists the host headers that are assigned on an IIS web server. To use the example script, copy the script into notepad or some other text editor, save it to your server as "HostHeaders.vbs", and then double-click the script to run it. The script will create a text file named "HostHeaders.txt" that contains all the host headers listed by site for your server.
Option Explicit
On Error Resume Next
Dim objBaseNode, objChildNode
Dim objBindings, intBindings
Dim objFSO, objFile, strOutput
' get a base object
Set objBaseNode = GetObject("IIS://LOCALHOST/W3SVC")
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile("HostHeaders.txt")
' check if we have an error ...
If (Err.Number <> 0) Then
' ... and output the error.
strOutput = "Error " & Hex(Err.Number) & "("
strOutput = strOutput & Err.Description & ") occurred."
' ... otherwise, continue processing.
Else
' loop through the child nodes
For Each objChildNode In objBaseNode
' is this node for a web site?
If objChildNode.class = "IIsWebServer" Then
' get the name of the node
strOutput = strOutput & "LM/W3SVC/" & _
objChildNode.Name
' get the server comment
strOutput = strOutput & " (" & _
objChildNode.ServerComment & ")" & vbCrLf
' get the bindings
objBindings = objChildNode.ServerBindings
' loop through the bindings
For intBindings = 0 To UBound(objBindings)
strOutput = strOutput & vbTab & _
Chr(34) & objBindings(intBindings) & _
Chr(34) & vbCrLf
Next
End If
' try not to be a CPU hog
Wscript.Sleep 10
Next
End If
objFile.Write strOutput
objFile.Close
Set objBaseNode = Nothing
Set objFSO = Nothing
If you feel adventurous, you could easily modify the script to return the text in a tab-separated or comma-separated format.
Enjoy!
25 June 2005 • by Bob • FrontPage
This article discusses how to use a SCHEMA.INI file to access information that is stored in various text file databases.
[CSVTEST.csv] ColNameHeader=True MaxScanRows=25 Format=CSVDelimited CharacterSet=ANSI
[TABTEST.txt] ColNameHeader=True MaxScanRows=25 Format=TabDelimited CharacterSet=ANSI
The following articles discuss the SCHEMA.INI format and related concepts in detail; MSDN keeps rearranging their hyperlinks, so hopefully they are still live:
23 November 2004 • by Bob • FrontPage
When you create a database editor using the FrontPage 2003 ASP.NET Database Interface Wizard (DIW), you are prompted to create a user account for editing the database. After running the wizard, there is no interface for changing the user or password, and there is no provision for adding more than one user account as an editor.
This behavior is by design. The user account specified when created the DIW pages is hard-coded into the "web.config" files used by the database editor.
To resolve this issue, you can modify the necessary "web.config" files to modify or add users.
When creating the database editor, FrontPage 2003 creates two "web.config" files, one will be in the root of the site, and the other will be in the folder containing the database editor. Currently, ASP.NET Security supports the MD5 and SHA-1 hash algorithms when configuring any user accounts in your "web.config" files for use with forms-based authentication. FrontPage 2003 creates user account information using the SHA-1 hash algorithm, but this article will explain how to customize that.
To modify or add users, use the following steps:
<authentication mode="Forms"> <forms loginUrl="login.aspx"> <credentials passwordFormat="SHA1"> <user name="msbob" password="21BD12DC183F740EE76F27B78EB39C8AD972A757"/> </credentials> </forms> </authentication>
<credentials passwordFormat="Clear">NOTE - You could just as easily configure "MD5" for the passwordFormat.
<html> <head> <title>MD5/SHA-1 Hash Generator</title> </head> <body> <h2>MD5/SHA-1 Hash Generator</h2> <% Dim strPassword As String = Request.Form("txtPassword") If Len(strPassword)>0 Then Dim objFormAuth As New System.Web.Security.FormsAuthentication() Dim strHashSHA1 As String = objFormAuth.HashPasswordForStoringInConfigFile(strPassword, "SHA1") Dim strHashMD5 As String = objFormAuth.HashPasswordForStoringInConfigFile(strPassword, "MD5") Response.Write("<p>Clear: " & strPassword & "</p>") Response.Write("<p>SHA-1: " & strHashSHA1 & "</p>") Response.Write("<p>MD5: " & strHashMD5 & "</p>") End If %> <form method="post"> <input type="text" name="txtPassword"> <input type="submit" value="Create Hashes"> </form> </body> </html>
<user name="msbob" password="21BD12DC183F740EE76F27B78EB39C8AD972A757"/>
<credentials passwordFormat="Clear"> <user name="user1" password="Password1"/> <user name="user2" password="Password2"/> <user name="user3" password="Password3"/> </credentials>
<authorization> <allow users="msbob"/> <deny users="*"/> </authorization>
<authorization> <allow users="user1,user2,user3"/> <deny users="*"/> </authorization>
When you browse your database editor, you should now be able to enter the credentials for any user accounts that you created.
For additional information on ASP.NET Security and forms-based authentication, please see the following Microsoft Knowledge Base articles:
07 March 2003 • by Bob • FrontPage
The Microsoft web site now offers a Visio Viewer Web Component for download. See the following URL for more information:
The purpose of this article is to show you how to use some of the FrontPage SDK functionality to add two new Web Components to FrontPage that will allow you to add the Visio Viewer to a web page.
NOTE - This example works in both FrontPage 2002 and FrontPage 2003.
This will be in one of the following paths by default:
"C:\Program Files\Microsoft Office\OFFICE10\1033\WEBCOMP"
"C:\Program Files\Microsoft Office\OFFICE11\1033\WEBCOMP"
[Component] Name="Microsoft Visio" Caption="C&hoose a component:" Sorted=True Type=Text OnlyFor1033=True [Component.Options] Option1=Visio1 Option2=Visio2 [Visio1] Name="Visio Viewer (With Wizard)" Description="Insert a Visio Viewer component on your page." URL="C:\Program Files\Microsoft Office\OFFICE11\1033\WEBCOMP\VISIO.HTM" [Visio2] Name="Visio Viewer (HTML Only)" Description="Insert a Visio Viewer component on your page." [Visio2.HTML] HTML1=<object classid="clsid:279D6C9A-652E-4833-BEFC-312CA8887857" HTML2=id="viewer1" width="300" height="300" HTML3=codebase="http://download.microsoft.com/download/VisioStandard2002/vviewer/2002/W98NT42KMeXP/EN-US/vviewer.exe"> HTML4=<param name="BackColor" value="16777120"> HTML5=<param name="PageColor" value="16777215"> HTML6=<param name="GridVisible" value="1"> HTML7=<param name="PageVisible" value="1"> HTML8=<param name="HighQualityRender" value="1"> HTML9=<param name="ScrollbarsVisible" value="1"> HTML10=<param name="ToolbarVisible" value="1"> HTML11=<param name="AlertsEnabled" value="1"> HTML12=<param name="ContextMenuEnabled" value="1"> HTML13=<param name="PropertyDialogEnabled" value="1"> HTML14=<param name="SRC" value=""> HTML15=<param name="CurrentPageIndex" value="1"> HTML16=<param name="Zoom" value="-1"> HTML17=</object>
NOTE - You need to make sure that the URL parameter in the file matches your correct drive and Office version path.
<html> <head> <meta name="GENERATOR" content="Microsoft FrontPage 6.0"> <meta name="ProgId" content="FrontPage.Editor.Document"> <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <title>Visio Viewer</title> <style> .button { width=80px; } .file { width=350px; } .text { width=40px; } body,td { font-family:'MS Sans Serif',verdana,arial; font-size:9pt; scrollbar-face-color:#cccccc; scrollbar-base-color:#cccccc; scrollbar-highlight-color:#cccccc; scrollbar-shadow-color:#cccccc; background-color:#cccccc; color:#000000 } </style> <script language="JavaScript"> <!-- function insertHTML() { // build the HTML output var html =''; html += "<object classid=\"clsid:279D6C9A-652E-4833-BEFC-312CA8887857\" id=\"viewer1\" "; html += " width=\"" + frmOptions.txtWidth.value + "\" "; html += " height=\"" + frmOptions.txtHeight.value + "\" "; html += " codebase=\"http://download.microsoft.com/download/VisioStandard2002/"; html += "vviewer/2002/W98NT42KMeXP/EN-US/vviewer.exe\">\n"; html += "<param name=\"BackColor\" value=\"16777120\">\n"; html += "<param name=\"PageColor\" value=\"16777215\">\n"; html += processCheckbox(frmOptions.chkGridVisible,"GridVisible"); html += processCheckbox(frmOptions.chkPageVisible,"PageVisible"); html += processCheckbox(frmOptions.chkHighQualityRender,"HighQualityRender"); html += processCheckbox(frmOptions.chkScrollbarsVisible,"ScrollbarsVisible"); html += processCheckbox(frmOptions.chkToolbarVisible,"ToolbarVisible"); html += processCheckbox(frmOptions.chkAlertsEnabled,"AlertsEnabled"); html += processCheckbox(frmOptions.chkContextMenuEnabled,"ContextMenuEnabled"); html += processCheckbox(frmOptions.chkPropertyDialogEnabled,"PropertyDialogEnabled"); html += "<param name=\"SRC\" value=\"" + frmOptions.txtVisioFile.value + "\">\n"; html += "<param name=\"CurrentPageIndex\" value=\"1\">\n"; html += "<param name=\"Zoom\" value=\"-1\">\n"; html += "</object>\n"; // preserve our options setCookie("txtVisioFile",frmOptions.txtVisioFile.value); setCookie("txtWidth",frmOptions.txtWidth.value); setCookie("txtHeight",frmOptions.txtHeight.value); setCookie("chkGridVisible",frmOptions.chkGridVisible.checked); setCookie("chkPageVisible",frmOptions.chkPageVisible.checked); setCookie("chkHighQualityRender",frmOptions.chkHighQualityRender.checked); setCookie("chkScrollbarsVisible",frmOptions.chkScrollbarsVisible.checked); setCookie("chkToolbarVisible",frmOptions.chkToolbarVisible.checked); setCookie("chkAlertsEnabled",frmOptions.chkAlertsEnabled.checked); setCookie("chkContextMenuEnabled",frmOptions.chkContextMenuEnabled.checked); setCookie("chkPropertyDialogEnabled",frmOptions.chkPropertyDialogEnabled.checked); // close the wizard window.external.WebComponent.PreviewHTML = html window.external.WebComponent.HTML = window.external.WebComponent.PreviewHTML; window.external.WebComponent.Tag = "body"; window.external.Close(true); } function initializeForm() { frmOptions.txtVisioFile.value=getCookie("txtVisioFile","http://localhost/sample.vsd"); frmOptions.txtHeight.value=getCookie("txtHeight","300"); frmOptions.txtWidth.value=getCookie("txtWidth","300"); frmOptions.chkGridVisible.checked=((getCookie("chkGridVisible","true")=="true")?true:false); frmOptions.chkPageVisible.checked=((getCookie("chkPageVisible","true")=="true")?true:false); frmOptions.chkHighQualityRender.checked=((getCookie("chkHighQualityRender","true")=="true")?true:false); frmOptions.chkScrollbarsVisible.checked=((getCookie("chkScrollbarsVisible","true")=="true")?true:false); frmOptions.chkToolbarVisible.checked=((getCookie("chkToolbarVisible","true")=="true")?true:false); frmOptions.chkAlertsEnabled.checked=((getCookie("chkAlertsEnabled","true")=="true")?true:false); frmOptions.chkContextMenuEnabled.checked=((getCookie("chkContextMenuEnabled","true")=="true")?true:false); frmOptions.chkPropertyDialogEnabled.checked=((getCookie("chkPropertyDialogEnabled","true")=="true")?true:false); } function processCheckbox(varBox,varName) { return("<param name=\""+varName+"\" value=\"" + ((varBox.checked == true) ? "1" : "0") + "\">\n"); } function setCookie(strName, strValue) { document.cookie = strName + "=" + escape(strValue); } function getCookie(strName,strDefault) { var aryCookies = document.cookie.split("; "); for (var i=0; i < aryCookies.length; i++) { var aryValues = aryCookies[i].split("="); if (strName == aryValues[0]) { var strValue = new String(aryValues[1]); return ((strValue != 'undefined') ? unescape(strValue) : strDefault ); } } return strDefault; } --> </script> </head> <body onload="initializeForm()"> <form name="frmOptions"> <table> <tr> <td colspan="5"><b>Display Options</b></td> </tr> <tr> <td width="10"><input accesskey="d" type="checkbox" name="chkPageVisible" checked></td> <td nowrap>Display the <u>d</u>rawing page</td> <td width="20"> </td> <td width="40"><input accesskey="h" type="text" class="text" name="txtHeight" value="300"></td> <td nowrap><u>H</u>eight (in pixels)</td> </tr> <tr> <td width="10"><input accesskey="g" type="checkbox" name="chkGridVisible" checked></td> <td nowrap>Display the <u>g</u>rid if the drawing page is visible</td> <td width="20"> </td> <td width="40"><input accesskey="w" type="text" class="text" name="txtWidth" value="300"></td> <td nowrap><u>W</u>idth (in pixels)</td> </tr> <tr> <td width="10"><input accesskey="q" type="checkbox" name="chkHighQualityRender" checked></td> <td colspan="4">Display using high-<u>q</u>uality rendering</td> </tr> <tr> <td width="10"><input accesskey="t" type="checkbox" name="chkToolbarVisible" checked></td> <td colspan="4">Display the <u>t</u>oolbar</td> </tr> <tr> <td width="10"><input accesskey="s" type="checkbox" name="chkScrollbarsVisible" checked></td> <td colspan="4">Display the <u>s</u>croll bars</td> </tr> </table> <hr> <table> <tr> <td colspan="2"><b>Event Processing Options</b></td> </tr> <tr> <td width="10"><input accesskey="a" type="checkbox" name="chkAlertsEnabled" checked></td> <td>Enable warning or <u>a</u>lert dialog boxes to show when an error occurs</td> </tr> <tr> <td width="10"><input accesskey="c" type="checkbox" name="chkContextMenuEnabled" checked></td> <td>Enable the <u>c</u>ontext menu to show on right-mouse events</td> </tr> <tr> <td width="10"><input accesskey="p" type="checkbox" name="chkPropertyDialogEnabled" checked></td> <td>Enable the <u>P</u>roperties and Settings dialog box to show on selection or toolbar events</td> </tr> </table> <hr> <table> <tr> <td nowrap>URL of <u>V</u>isio File</td> <td><input class="file" accesskey="v" type="text" name="txtVisioFile"></td> </tr> </table> <hr> <table width="100%"> <tr> <td align="right" nowrap> <button class="button" accesskey="o" onclick="insertHTML();"><u>O</u>K</button> <button class="button" accesskey="c" onclick="window.external.Close();"><u>C</u>ancel</button> </td> </tr> </table> </form> </body> </html>
25 September 2002 • by Bob • Microsoft
For some inexplicable reason, Microsoft chose me to be one of their featured employees on the Microsoft Careers website. As a result, I was interviewed and photographed, and my information was posted on the Microsoft website for all to see.
Here is what they posted about me:
Robert
Support Professional
Developer and Line-of-Business Support Internet Team
At Microsoft, we have the opportunity to directly impact the development of a product.
Supporting Microsoft's enterprise-level customers with Microsoft's Internet Information Services Team may seem like a daunting task. Not for Robert, a Support Professional with Microsoft's Developer and Line-of-Business Internet Support Team. He thrives on challenge. "Working on the Internet Support Team is living on the 'Bleeding Edge' of technology," he says. "There are always new issues, new problems to be solved."
It's the excitement generated by Microsoft's products that first attracted Robert to Microsoft. "I worked for a community college in Tucson, AZ," he says, "where I managed a large Windows NT network. We were an all-Microsoft shop, and I was something of a Microsoft software addict. When an opportunity to work at Microsoft came along, I jumped at it."
Starting in Microsoft Access Support, Robert quickly learned that a career at Microsoft would allow him to grow and seek new challenges, while constantly making a difference in the lives of Microsoft's customers-to him, the most rewarding part of his job. "Seeing the way our software helps so many people, and helping them use our software to make their lives easier is great," says Robert.
"Another aspect I enjoy," he adds, "is when an idea of mine becomes part of a new product. I can't think of any other companies where an employee has the ability to contribute to the direction of a project simply by e-mailing a suggestion." Some of the product contributions he's made have even been on behalf of Microsoft's customers. "I'm proud of instances in which I was able to represent our customers' wishes to the Development Team," he adds. "It's always great to be the customers' advocate."
When asked what it's like working at Microsoft, Robert becomes animated. "The way people here work together is amazing," he says, "Microsoft hires people from diverse backgrounds; that allows us to draw on each other's experiences to solve a problem." "And," he contends, "the amount of knowledge that is available internally is staggering - searching our Intranet for information is often more productive than searching the Internet.
The atmosphere of cooperation and camaraderie isn't limited to the workday. While Robert and his co-workers share a passion for technology, a passion for helping Microsoft's customers, and a strong desire to learn, they also share a need to relax, unwind and have fun. "Our team barbecues, goes to lunch together, goes to movies or GameWorks," he says. It's their ability to maintain a balance between work and life that allows them to face the challenges of working in the fluid and fast-paced industry of high technology.
According to Robert, the most technically challenging part of his job is trying to stay abreast of new programming language technologies. "All our programming languages are constantly being redefined to take full advantage of new Windows technologies," he says. And it's the dynamic nature of these languages that often leads to the part of his job that Robert finds most exciting. "Programming," he grins. "There are plenty of opportunities to write code, and I love to write code."
11 June 2002 • by Bob • Windows
Many years ago I put together a bunch of information about logging system activity in W3C format by using Group Policy Objects and Windows Script Host. All of that information was supposed to become Microsoft KB article 324414, but I changed teams and I eventually lost track of its status. Recently I had a need for the information in that KB article and discovered that it was never published, so I had to look for my notes to reconstruct what was supposed to be in the KB article, and I thought that all that effort would make a good blog post.
(Note: This blog post has been updated a few times since it was first posted in order to keep it up-to-date.)
The steps in this blog post will show you how to configure your network for additional logon/logoff information for all domain clients by using a sample Windows Script Host (WSH) script to create log files that conform to the W3C Extended Log File (ExLF) Format.
The W3C Extended Log File Format is currently used on Windows servers by the various web services that install with Internet Information Services. These log files are kept in your %SystemRoot%\System32\LogFiles or %SystemRoot%\Inetsrv\Logs\LogFiles folder. By configuring this sample logging script through a domain-level Group Policy, a new folder named Activity will be created under the %SystemRoot%\System32\LogFiles folder containing log entries formatted like the following example:
#Description: Log file for all LOGON/LOGOFF activity #Date: 2002-01-01 21:28:50 #Fields: date time s-computername cs-username cs-method 2002-01-01 21:28:50 MYCOMPUTER LOCALHOST\SYSTEM STARTUP 2002-01-01 21:32:55 MYCOMPUTER MYDOMAIN\userone LOGON 2002-01-01 21:45:58 MYCOMPUTER MYDOMAIN\userone LOGOFF 2002-01-01 21:47:00 MYCOMPUTER MYDOMAIN\usertwo LOGON 2002-01-01 21:52:02 MYCOMPUTER MYDOMAIN\usertwo LOGOFF 2002-01-01 21:53:09 MYCOMPUTER LOCALHOST\SYSTEM SHUTDOWN
Since there are a wide variety of applications that can process log files in the W3C Extended Log File Format, recording logs in this format allows domain administrators to use tools they are already familiar with when analyzing network logon/logoff information.
NOTE: The W3C Extended Log File Format requires that all times must be kept in Greenwich Mean Time (GMT). As such, all logon/logoff activity recorded by the script in this article will be listed in GMT. This allows a uniform standard for large-scale networks that traverse multiple time zones.
Option Explicit
On Error Resume Next
' declare all variables
Dim objFSO,objFile
Dim objNet,objShell
Dim objProcess,objArgs
Dim strFolder,strFile
Dim blnFileExists
Dim objDateTime,lngTimeZoneOffset
Dim strYear,strMonth,strDay
Dim strLongDate,strShortDate
Dim strShortTime,strMethod
Dim strComputerName,strUserDomain,strUserName
' create all objects
Set objNet = WScript.CreateObject("WScript.Network")
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
Set objShell = WScript.CreateObject("WScript.Shell")
Set objProcess = objShell.Environment("PROCESS")
Set objArgs = WScript.Arguments
' process arguments
If objArgs.Count <> 1 Then WScript.Quit
strMethod = UCase(objArgs(0))
' perform date operations
lngTimeZoneOffset = GetTimeZoneOffset()
objDateTime = Now() - lngTimeZoneOffset
strYear = CStr(Year(objDateTime))
strMonth = Right("00" & CStr(Month(objDateTime)),2)
strDay = Right("00" & CStr(Day(objDateTime)),2)
strLongDate = strYear & "-" & strMonth & "-" & strDay
strShortDate = Right(strYear,2) & strMonth & strDay
strShortTime = FormatDateTime(objDateTime,4) & ":" & Right("00" & CStr(Second(objDateTime)),2)
' get network information
strComputerName = objNet.ComputerName
If Len(strComputerName) = 0 Then strComputerName = "LOCALHOST"
strUserDomain = objNet.UserDomain
If Len(strUserDomain) = 0 Then strUserDomain = "LOCALHOST"
strUserName = objNet.UserName
If Len(strUserName) = 0 Then strUserName = "()"
' get windows directory name
strFolder = objProcess("WINDIR")
' check for and create "System32" folder
strFolder = strFolder & "\System32"
If objFSO.FolderExists(strFolder) = False Then
objFSO.CreateFolder(strFolder)
End If
' check for and create "LogFiles" folder
strFolder = strFolder & "\LogFiles"
If objFSO.FolderExists(strFolder) = False Then
objFSO.CreateFolder(strFolder)
End If
' check for and create "ACTIVITY" folder
strFolder = strFolder & "\ACTIVITY"
If objFSO.FolderExists(strFolder) = False Then
objFSO.CreateFolder(strFolder)
End If
' set up log file name
strFile = "ex" & strShortDate & ".log"
' check if log file exists
blnFileExists = objFSO.FileExists(strFolder & "\" & strFile)
' open or create the log file
Set objFile = objFSO.OpenTextFile(strFolder & "\" & strFile,8,True)
' write headers if new file
If blnFileExists = False Then
objFile.WriteLine "#Description: Log file for all LOGON/LOGOFF activity"
objFile.WriteLine "#Date: " & strLongDate & " " & strShortTime
objFile.WriteLine "#Fields: date time s-computername cs-username cs-method"
End If
' write the log data
objFile.WriteLine strYear & "-" & strMonth & "-" & strDay & " " & _
strShortTime & " " & _
strComputerName & " " & _
strUserDomain & "\" & _
strUserName & " " & _
strMethod
' close the log file
objFile.Close
Function GetTimeZoneOffset()
On Error Resume Next
Dim tmpShell,tmpOffset
Set tmpShell = WScript.CreateObject("WScript.Shell")
tmpOffset = objShell.RegRead("HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\ActiveTimeBias")
If Len(tmpOffset) = 0 Then
tmpOffset = objShell.RegRead("HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\Bias")
End If
' set a default offset if none can be determined
If Len(tmpOffset) = 0 Then tmpOffset = "0"
' calculate offset in hours
tmpOffset = (CLng(tmpOffset) * -1) / 60
' calculate offset in 1/24 of a day
tmpOffset = tmpOffset / 24
GetTimeZoneOffset = tmpOffset
End Function
To use the sample script with the Default Domain Policy Group Policy Object (GPO), you first need to determine the Globally Unique Identifier (GUID) for the GPO. To do so, use the following steps:
To use the sample script with the GPO, you will need to copy the activity.vbs script on your desktop to each of the following paths:
%SystemRoot%\SYSVOL\sysvol\<DOMAIN>\Policies\<GUID>\USER\Scripts\Logon %SystemRoot%\SYSVOL\sysvol\<DOMAIN>\Policies\<GUID>\USER\Scripts\Logoff %SystemRoot%\SYSVOL\sysvol\<DOMAIN>\Policies\<GUID>\MACHINE\Scripts\Startup %SystemRoot%\SYSVOL\sysvol\<DOMAIN>\Policies\<GUID>\MACHINE\Scripts\Shutdown
Where <DOMAIN> is the Fully Qualified Domain Name (FQDN) of your domain, (e.g. mydomain.local ), and <GUID> is the Globally Unique Identifier (GUID) for the Default Domain Policy GPO.
If the Logon Script does not run, you may need to check your network connection speed as the script may not run when you first log on to the network. For additional information on this issue, click the article numbers below to view the articles in the Microsoft Knowledge Base:
302104 The Logon Script Does Not Run During the Initial Logon Process
For more information on the extended log file format, see the specification in the W3C Working Draft at the following URL:
http://www.w3.org/TR/WD-logfile
For additional information on assigning Logon/Logoff Scripts, click the article number below to view the article in the Microsoft Knowledge Base:
322241 HOW TO: Assign Scripts in Windows 2000
For additional information on the Extended Log File Format, click the article numbers below to view the articles in the Microsoft Knowledge Base:
194699 Extended Log File Format Always in GMT
271196 IIS Log File Entries Have the Incorrect Date and Time Stamp
242898 IIS Log File Naming Syntax
21 September 2001 • by Bob • IIS, SSL, Windows
When you manage a certificate server, you will periodically need to issue certificates to requestors. To to so, use the following steps: