Domestic Terrorists Come in Many Forms

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 "Mr. Whit," I was merely offended. His errant ramblings seemed to be another entry in a long line of deranged brain dumps from scores of deranged imbeciles that I seemed to discover whenever I ventured into another dark corner within the vast wastelands of west coast propaganda. I lived in Seattle for a decade or so, and I've seen this type of close-minded lunacy before. To paraphrase the Bard, the author of that particular op-ed, Mr. Whit, has no more intelligence in him than in a stewed prune. (Methinks he doth possess a great deal less.)

After a bit of time had passed, I pondered more about the context of Mr. Whit's article, and I was appalled by the abhorrent vulgarity of what his brief manifesto actually represents: Mr. Whit is a US Citizen who is outspoken and unapologetic about his desire that some form of harm should come to other US citizens. That admission makes him, using today's parlance, a domestic terrorist. Plain and simple. When one American's wish is that other Americans must suffer in order to make a political point, then that American is no better than the abomination that was Timothy McVeigh. After all, the late Mr. McVeigh only wanted to make a political statement when he and his accomplice bombed the Federal Building in Oklahoma City, right?

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, Mr. Whit regards his self-appointed role as an oracle of truth as more beneficial to society than the meager value of average peasants, and therefore he believes that he has the right to condemn other lives to death in order to satisfy his misguided philosophies. The fates of those whom Mr. Whit would send to their graves are secondary to his gargantuan ego, and their lives are worth less than his sanctimonious convictions.

On the one hand, Mr. Whit accuses the US government of believing that "might is right" when it decides who gets to live or die, while on the other hand he freely chooses (from the sanctity of his word-processor) who else gets to live or die. Like Mr. McVeigh before him, Mr. Whit's deplorable appetite for others to suffer for his wretched aberration of morality is fully-vindicated within the boundaries of his twisted, little worldview. I am sure that somewhere inside his hollow, rat-infested cranium, Mr. Whit believes that the "ends justify the means." However, Mr. Whit doesn't have to face the consequences of his brain-dead decrees, whereas the innocent lives that he has condemned to death and their unfortunate families are left to suffer.

History has had more than its fair share of sociopaths who fail to take responsibility for their murderous actions, and Mr. Whit follows their example to the letter when he wishes death upon US troops while skirting away from any personal culpability by laying the blame for their deaths on the government. What Mr. Whit does not realize is that he doesn't get to have it both ways; he cannot pronounce a death sentence on others without being found guilty for his own crimes. He cannot claim that our government is guilty of terrorism, then advocate for the deaths of other US citizens and not be found guilty of his own brand of repugnant and unctuous terrorism. His self-righteous delusions do not grant him the title of judge, jury, or executioner.

It is ironic that short-sighted morons like Mr. Whit are quick to exercise their first amendment right to freedom of speech, while overlooking the sacrifices that were made on his behalf in order to guarantee his right to speak his mind without fear of reprisal. Long before Mr. Whit's feckless mortal coil ventured forth upon the country that he despises and condemns, the same sort of men and women on whom he passes his misguided judgment fought and died so that he might one day have the freedom to spit on their collective memories. Liberals like Mr. Whit never seem to realize that no one can have freedom in this world unless someone is willing to fight for it. It is clear that Mr. Whit will never personally fight for his freedom; he will continue to sit in the shadows and dispatch his putrid, little missives whenever a contrary wind ruffles his delicate feathers.

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 "million-man-march" on the capitol to demand that Congress should bring our brave men and women home. When you get right down to it, I do not mind when someone informs me that something I believe to be right or wrong might be true or false.

However, I damn sure mind when some hypocritical, warthog-faced buffoon signs a death warrant for members of our country's armed forces from the safe haven of his computer keyboard, tucked safely away in an office where no harm will come to him. And yet, despite my personal loathing for Mr. Whit, and in deference to my belief that simpletons like Mr. Whit are utterly useless to society, I do not wish that any harm should come to him. I served in our nation's armed forces so that even a miserable, vomitus mass like Mr. Whit has the right to share his pathetic sentiments in a public forum. And to be honest, if push came to shove, I would do so again. And this is the paradox that makes our country great: the strong and the brave will thanklessly sacrifice their personal safety to fight and defend the rights of the weak and ungrateful cowards who condemn them.

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."

IIS 6: Listing the Host Headers of all Web Sites using ADSI

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!

FrontPage and Text File Databases

Summary

This article discusses how to use a SCHEMA.INI file to access information that is stored in various text file databases.


More Information

Start a blank SCHEMA.INI file
  1. Open a Web in FrontPage 2003 using HTTP
  2. Start a new text file
    1. Click File -> New
    2. Click "Text file" on the Task Pane
    3. Save the file as "_private/schema.ini"
  3. Close the text file
Add a database connection for text file databases
  1. Click Tools -> Site Settings
  2. Click the "Database" tab
  3. Click the "Add" button
  4. Name the connection "TEXTFILES"
  5. Choose "File or folder in current web site"
  6. Click the "Browse" button
    1. Double-click the "_private" folder
    2. Choose "Microsoft Text Driver (*.txt; &.csv)" as the file type
    3. Click "OK" to close the dialog
  7. Click "OK" to close the database connection dialog
  8. Click "OK" to close the site settings dialog
Using a Comma-Separated Value file
  1. If not already open, open the Web form earlier in FrontPage 2003 using HTTP
  2. Start a new page
  3. Save the page as "CSVTEST.htm" in the root of your web site
  4. Insert a form on the page:
    1. Click Insert -> Form -> Textbox
    2. Right-click the form and select "Form Field Properties"
    3. Name the field "Name"
    4. Click "OK" to close the text box properties dialog
    5. Right-click the form and select "Form Properties"
    6. Click the "Options" button
    7. Specify "_private/CSVTEST.csv" as the output path
    8. Choose "Text database usign comma as a separator"
    9. Make sure that the "Include field names" box is checked
    10. Click the "Save Fields" tab
    11. Check the boxes for "Remote computer name", "Browser type", and "Username"
    12. Specify a format for both the date and time
    13. Click "OK" to close the options dialog
    14. Click "OK" to close the form properties
  5. Save and close the page
  6. Preview the page in your browser and submit several data items
  7. Open the "_private/schema.ini" file from earlier
  8. Enter the following information:
    [CSVTEST.csv]
    ColNameHeader=True
    MaxScanRows=25
    Format=CSVDelimited
    CharacterSet=ANSI
  9. Save and close the "_private/schema.ini" file
  10. Start a new page
  11. Insert a database results region on the page:
    1. Click Insert -> Database -> Results
    2. Choose "TEXTFILES" for the connection and click "Next"
    3. Choose "CSVTEST.csv" for the record source and click "Next"
    4. Click "Next"
    5. Choose "Table - one record for row" and click "Next"
    6. Click "Finish"
  12. Save the page as "CSVTEST.asp" in the root of your web site
Using a Tab-Separated Value file
  1. If not already open, open the Web form earlier in FrontPage 2003 using HTTP
  2. Start a new page
  3. Save the page as "TABTEST.htm" in the root of your web site
  4. Insert a form on the page:
    1. Click Insert -> Form -> Textbox
    2. Right-click the form and select "Form Field Properties"
    3. Name the field "Name"
    4. Click "OK" to close the text box properties dialog
    5. Right-click the form and select "Form Properties"
    6. Click the "Options" button
    7. Specify "_private/TABTEST.txt" as the output path
    8. Choose "Text database usign tab as a separator"
    9. Make sure that the "Include field names" box is checked
    10. Click the "Save Fields" tab
    11. Check the boxes for "Remote computer name", "Browser type", and "Username"
    12. Specify a format for both the date and time
    13. Click "OK" to close the options dialog
    14. Click "OK" to close the form properties
  5. Save and close the page
  6. Preview the page in your browser and submit several data items
  7. Open the "_private/schema.ini" file from earlier
  8. Enter the following information:
    [TABTEST.txt]
    ColNameHeader=True
    MaxScanRows=25
    Format=TabDelimited
    CharacterSet=ANSI
  9. Save and close the "_private/schema.ini" file
  10. Start a new page
  11. Insert a database results region on the page:
    1. Click Insert -> Database -> Results
    2. Choose "TEXTFILES" for the connection and click "Next"
    3. Choose "TABTEST.txt" for the record source and click "Next"
    4. Click "Next"
    5. Choose "Table - one record for row" and click "Next"
    6. Click "Finish"
  12. Save the page as "TABTEST.asp" in the root of your web site

References

The following articles discuss the SCHEMA.INI format and related concepts in detail; MSDN keeps rearranging their hyperlinks, so hopefully they are still live:

How to enable or change multiple FrontPage/ASP.NET database editor users

Behavior/Symptoms

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.


Cause

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.


Workaround

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:

  1. Open the web site where you have used FrontPage 2003's Database Interface Wizard (DIW) to create an ASP.NET Database Editor.
  2. Open the "web.config" file in the root folder of your web site.
  3. Locate the section that resembles the following:
    <authentication mode="Forms">
      <forms loginUrl="login.aspx">
        <credentials passwordFormat="SHA1">
           <user name="msbob" password="21BD12DC183F740EE76F27B78EB39C8AD972A757"/>
        </credentials>
      </forms>
    </authentication>
  4. As previously mentioned, ASP.NET Security supports clear text and the MD5 and SHA-1 hash algorithms when configuring user accounts. To change the security method to clear text, change the passwordFormat to "clear". For example:
    <credentials passwordFormat="Clear">
    NOTE - You could just as easily configure "MD5" for the passwordFormat.
  5. If you are configuring the passwordFormat as "SHA1" or "MD5", you can use the following sample code to create the password hashes:
    <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>
  6. Modify or remove the existing user account, which may resemble the following:
    <user name="msbob" password="21BD12DC183F740EE76F27B78EB39C8AD972A757"/>
  7. Add any aditional users as desired.
  8. The resulting credentials section of the "web.config" in the root of the web site may now resemble something like the following:
    <credentials passwordFormat="Clear">
      <user name="user1" password="Password1"/>
      <user name="user2" password="Password2"/>
      <user name="user3" password="Password3"/>
    </credentials>
  9. Save and close the "web.config" for the root folder of your web site.
  10. Open the "web.config" file in the "editor" folder of the ASP.NET database editor that you created in your web site. (For example, if you created a database editor for one of the tables in the built-in sample "Northwind" database, the default folder path from the root of your web site might resemble one of the following paths:
    • /Sample_interface/Categories/editor
    • /Sample_interface/Employees/editor
    • /Sample_interface/Products/editor
  11. Locate the section that resembles the following:
    <authorization>
      <allow users="msbob"/>
      <deny users="*"/>
    </authorization>
  12. Remove or add any users as desired, separating individual users with a comma for the delimiter.
  13. The resulting authorization section of the "web.config" in the "editor" folder for your database editor may now resemble something like the following:
    <authorization>
      <allow users="user1,user2,user3"/>
      <deny users="*"/>
    </authorization>
  14. Save and close the "web.config" in the "editor" folder for your database editor.

When you browse your database editor, you should now be able to enter the credentials for any user accounts that you created.


Additional Information

For additional information on ASP.NET Security and forms-based authentication, please see the following Microsoft Knowledge Base articles:

FrontPage Visio Viewer Web Component

12/05/2010 UPDATE: The download link for the Visio viewer is no longer valid, and I'm sure that the GUID for any new viewer has changed. I'll fix this blog post when I have the chance to get all the new data together.

Summary

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.


More Information

STEP #1 - Locate your "Web Components" folder:

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"

 

STEP #2 - Save the following INI file in the folder as "VISIO.INI":
[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.

 

STEP #3 - Save the following HTML file in the folder as "VISIO.HTM":
<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">&nbsp;</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">&nbsp;</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>

 

STEP #4 - Open a new page in FrontPage

 

STEP #5 - Click "Insert" -> "Web Component"

 

STEP #6 - Select "Microsoft Visio" in the list of component types

 

STEP #7 - Choose to insert the HTML-only version or the the wizard-based version

NOTES:

  1. The HTML-only version inserts just the ActiveX control, allowing you to modify the raw HTML, but is less user-friendly when you double-click it.
  2. The wizard-based version is more user-friendly for inserting and modiyfing the control, but it is a web-bot and therefore does not allow you to modify the raw HTML.
  3. The codbase download path for the control is hard-coded; if that changes, you will need to update the INI file and HTML file accordingly.

My 15 Minutes of Fame

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:


robmcm (2)

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."

How to Record Logon Activity in W3C Extended Log File Format using WSH

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.)


IN THIS POST


APPLIES TO

  • Windows Server 2008 R2
  • Windows 7
  • Windows Server 2008
  • Windows Vista
  • Windows Server 2003 R2
  • Windows Server 2003
  • Windows XP
  • Windows Server 2000

SUMMARY

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.


MORE INFORMATION

Step 1 - Create the Sample Logging Script

  1. Log on to your Windows Domain Controller as a Domain Administrator.
  2. Open Windows Notepad by clicking Start, then All Programs, then Accessories, and then Notepad.
  3. Type or paste the following WSH code into notepad:
    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
  4. Save the file:
    • Click the File menu, and then Save.
    • When the Save As dialog appears, choose your desktop as the destination.
    • Enter activity.vbs for the File name.
    • Click the Save button.
  5. Click the File menu, and then Exit to close Notepad.

Step 2 - Copy the Sample Logging Script to your Group Policy Folders

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:

  1. Start the Active Directory Users and Computers snap-in in the Microsoft Management Console (MMC). To do so, click Start, point to All Programs, point to Administrative Tools, and then click Active Directory Users and Computers.
  2. Right-click your domain, and then click Properties.
  3. Click the Group Policy tab.
  4. Highlight the Default Domain Policy, and then click the Properties button:
    • The GUID for the GPO will be listed as the Unique name property in the Summary section of the properties dialog.
    • The Default Domain Policy GUID will always be {31B2F340-016D-11D2-945F-00C04FB984F9}, if you choose enable logging in a different policy this will be a different GUID.
  5. Click the Cancel button to close the GPO properties dialog.
  6. Click the Cancel button to close the domain properties dialog.

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.

Step 3 - Configure the Script to Record LOGON/LOGOFF Activity

  1. Start the Active Directory Users and Computers snap-in in the Microsoft Management Console (MMC). To do this, click Start , point to Programs , point to Administrative Tools , and then click Active Directory Users and Computers .
  2. Right-click your domain, then click Properties .
  3. Click the Group Policy tab.
  4. Highlight the Default Domain Policy , then click the Edit button.
  5. In the console tree, click the plus sign (+) next to the Windows Settings under User Configuration , then highlight Scripts (Logon/Logoff) .
  6. Add the Logon script:
    1. In the right pane, double-click the Logon item.
    2. Click the Add button.
    3. Click the Browse button.
    4. Highlight activity.vbs , then click the Open button.
    5. Type LOGON in the Script Parameters box.
    6. Click OK to add the script.
    7. Click OK to close the Logon scripts dialog.
  7. Add the Logoff script:
    1. In the right pane, double-click the Logoff item.
    2. Click the Add button.
    3. Click the Browse button.
    4. Highlight activity.vbs , then click the Open button.
    5. Type LOGOFF in the Script Parameters box.
    6. Click OK to add the script.
    7. Click OK to close the Logoff scripts dialog.
  8. Close the Group Policy Editor.
  9. Click OK to close the domain properties dialog.

Step 4 - Configure the Script to Record STARTUP/SHUTDOWN Activity

  1. Start the Active Directory Users and Computers snap-in in the Microsoft Management Console (MMC). To do this, click Start , point to Programs , point to Administrative Tools , and then click Active Directory Users and Computers .
  2. Right-click your domain, then click Properties .
  3. Click the Group Policy tab.
  4. Highlight the Default Domain Policy , then click the Edit button.
  5. In the console tree, click the plus sign (+) next to the Windows Settings under Computer Configuration , then highlight Scripts (Startup/Shutdown) .
  6. Add the Startup script:
    1. In the right pane, double-click the Startup item.
    2. Click the Add button.
    3. Click the Browse button.
    4. Highlight activity.vbs , then click the Open button.
    5. Type STARTUP in the Script Parameters box.
    6. Click OK to add the script.
    7. Click OK to close the Startup scripts dialog.
  7. Add the Shutdown script:
    1. In the right pane, double-click the Shutdown item.
    2. Click the Add button.
    3. Click the Browse button.
    4. Highlight activity.vbs , then click the Open button.
    5. Type SHUTDOWN in the Script Parameters box.
    6. Click OK to add the script.
    7. Click OK to close the Shutdown scripts dialog.
  8. Close the Group Policy Editor.
  9. Click OK to close the domain properties dialog.

TROUBLESHOOTING

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


REFERENCES

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

IIS 5: Setting up SSL - Appendix C: Processing a Certificate Request

When you manage a certificate server, you will periodically need to issue certificates to requestors. To to so, use the following steps:

  1. Open the "Certificate Authority" administrative tool:

  2. Click on "Pending Requests":

  3. Right-click the pending request and choose "All Tasks", then click "Issue":

  4. The certificate will now show up under "Issued Certificates":

IIS 5: Setting up SSL - Appendix B: Obtaining a Root Certificate

Obtaining a root certificate is one of the most important steps for servers or clients that will use certificates that you issue. While this step is not necessary on the server where you installed Certificate Services, it is absolutely essential on your other servers or clients because it allows those computers to trust you as a Certificate Authority. Without that trust in place, you will either receive error messages or SSL simply won't work.

This process is broken into two steps:


Downloading the Root Certificate

  1. Browse to your certificate server's address, (e.g. http://<server-name>/certsrv/), and choose to retrieve the CA certificate:

  2. Click the link to download the CA certificate:

  3. Choose to save the certificate file to disk:

  4. Save the file to your desktop:


Installing the Root Certificate

Before using any certificates that you issue on a computer, you need to install the Root Certificate. (This includes web servers and clients.)

  1. Double-click the file on your desktop:

  2. Click the "Install Certificate" button:

  3. Click "Next" to start the Certificate Import Wizard:

  4. Choose to automatically choose the store:

  5. Click the "Finish" button:

  6. Click "Yes" when asked if you want to add the certificate:

    NOTE: This step is very important. If you do not see this dialog, something went wrong.
  7. Click "OK" when informed that the import was successful.

IIS 5: Setting up SSL - Appendix A: Installing Certificate Services

In this blog post I'll discuss installing Certificate Services for Windows 2000 in order to test SSL in your environment. To install Certificate Services, use the following steps:

  1. Run the "Windows Component Wizard" in "Add/Remove Programs", choose "Certificate Services", and click "Next":

  2. Choose "Stand-alone root CA", then click "Next":

  3. Enter all requested information, then click "Next":

  4. Accept the defaults for the data locations and click "Next":

  5. The wizard will step through installing the services:

  6. When the wizard has completed, click "Finish" to exit the wizard: