Yeshai Bouskila Just Another Site Of Mine

31Jan/120

VBScript Read XML File – How To???

So you have an XML file and you want to use it with VBSCript....
In this post we will review reading an XML file by knowing the TAG names, next time we will break down on opening an XML file without knowing the tags.

Let's take a look at this xml file (if you don't know what's XML then go here linky).

I have multiple tags with values, if you know the XML tag

<?xml version='1.0' encoding='UTF-8'?>
<!-- This document was created with Syntext Serna Free. --><YeshaiUpgrade xmlns="Yeshai Upgrade Package">
  <Upgrade>
    <Version>
      <FirstPackage>Yes</FirstPackage>
      <UpgradeType>YeshaiMainComp</UpgradeType>
      <NewVersion>Yeshai.57</NewVersion>
      <OldVersion>Yeshai.50</OldVersion>
      <UpgradeBaseFolder>C:\Yeshai</UpgradeBaseFolder>
      <Reboot>No</Reboot>
      <ExecuteEndSciprt>Upgrade.vbs</ExecuteEndSciprt>
      <ShutDownServices>Yes</ShutDownServices>
      <ShutDownXMLFile>SomeFile.XML</ShutDownXMLFile>
      <ExecuteAfterReboot>Yes</ExecuteAfterReboot>
      <ExecuteAfterRebootScript>Phase2.vbs</ExecuteAfterRebootScript>
      <Notes>Just Some Notes About The Package</Notes>
    </Version>
  </Upgrade>
</YeshaiUpgrade>

First thing we need to reference the XML object

	Set xmlDoc = CreateObject("Msxml2.DOMDocument")

now we are going to make a reference to our XML file
You can set this how ever you want but I'm going based on the fact I don't know the path to where the file will be (this is not mandatory)

		sPackageFile = sCurPath & "\UpgradePackage.xml"

Next step is referencing each and every tag you want to pull from the XML file

		FirstPackage = XMLRead (sPackageFile,"FirstPackage")
		UpgradeType = XMLRead (sPackageFile,"UpgradeType")
		NewVersion = XMLRead (sPackageFile,"NewVersion")
		OldVersion = XMLRead (sPackageFile,"OldVersion")
		UpgradeBaseFolder = XMLRead (sPackageFile,"UpgradeBaseFolder")
		Reboot = XMLRead (sPackageFile,"Reboot")
		ExecuteEndSciprt = XMLRead (sPackageFile,"ExecuteEndSciprt")
		ShutDownServices = XMLRead (sPackageFile,"ShutDownServices")
		ShutDownXMLFile = XMLRead (sPackageFile,"ShutDownXMLFile")
		ExecuteAfterReboot = XMLRead (sPackageFile,"ExecuteAfterReboot")
		ExecuteAfterRebootScript = XMLRead (sPackageFile,"ExecuteAfterRebootScript")
		Notes = XMLRead (sPackageFile,"Notes")

Now I love functions so just for y'all I've added this function

Function XMLRead(XMLFileName, XMLTag)
		xmlDoc.load(XMLFileName)
		Set ElemList = xmlDoc.getElementsByTagName(XMLTag)
		XMLRead = ElemList.item(0).Text

End Function

After you run the process each one of the values is read from the XML file...

Quite simple :)

Print This Post Print This Post
19Aug/110

Modify Text/Batch/Registry Files For Automation

So let's say you are working with Batch Files or Regsitry files and you want to automate so sort of process to prompt a user for an input box and change values.

We have a registry file that contains the following information that we want to change.
Make sure that you set the text you want to change to strings that aren't anywhere else in the file or else you will make changes to multiple items so don't just change a "Y" to something else.

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\YeshaiB]
"SiteID"="XXXX"
"PhoneNumber"="PPP-PPP-PPPP"
"TerminalID"="TID"

First we will start with a input box for SiteID, PhoneNumber and TerminalID

	set objShell = CreateObject("Wscript.Shell")
	Set objFSO = CreateObject("Scripting.FileSystemObject")

	SiteID = InputBox("Please Enter SiteID", "Site ID","")
	PhoneNumber = InputBox("Please Enter PhoneNumber in the following format xxx-xxx-xxxx","Phone Number","xxx-xxx-xxxx")
	TerminalID = InputBox("Please Enter TerminalID","Terminal ID","")

You can add protection around the input boxes so you have to enter a minimum amount of characters or must be numeric and have a specific amount of digits if you need.
This would be easier to accomplish by specific functions but let's talk about that some other time.

Now let's update our registry file before we merge it or deploy it.
First we point to our registry file

File = "C:\yeshaib.reg"

Now we will open the file and read the content, look for specifc strings and replace them.

Const ForReading = 1
Set objFile = objFSO.OpenTextFile(File, ForReading)
MyString = objFile.ReadAll()
objFile.Close

MyString = Replace(MyString, "PPP-PPP-PPPP", PhoneNumber, 1, -1, 1)
MyString = Replace(MyString, "XXXX", SiteID, 1, -1, 1)
MyString = Replace(MyString, "TID", TerminalID, 1, -1, 1)

Set objFile = objFSO.CreateTextFile( File, True)
objFile.Write MyString
objFile.Close

Run the script and it will prompt you three times

ID

Phone

TID

And the Registy file will have the correct changes

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\YeshaiB]
"SiteID"="8192"
"PhoneNumber"="972-972-9972"
"TerminalID"="4"
Print This Post Print This Post
11Feb/112

Changing Computers IP Addresses with VBScript

So now that we changed the machine name and user names we might need to change some IP's....

As you can see below you will need to specify the IP's somehow (hard coded right now) with a MSGBOX, Registry read, text file, Machine name etc

'----------------------------------------------------------------------

	const HKLM   = &H80000002

	Set WshShell = CreateObject("WScript.Shell")
        Set objFSO = CreateObject("Scripting.FileSystemObject")
	Set oNetwork = CreateObject("WScript.Network")

	strCurrentComputerName = oNetwork.ComputerName

	'Setup IP's you want to implament, you can add logic for MSGBOX etc.
		strComputer = "."
		IPAddress = "10.11.12.13"
		dGateway = "10.11.12.11"
		arrIPAddress = Array(IPAddress)
		arrSubnetMask = Array("255.255.255.128")
		arrGateway = Array(dGateway)
		arrDNSServers = Array("12.107.200.146")

		Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
		Set colNetAdapters = objWMIService.ExecQuery("Select * from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")

		For Each objNetAdapter in colNetAdapters
		     errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)
		     errGateways = objNetAdapter.SetGateways(arrGateway)
		     intSetDNSServers = objNetAdapter.SetDNSServerSearchOrder(arrDNSServers)
		Next

		If intSetDNSServers = 0 Then
		    MSGBOX("Server IPs set to: IPAddress = " & IPAddress)
		Else
			MSGBOX("Error setting server info.")
	 	End If
Print This Post Print This Post
10Feb/111

Rename Machine Name with VBS

So... we renamed a user name with VBS here - Linky but now we need to change the machine name.
How simple is that? very

As you can see below specify a machine name under
strNewName = "InRimServer"
So "InRimServer" is the hard coded name of the script but you can change this with a MSGBOX or pull the value from other locations....
And initiate a reboot in the end of the script (or manually afterwards)


'----------------------------------------------------------------------

	const HKLM   = &H80000002

	Set WshShell = CreateObject("WScript.Shell")
    Set objFSO = CreateObject("Scripting.FileSystemObject")
	Set oNetwork = CreateObject("WScript.Network")

	strCurrentComputerName = oNetwork.ComputerName

 	strNewName = "InRimServer"

	strKeyPath   = "System\CurrentControlSet\Control\ComputerName\ComputerName"
	set objReg = GetObject("winmgmts:\\" & strCurrentComputerName & "\root\default:StdRegProv")
	intRC = objReg.SetStringValue(HKLM, strKeyPath, "ComputerName", strNewName)

	if intRC <> 0 Then
		MSGBOX("Error setting ComputerName value: " & intRC)
	Else
		MSGBOX("Successfully set ComputerName value to " & strNewName)
	end if

	strKeyPath   = "System\CurrentControlSet\Services\Tcpip\Parameters"
	intRC = objReg.SetStringValue(HKLM, strKeyPath, "NV Hostname", strNewName)
	if intRC <> 0 Then
		MsgBox("Error setting NV Hostname value: " & intRC)
	Else
		MsgBox("Successfully set NV Hostname value to " & strNewName)
	end if

 	'Remove the comments if you want an auto reboot
' 	MsgBox("Rebooting system...")
' 	WScript.Echo "Rebooting system..."
'	Set OpSysSet = GetObject("winmgmts:{impersonationLevel=impersonate,(Shutdown)}//" & strComputer).ExecQuery("select * from Win32_OperatingSystem where Primary=true")
'    for each OpSys in OpSysSet
'        OpSys.Reboot()
'    Next    
Print This Post Print This Post
1Feb/110

Rename Users with VBScript

This question came through the red phone line (well email).... (and there were two questions but I'll save the other for a different post....)
And it's quite simple but we are going to cheat here and use a net user command.

So we need to determine a few things well just one thing, Is the user name constant name or does it change?

So this is how my script would look like
I'm going to look at this as if the user is a constant user (name does not change)

' Set some objects
    Set WshShell = CreateObject("WScript.Shell")
    Set objFSO = CreateObject("Scripting.FileSystemObject")

    Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")

'get our constant user name from the system (change the UserNameHere)
Set colItems = objWMIService.ExecQuery ("Select * from Win32_UserAccount Where Name = 'UserNameHere'")
	For Each objItem in colItems
	  objItem.Rename "NewUserNameHere"
	next
'change the user name
 WshShell.Run "cmd /c net user UserNameHere /fullname: NewUserNameHere", 1, true 

Kinda simple, but what happens if you don't know the user name and simply want to change the user name?
I don't think this is a good idea but lets say we just want to add some characters to the user...

So we are going to add a few lines and change a few lines...

' Set some objects
    Set WshShell = CreateObject("WScript.Shell")
    Set objFSO = CreateObject("Scripting.FileSystemObject")

    Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
'set and get the current user account
    Set objNetwork = CreateObject("WScript.Network")
    strUserName = objNetwork.UserName

'get our constant user name from the system remember we got the current user before

Set colItems = objWMIService.ExecQuery ("Select * from Win32_UserAccount Where Name = '" & strUserName & "'")
	For Each objItem in colItems
	  objItem.Rename strUserName & "Tech"
	next
'change the user name
 WshShell.Run "cmd /c net user "& strUserName &" /fullname: """ & strUserName & "Tech""", 1, true
MsgBox "cmd /c net user "& strUserName &" /fullname: " & strUserName & "Tech"

Don't forget to add some protection and logging, and if you need to change your auto login etc...
As well you might not need the MsgBox and you will need to reboot.

Print This Post Print This Post
17Jan/110

VBScripts – Generic Templates for download

Hello Readers,

I've added a download section where I will provide templates for Generic Scripts that you can modify and use.
No Credit needed simply enjoy.
Hit the Download section on the top.

Have fun with this one :)

Set wshShell = wscript.CreateObject("WScript.Shell")
do
wscript.sleep 100
CreateObject("SAPI.SpVoice").Speak "You don't need to see my identification... Join the Droid... "
Loop
Print This Post Print This Post
30Dec/100

Get Directory Path of an executing Batch file

Might not be needed for most of you out there that don't use Batch files but what the heck.

So I was writing this simple app that will capture all my DLL and EXE files into a batch files to register and unregister them.... Please don't ask me why (You can ask the QA team).

And one issue I found that if you run the batch file from a different folder was that is will execute the content of the batch file on the current working folder E.g batch file runs from C:\SomeFolder\ but you are in  C:\SomeOtherFolder\

So a simple addition at the beging of the batch file will return move to the correct folder.
Simply add "cd /d %~dp0" to the batch file and the execution will run on the folder.

Found this online (Some say he is wanted by the CIA, and that if he could be bothered, he could crack the Da Vinci code in 43 seconds. All we know is, he's called The Stig. I don't have The Stig's number so I use Google).
Source - Linky

Print This Post Print This Post
26Dec/100

VBScript – Using SUB’s and not the Sandwich and Functions

So, you have seen how do use some of my ideas (Well not only mine as you can find them across the WWW but this is my Blog so they are mine for this POST....)  and one of them was the WriteToLog Sub So let's talk about SUB's and Functions what we can do and use them for.

So what's the big idea? and whats the difference between a SUB and a Function?
Both the SUB and the Functions are Procedues that can be called within your script and execute some functionality without writing lines of code over and over....
There is one major difference between SUB's and Functions and it's that a Function can return a value and a SUB can only run the proceduer.
So just as an example my WriteToLog SUB is called from withing the script's and writes to a file based on arguments provided like Text, Time, File information ETC.
And as another Example that I will write about in a future date a Function that will return if  "RegistryItemExists" or "FileVersion" you catch my drift here...

A SUB (Again not the one from Subway) is a Subroutine or some might call it a procedure are basically an instance of code that you are going to use multiple times around your script but only right the main portion ounce.

So how do you start?
The Sub will Start with a Sub and a Value as well as some Arguments here is an example of a Copy SUB

Sub xCopyFile(xCopyFrom, xCopyTo)
----> Here goes the code
End Sub

So in this case I will write all my code inside the sub where xCopyFrom, xCopyTo will get values from the execution line in your code
So my execution line could look like

xCopyFile = "C:\Test.txt", "C:\Temp\Test.txt"

In this case
"C:\Test.txt" = "xCopyFrom" argument
"C:\Temp\Test.txt" = "xCopyTo" argument

And my real SUB could do some other things like verify that the destination

Now a Function
So a Function is writen in the same generic way to open and close the function


Function FileVersion(FileName)

-----> Code goes here

End Function

And in this case i'm going to get a file version for components I want to upgrade on the system and do something if needed.....
So the Code behind the function is simple as well (you do need some more code on your script...)


Function FileVersion(FileName)

FileVersion = objFSO.GetFileVersion(FileName)

End Function

So in this case from the script I will call the function in this way
MonitorFolderApp = FileVersion("C:\MonitorApp\MonitorApp.Exe")

So
MonitorFolderApp is the variable I want to assign the version to
= FileVersion calls the function
and ("what ever arguments", "Some More Arguments")  are the arguments you pass on to the Function

You might say why should I use a function just for one line of code? well you might be correct but here is an example for checking if a registry key exists as a function (I found this online somewhere, I will need to find where so I can give them some credit!)

Function xRegItemEX (xRegKey)
 On Error Resume Next

 If (Right(xRegKey, 1) = "\") Then
 objShell.RegRead xRegKey
 Select Case Err
 Case 0:
 xRegItemEX = true
 Case &h80070002:
 ErrDescription = Replace(Err.description, xRegKey, "")
 Err.clear
 objShell.RegRead "HKEY_ERROR\"
 If (ErrDescription <> Replace(Err.description, "HKEY_ERROR\", "")) Then
 xRegItemEX = true
 Else
 xRegItemEX = false
 End If
 Case Else:
 xRegItemEX = false
 End Select
 Else
 objShell.RegRead xRegKey

 Select Case Err
 Case 0:
 xRegItemEX = true
 Case Else
 xRegItemEX = false
 End Select
 End If
 On Error Goto 0
End Function
Print This Post Print This Post
12Nov/100

VBScript – Passing Arguments

So you want to pass some arguments to your VBScript either with a shortcut or command prompt...

Why do you need this at all? let's say I have some customer I want to deploy some software or do something on their system and as well all know (Or we might not... at least not me) there is no way to Compress/UnCompress (Zip'd) files via VBScript in a nice way.

Or I want to automate a procedure to upgrade and if needed do a downgrade.

So the idea here is simple, I create a VBScript that will preform an UnZip and I want to specify what file ti UnZip and where to extract it to (I know you can always use WinZip Self Extractor of some sort but this is just an example for Arguments).

So here goes, simple start of the script with some objects (if you want you can open explicits I don't think it's needed with this one)


set objShell = CreateObject("Wscript.Shell")

set objFSO = CreateObject("Scripting.FileSystemObject")

Next line is where we set to get arguments from the script


Set args = WScript.Arguments

Now i'm going to do some verification here that if no arguments are passed i'm going to show an error with a MSGBOX as you can see in the screenshot below, and when they hit OK i'll quit the script.


If Wscript.Arguments.Count = 0 Then

MsgBox ("Add some arugments this will not work without them...." &amp; vbNewLine &amp; _

"Please add MainFile and Locaion do unzip like Script.vbs C:\Temp\Temp.zip C:\Temp\")

WScript.Quit

Here is where i'm going to assign the arguments to a value, each arogument is passed as a number where the first argument is (0) and moving on.

In this case my command would be UnZip.vbs C:\Temp\Upgrade1234.zip C:\Temp\SoftwareUpgrade1234\

So

args.Item(0) = C:\Temp\Upgrade1234.zip  <-- First one

And

args.Item(1) =  C:\Temp\SoftwareUpgrade1234\ <-- Second one

I think you catch what i'm talking about...


Else

PathOfZipFile = args.Item(0)

ExtractZipTo = args.Item(1)

End If

And this is what I do to UnZip the files.... (simple but make sure that you create folders if needed ETC...)


set UnZipIt = CreateObject("Shell.Application")

set FilesInzip=UnZipIt.NameSpace(PathOfZipFile).items

UnZipIt.NameSpace(ExtractZipTo).CopyHere(FilesInzip)

So here is the whole code.... just so it's easy on the copy/paste (That you can't do on WP7... YET)


set objShell = CreateObject("Wscript.Shell")

set objFSO = CreateObject("Scripting.FileSystemObject")

Set args = WScript.Arguments

If Wscript.Arguments.Count = 0 Then

MsgBox ("Add some arugments this will not work without them...." &amp; vbNewLine &amp; _

"Please add MainFile and Locaion do unzip like Script.vbs C:\Temp\Temp.zip C:\Temp\")

WScript.Quit

Else

PathOfZipFile = args.Item(0)

ExtractZipTo = args.Item(1)

End If

set UnZipIt = CreateObject("Shell.Application")

set FilesInzip=UnZipIt.NameSpace(PathOfZipFile).items

UnZipIt.NameSpace(ExtractZipTo).CopyHere(FilesInzip)
Print This Post Print This Post
16Aug/101

VBScript – In the beginning LOGGING

So what is VBScript? I'm not going to go into the whole what and why... you can read it all on WiKiPeDiA.
Sort Story
VBScript (Visual Basic Scripting Edition) is an Active Scripting language developed by Microsoft that is modelled on Visual Basic. It is designed as a “lightweight” language with a fast interpreter for use in a wide variety of Microsoft environments. VBScript uses the Component Object Model to access elements of the environment within which it is running; for example, the FileSystemObject (FSO) is used to create, read, update and delete files.
Read more on Wiki - http://en.wikipedia.org/wiki/VBScript

So now they what we can do with it and why as there are other solutions.
What did I use VBS for?
Anything from Go-Live with user intervention to enter details for Machine name changes, IP Changes, Registry Changes, DB Changes and much more to automate Go-Live and System staging.
Automate backup and restore, tie into active solutions via MS solutions...
HTA files are a nice touch to make everything look somewhat up to date.
VBScript is a simple but sofisticated way of automating enviromentatal solutions.

But before I start with anything i'm going to recommend LOGGING!!! so add the following code to the end of your scripts and LOG away.
There are many variations but I like the following one and it does have some variations, but here is what I like about it.
1. Create a few log files with the same SUB
2. Consistency with all your log files

In this example we use one log and one line, the log write line

WriteToLog("Generic Log.vbs - Write This")

The output line in the log file will be
8/16/2010 11:26:00 PM    :    Generic Log    :    Generic Log.vbs - Write This

Full Code

'----------------------------------------------------------------------
' Filename:  Generic Log.vbs
' Copyright (c) Yeshai Bouskila 2009
' All Rights Reserved
'
' Please Enter Updates with date and name including line of Change
'----------------------------------------------------------------------
'---------------------------------------------------------------------- 

 set objShell = CreateObject("Wscript.Shell")
 set objFSO = CreateObject("Scripting.FileSystemObject")

'--- Main Begins ---------------------------------------

 WriteToLog("Generic Log.vbs - Write This")

'--- Main Ends -----------------------------------------

'--- Write to log --------------------------------------
Sub WriteToLog(strLogMessage)
 Const ForAppending = 8
 Const vbsName = "Generic Log"

 strLogFileName = "C:\GenericLog.log"
 strLogEntryTime = NOW

 'test whether file exists To either write/append to file
 if objFSO.FileExists(strLogFileName) Then
 Set objLogFileTransaction = objFSO.OpenTextFile(strLogFileName, ForAppending)
 Else
 Set objLogFileTransaction = objFSO.CreateTextFile(strLogFileName)
 End if

 objLogFileTransaction.WriteLine strLogEntryTime &amp; chr(9) &amp; chr(58) &amp; chr(9) &amp; vbsName &amp; chr(9) &amp; chr(58) &amp; chr(9) &amp; strLogMessage
 objLogFileTransaction.Close
 WScript.StdOut.WriteLine strLogMessage
 WScript.StdOut.WriteLine ""
End Sub

Now let's say I want to write in one script to a few log files but want to keep it constant.
We will change our SUB line to request another parameter from the WriteToLog line in the script

Sub WriteToLog(strLogMessage,strLogFileName)
 

As well another change to the log name in the function

strLogFileName = "C:\"& strLogFileName & ".log"

So what did we just do if our write to log like looks like this?

WriteToLog "Something for the VBScript Log","WhatAlog"

first area is our strLogMessage, second area is the log name strLogName
strLogMessage = "Something for the VBScript Log"
strLogName = "WhatAlog"

There are unlimited options here, have fun and ask away if you need.

Print This Post Print This Post