XML archives - The VBScript Network and Systems Administrator's Cafe

The VBScript Network and Systems Administrator's Cafe:

XML

Dec 8 2008   10:54PM GMT

A great XMLDOM online reference for creating XSLT Translation documents



Posted by: Jerry Lees
XML, XSLT, XMLDOM, Online References

If you were interested in my previous posts relating to XML and XSL Translations. You’ll know how difficult it is sometimes to get the syntax right and know what functions are available to you when writing a XSLT document to translate a XML file into HTML.

Well, I recently found a great reference for XML’s XMLDOM interface. Check it out,

Oct 3 2008   3:00PM GMT

How to retrieve HTML web pages with VBScript via the Microsoft.XmlHttp object



Posted by: Jerry Lees
HTTP, HTML, XML, VBScript, VBScript Objects, Microsoft.XmlHttp, Web Pages

Recently, I had a situation where I had to pull down a HTML page to compare it to a known copy of the page. Certainly, IE or FireFox– or Google’s Chrome would have done the trick and I could have viewed the source. But that would require me to do work every time we needed to check the page against the known good source.

 Instead I wrote a script to pull the HTML source and echo the response to the console (or a messag box if you are not using cscript to execute the script). While not a full blown HTTP QA script it does do the job of getting the HTTP responses from the server and is certainly a core part of any QA script anyone would write.

Basically the script uses the Microsoft.XMLHTTP object to preform all the HTTP calls and retrieve the HTML page. It sounds scary, but if you look at the script below I think you’ll find that it really is quite easy to accomplish.  So, here is the script’s code:

URL=”http://www.gamersigs.net/
Set WshShell = WScript.CreateObject(”WScript.Shell”)
Set http = CreateObject(”Microsoft.XmlHttp”)

On Error Resume Next
http.open “GET”, URL, False
http.send “”
if err.Number = 0 Then
     WScript.Echo http.responseText
Else
     Wscript.Echo “error ” & Err.Number & “: ” & Err.Description
End If
set WshShell = Nothing
Set http = Nothing

Enjoy!


May 2 2008   4:15PM GMT

Easily document group policy objects in Microsoft Word using VBScript with the Microsoft.XMLDOM and Word.Application objects



Posted by: Jerry Lees
Documentation, XML, VBA, VBScript, DataManagement, Microsoft.XMLDOM, Functions, Word.application

OK, here is the posting I hinted at in  my previous posting this week entitled, Using VBScript to create Word documents automatically with the Word.Application Object. In that posting I mentioned a project where I had to create a ton of documentation… but I didn’t say what it was that I had to document. Yeah, you guessed it from this article’s title… Group Policy Settings! I had to document settings in a series of policies I was proposing we implement at my employer. Here is the scenario:

I was asked “Can you document all the settings you are proposing in the new policies for the other members of IT? Also, Can you document the name of the setting, what you want it to be and what options are available to change it to? Oh, and what each value means when you set it?…. Do you think you’ll have time to also let us know for each setting what the supported or intended OS version is for the setting? I need it by Friday.”

Now, much like you might do, I said “I’ll try.” and mumbled under my breath later “If you bring me a pound of Lead I’ll turn it to Gold too!”… None the less, after my initial pity party, I began looking at the Information available to me in the Group Policy Management Console (Available here if you don’t have it already.), much to my surprise I found almost everything I needed when I looked at the individual settings… it just wasn’t in a format I could show to people or they could read easily. So I set out to try and copy and paste the information into word… for 20 seconds… and realized this is way to much work! And what do I always say??????   Be Lazy!

Now I looked at the options available to me on exporting the file and CSV was one of them, but unfortunately all the relationships were lost and I couldn’t make heads or tails of how to cobble it back together in a meaningful way after the export. Then I noticed XML and remembered my last post on Microsoft.XMLDOM (Using XML in VBScript via Microsoft.XMLDOM to work with data feeds) and thought, I really need to get back to that… so here we are!

First, Just like my last post– you’ll need Microsoft Word installed where you run this script for it to operate. Then you’ll need to use The Group Policy Management console to export the policy settings to XML. (hover over the icons along the top, it’s the one with the icon that looks like a page of paper with an arrow pointing right, one of the save as options is XML.) Save this file into the location where the script is located (I recommend a descriptive name, because it will be the heading for your document.) and with a single edit of the script you will have a word doc on the root of your C: drive with the same name— only documented in Word!

The script basically opens and reads in the XML Document and creates a Word.Application object to create a Microsoft Word Document at the root of the C: Drive, then writes formatted text to the document to make the data in the XML readable. But, enough of a introduction! On to the script! Here is the script:

 set xmlDoc=CreateObject(”Microsoft.XMLDOM”)
Set objWord = CreateObject(”Word.Application”)
Set objDoc = objWord.Documents.Add()
Set objSelection = objWord.Selection

‘This is the actual name of the XML document minus the path and the “.XML” extension, it becomes the word doc header
xmlfile = “Locked Down Desktop Policy”

objSelection.Font.Name = “Arial”
objSelection.Font.Size = “18″
objSelection.Font.Bold = True
objSelection.TypeText xmlfile & VbCrLf

objSelection.Font.Bold = False
objSelection.Font.Size = “10″

xmlDoc.async=”false”
xmlDoc.load(xmlfile &”.xml”)
for each x in xmlDoc.documentElement.childNodes
If x.nodename = “Computer” or x.nodename = “User” Then
For Each y In x.childnodes
if y.Nodename = “ExtensionData” then
For Each z In y.childnodes
If z.Nodename = “Extension” Then
For Each setting In z.childnodes
objSelection.TypeText “______________________________________” & vbCr
DocumentPolicy(Setting)
Next
End if
Next
End if
Next
End If
Next
objDoc.SaveAs(”C:\” & xmlfile & “.doc”)
objWord.Quit

Function DocumentPolicy(Setting)
‘this function basically cleans up the headers of the word document, so they are more human readable
Select Case setting.nodename
Case “q1:Policy”
replacestr = “q1:”
Case “q1:DropDownList”
replacestr = “q1:”
Case “q1:Name”
replacestr = “q1:”
Case “q1:Value”
replacestr = “q1:”
Case “q1:State”
replacestr = “q1:”
Case “q2:Audit”
replacestr = “q2:”
Case “q2:SecurityOptions”
replacestr = “q2:”
Case “q2:EventLog”
replacestr = “q2:”
Case “q2:RestrictedGroups”
replacestr = “q2:”
Case “q2:File”
replacestr = “q2:”
Case “q2:Display”
replacestr = “q2:”
Case “q3:General”
replacestr = “q3:”
Case “q3:HashRule”
replacestr = “q3:”
Case “q3:PathRule”
replacestr = “q3:”
Case “q3:InternetZoneRule”
replacestr = “q3:”
Case “q4:AutoEnrollmentSettings”
replacestr = “q4:”
Case “q4:AutoEnrollmentSettings”
replacestr = “q4:”
Case “q4:RootCertificateSettings”
replacestr = “q4:”
Case “q4:EFSSettings”
replacestr = “q4:”
Case “q5:PreferenceMode”
replacestr = “q5:”
Case “q2:PreferenceMode”
replacestr = “q2:”
Case “q2:ProxySettings”
replacestr = “q2:”
Case “q2:UseSameProxy:”
replacestr = “q2:”
Case “q2:HTTP:”
replacestr = “q2:”
Case “q2:NoProxyIntranet:”
replacestr = “q2:”
End Select
objSelection.Font.Bold = True
objSelection.TypeText VbCrLf & replace(setting.nodename, replacestr,””) & VbCrLf
objSelection.Font.Bold = False
For Each Value In Setting.Childnodes
NodeName = replace(Value.nodename,replacestr,””)
If NodeName = “Explain” Then
objSelection.Font.Bold = True
objSelection.TypeText Nodename & “: ” & vbcrlf
objSelection.Font.Bold = False
objSelection.TypeText vbTab & replace(value.text,”\n\n”, VbCrLf & VbCrLf & vbTab )& vbcrlf
Else
objSelection.Font.Bold = True
objSelection.TypeText Nodename & “: “
objSelection.Font.Bold = False
objSelection.TypeText vbtab & value.text & vbcrlf
End if
Next
If isnull(Setting.childnodes) Then
For Each node In Setting.childnodes
DocumentPolicy(node)
next
End if
objSelection.TypeText VbCrLf
End FunctionNow, when you run this script agains your export there may be some XML tags I didn’t notice because a setting you set is one I didn’t set. Any time you see them in the document you can add a new Case statement in the select case followed by setting the replacestr to the string you want to replace with a null. The lines I’m talking about look similar to this:

  Case “q2:xxxxxxxx”
replacestr = “q2:”

As always, this code works perfectly. However, sometimes the formatting of the blog breaks the code if you copy and paste it into your editor. So, if you’d like to not type or troubleshoot any syntax errors due to the copy and paste problems– I’ve provided the code for download, plus example output files  from my final tests for you. You’ll find the code and other files available for download from my website’s (www.websystemsadministration.com) File Depot under the ITKE Blog Scripts category. Enjoy and happy scripting!


Mar 21 2008   5:39PM GMT

Explanation: Using Microsoft.XMLDOM to work with data feeds in VBScript



Posted by: Jerry Lees
XML, Development, VBScript, DataManagement, Microsoft.XMLDOM, 360voice

You may recall we recently worked with a cool little script that itself didn’t have anything to do with systems administration, the 360voice API script in a previous post, but the concepts can be used in many different areas since XML data feeds are ever becoming the standard way to communicate related data between applications and systems.

In this script, I used many topics we’ve previously discussed and added a powerful object, Microsoft.XMLDOM. Essentially, DOM stands for Document Object Model– which is a way for the document to describe and relate the data it contains. Here is an example XML document header for “mydata”

<?xml version=”1.0″?>
<!DOCTYPE Mydata SYSTEM “mydata.dtd”>

This essentially in the first line tells us the file is an XML document, Version 1.0 to be specific, and in the second line tells us the Document Type Definition file that we can have the parser verify the XML file against. DTD’s and XML Schemas are beyond the scope of what we’re discussing but can be very useful becasue they define the rules by which a XML document must conform to be considered valid– however they are not required to be in an XML file.

After these lines the XML file has nodes and child nodes in it. This is where the bulk of our work was done going through the nodes and pulling out child nodes and values. In this illustration we’ll use the following URL to my XML Game data at 360voice.com (note the data will change over time, but the datastructure should stay pretty much the same)

As of this moment, the file looks like:

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<api>
<info>
<version>1.2</version>
<gamertag>jlees</gamertag>
</info>
<gamerscore>
<score>
<value>23740</value>
<date>3/20/2008 4:42:02 AM</date>
</score>
<score>
<value>23740</value>
<date>3/19/2008 4:45:18 AM</date>
</score>
</gamerscore>
</api>

Notice how the main Node (The “document” Node) is titled api? The XML Parser automatically read that entire node in at the load of the document. After that we have nodes called info and gamerscore that both contain data and/or child nodes.

the info tag contains the version and gamertag values, you’ll notice I used the gamertag value in the script to pull the name of the gamertag with this line of the script code after checking to see if the currently looped through tag had the name “info”:

WScript.Echo GetTagValue(x,”gamertag”)

See how that works? This example was pretty simple since it was just off the root. The score value and date were a bit harder to get at, but not to bad.

They are contained in a child node called “score”, but they are a child of gamerscore– so you’ll see that I check to see if the tag is “gamerscore” and then loop through the score tag separately looking for each instance of the node called score and pulling the tag value and placing it into an array called gamerscore.

All pretty straightforward. There are certainly better ways to deal with XML than writing code tightly around the XML itself, but this illustrates the use of Microsoft.XMLDOM and explains the heirarchial nature of XML nicely the way it’s been coded.

See if you can play around with the code and make it better! Thanks again to the folks at 360voice for providing the API and it’s documentation!

Happy coding and have fun!


Mar 14 2008   5:57PM GMT

Using XML in vbscript via Microsoft.XMLDOM to work with data feeds



Posted by: Jerry Lees
XML, VBScript, DataManagement, Microsoft.XMLDOM, 360voice

In this installment I wanted to both celebrate and congratulate the winners of the ITKE Challenge that has been running over the last few months for an XBOX 360 ELITE system, among other prizes. I also wanted to write about XML use in vbscript as well so the challenge was how to accomplish both tasks…

Then I remembered a great community site, that I’ve been a member of for a little over a year or so, called 360voice. Basically, those guys have a truly awesome idea over there… I play games with my Xbox 360 and it blogs about the times we have—and I don’t have to do any work on my own. ;-) If you have a 360 and don’t have an account setup, go over and check it out, tell ‘em Jlees sent you. Heck, while you are at it watch my blog there and drop me a note.

At any rate, one of my challenges was to get everyone the same XML file, while not creating it myself because I wanted the script to be useful under certain circumstances. 360voice came through with their API Documentation! Think about it… now your scripting life has insite into your gaming life (and other’s as well) you could write a script to compare your achievements to your buddies, show the games you haven’t completed, and all sorts of other stuff. Why?? Because you can!

Consider this working code (that indecently pulls the XML directly from the website without saving it locally) that shows the last 10 days of gamerscore history for two gamertags in the output, in my case I chose mine, Jlees, and one of the owners of the site, changeagent, to do the comparison.. From this script alone you could graph your gamerscore and a buddies so you can compare and have irrefutable bragging rights about your gaming powers! (notice: that I put just about everything together we’ve talked about up to now in this one script, if your just joining us you might want to go back and brush up the last few weeks worth of blogs really quick. Also, I’ve noticed some cases where the sourcecode does not copy correctly, so I have uploaded the source to this article to my website here for you to download.)

Option Explicit

Dim GamerTag1,GamerTag2, GamerScore, Days, xmlDoc, x, y, Value, Count

GamerTag1 = “CrashSerious” ‘change this to your gamertag
GamerTag2 = “ChangeAgent” ‘change this to your buddies gamer tag
‘ a quick note on the following line. It’s great the folks at
www.360voice.com gave us this API
‘ While you likely can change this to something other than 10 below, I strongly encourage you To
‘ limit it to less than a month. The pulling of this data will no doubt have an impact on their servers
‘ and excessive pulls will likely get you blocked, the API removed, or restricted.
‘ Basically, be a good neighbor.
Days = 10 ‘ change this to the number of days to pull.

DisplayTagHistory(GamerTag1)
DisplayTagHistory(GamerTag2)

Sub DisplayTagHistory(GamerTag)
 set xmlDoc=CreateObject(”Microsoft.XMLDOM”)

 ReDim GamerScore(Days)

 xmlDoc.async=”false”
 xmlDoc.load(”
http://www.360voice.com/api/score-getlist.asp?tag=” & GamerTag & “&num=” & days)
 for Each x in xmlDoc.documentElement.childNodes
   If x.nodename = “info” Then ‘ this is where the gamer tag is located in the node named “gamertag”
    WScript.Echo GetTagValue(x,”gamertag”)
   End If
 
   If x.NodeName = “gamerscore” Then
  Count = 0
  For Each y In x.childnodes  ’ this is where the score for that day is located
         ’ in a node named “value”
   GamerScore(Count) = GetTagValue(y,”value”)
   ’below we output the data. You could easily change the “vbTab & “:” & vbTab” to
   ’a , and create a CSV or write to a file. the world’s wide open from here.
   WScript.Echo Date-Count & vbTab & “:” & vbTab & Gamertag & vbTab & “: ” & GamerScore(Count)
   Count = Count + 1
  Next
   End If
 Next
End sub

‘note this function assumes only one node named the same as SrchStr is in the XMLTAG child node.
‘ if there is more than one, only the last value will be returned.
Function GetTagValue(XMLTag, SrchStr)
 for each Value In XMLTag.childNodes
    if ucase(Value.nodename) = Ucase(SrchStr) Then
     GetTagValue = Value.text ‘get the value in the node requested.
    End If
 Next 
End Function

The output, with the script untouched, should look like so:

 JLees
3/14/2008 : JLees : 23740
3/13/2008 : JLees : 23730
3/12/2008 : JLees : 23730
3/11/2008 : JLees : 23730
3/10/2008 : JLees : 23730
3/9/2008 : JLees : 23730
3/8/2008 : JLees : 23700
3/7/2008 : JLees : 23700
3/6/2008 : JLees : 23700
3/5/2008 : JLees : 23700
ChangeAgent
3/14/2008 : ChangeAgent : 12817
3/13/2008 : ChangeAgent : 12817
3/12/2008 : ChangeAgent : 12817
3/11/2008 : ChangeAgent : 12817
3/10/2008 : ChangeAgent : 12817
3/9/2008 : ChangeAgent : 12817
3/8/2008 : ChangeAgent : 12817
3/7/2008 : ChangeAgent : 12817
3/6/2008 : ChangeAgent : 12817
3/5/2008 : ChangeAgent : 12777

I only used ONE new thing in this code Microsoft.XMLDOM, which we’ll discuss in a later entry but I wanted to call your attention to the following line in this entry:

xmlDoc.load(”http://www.360voice.com/api/score-getlist.asp?tag=” & GamerTag & “&num=” & days) 

 

This line is the one where you would specify the path for the XML file, whether it is a local file or a file on the internet—like this rss feed to my blog. Also note that the DisplayTagHistory subroutine is highly focused to this XML feed and will likely need some work to get it to display another.

Enjoy!

Extra Credit: Can you modify the code to include the other owner of the 360voice site and compare his score with mine and changeagent’s? His Gamertag is Fatty Chubs.