Category : Programming

Programming Windows

VBScript: Change Word Document Template

During most of my Infrastructure and Migration projects, most customers have the same issue. After migrating the file data to a new server, old documents may try to access their original document template on which they are based on.
Unfortunately, the referenced path is not a mapped network drive or a relative path – it is a UNC Path containing the old server name.

Therefore, I wrote a little script that will process all Word Documents within a given path and replace the old Server and or Share name with the new ones. After that, the launch of these old documents will be much faster.
You need write permissions to all Word Documents which should be changed and of course you need to have Microsoft Word (I used Word 2010) installed:

' #####################################################################
' ##
' ## (C) 2012 Michael Miklis (michaelmiklis.de)
' ##
' ##
' ## Filename:      ChangeWordDocumentTemplate.vbs
' ##
' ## Version:	    1.0
' ##
' ## Release:	    Final
' ##
' ## Requirements:  -none-
' ##
' ## Description:   Changes the template in doc files
' ##
' ## This script is provided 'AS-IS'.  The author does not provide
' ## any guarantee or warranty, stated or implied.  Use at your own
' ## risk. You are free to reproduce, copy & modify the code, but
' ## please give the author credit.
' ##
' ####################################################################
Option Explicit

Dim strFilePath
Dim strPath
Dim intCounter
Dim strFileName
Dim OldServer
Dim NewServer
Dim objDoc
Dim objTemplate
Dim dlgTemplate
Dim objWord
Dim strFileArr
Dim objFs
Dim i

Const wdDialogToolsTemplates = 87

Set objFS = CreateObject("Scripting.Filesystemobject")

Set objWord = CreateObject("Word.Application")
objWord.Visible = false

strFilePath = "C:Usersmichaeldesktop"
OldServer = "vv"
NewServer = "OLD-FILESERVERsharefolder1"

If Right(strFilePath, 1) = "" Then strFilePath = Left(strFilePath, Len(strFilePath) - 1)

strFileArr = Split(CreateFileList(objFS.GetFolder(strFilePath),true), vbCr)

For i=0 to UBound(strFileArr)
	If NOT strFileArr(i) = "" then
		strFileName = strFileArr(i)

		wscript.echo "--------------------------------------------------"
		wscript.echo "Processing File: " & strFilename

		Set objDoc = objWord.Documents.Open(strFileName)
		Set objTemplate = objDoc.AttachedTemplate
		Set dlgTemplate = objWord.Dialogs(wdDialogToolsTemplates)
		strPath = dlgTemplate.Template

		wscript.echo "Old Template Name: " & strPath

		'// Only process templates based on old server
		If LCase(Left(strPath, Len(OldServer))) = LCase(OldServer) Then
			wscript.echo "Template needs to be changed..."
			'objDoc.AttachedTemplate = NewServer & Mid(strPath, Len(OldServer) + 1)
			wscript.echo "New Template Name: " & NewServer & Mid(strPath, Len(OldServer) + 1)
		End If

		objDoc.Save
		objDoc.Close

		wscript.echo "--------------------------------------------------"
		wscript.echo ""
	End If
Next

Set objDoc = Nothing
Set objTemplate = Nothing
Set dlgTemplate = Nothing

'// Close Word
objWord.Quit (False)

'______________________FUNCTIONS & SUB ROUTINES_______________________

Function CreateFileList(objFolder, bRecursive)
	'//
<summary> '// Creates a List containing all Files
 '// </summary>
	'//Root-Folder for searching
	'//Search recursive
	Dim objFile, objSubFolder

        For each objFile in objFolder.Files
		If Right(lcase(objFile),4) = ".doc" OR Right(lcase(objFile),5) = ".docx" AND NOT Left(objFile.Name,1) = "~" then
	        	CreateFileList = CreateFileList & objFile.Path & vbCr
		End If
	Next

	If bRecursive = true then
		For each objSubFolder in objFolder.Subfolders
			CreateFileList = CreateFileList & CreateFileList(objSubFolder, true)
	        Next
	End If
End Function
Read More
Programming Windows

VBScript: List all installed applications

Just a simple inventory script. This script does NOT query the WMI Installed_Product table, which an be quite time and CPU consuming. Instead, my script queries the Uninstall-Registry key to generate the list of installed apps which makes it lot faster:

' #####################################################################
' ##
' ## (C) 2010 Michael Miklis (michaelmiklis.de)
' ##
' ## 
' ## Filename:      GetInstalledApplications.vbs
' ##
' ## Version:	    1.0
' ##
' ## Release:	    Final 
' ##
' ## Requirements:  -none-
' ## 
' ## Description:   List installed applications based on uninstall key
' ##
' ## This script is provided 'AS-IS'.  The author does not provide 
' ## any guarantee or warranty, stated or implied.  Use at your own 
' ## risk. You are free to reproduce, copy &amp; modify the code, but 
' ## please give the author credit. 
' ##
' ####################################################################
Option Explicit


wscript.echo GetInstalledApplications


'______________________FUNCTIONS &amp; SUB ROUTINES_______________________

Function GetInstalledApplications
	'// &lt;summary&gt; 
	'// List installed applications
	'// &lt;/summary&gt;
	'// &lt;param name=&quot;strComputername&quot;&gt;Computername&lt;/param&gt;
 
	Const HKLM = &amp;H80000002		'HKEY_LOCAL_MACHINE

	Dim objREG			'Registry Object
	Dim strBaseKey			'Uninstall Key
	Dim intRet			'Return Code
	Dim arSubKeys			'Reg-Key Array
	Dim strKey			'Reg-Key Element
	Dim strValue			'Reg-Value

	Set objREG = GetObject(&quot;winmgmts:{impersonationLevel=impersonate}!./root/default:StdRegProv&quot;)
	strBaseKey = &quot;SOFTWAREMicrosoftWindowsCurrentVersionUninstall&quot;

	intRet = objREG.EnumKey(HKLM, strBaseKey, arSubKeys)

	For Each strKey In arSubKeys
		intRet = objREG.GetStringValue(HKLM, strBaseKey &amp; strKey, &quot;DisplayName&quot;, strValue)

		If intRet &lt;&gt; 0 Then
			objREG.GetStringValue HKLM, strBaseKey &amp; strKey, &quot;QuietDisplayName&quot;, strValue
		End If

		If strValue &lt;&gt; &quot;&quot; Then
			GetInstalledApplications = GetInstalledApplications &amp; strValue &amp; vbCrLf
		End If
	Next
End Function
Read More
Programming Windows

VBScript: List all files in a directory recursively

This is definitely my most used VBScript function ever. Just specify a directory a you’ll receive a complete directory listing recursively.

' #####################################################################
' ##
' ## (C) 2005 Michael Miklis (michaelmiklis.de)
' ##
' ## 
' ## Filename:      ListFilesRecursive.vbs
' ##
' ## Version:	    1.0
' ##
' ## Release:	    Final 
' ##
' ## Requirements:  -none-
' ## 
' ## Description:   Creates a List of files and folders
' ##
' ## This script is provided 'AS-IS'.  The author does not provide 
' ## any guarantee or warranty, stated or implied.  Use at your own 
' ## risk. You are free to reproduce, copy & modify the code, but 
' ## please give the author credit. 
' ##
' ####################################################################
Option Explicit

Dim objFS

Set objFS = CreateObject ("Scripting.FileSystemObject")

wscript.echo CreateFileList(objFS.GetFolder("C:\Users\michael\desktop"), True)

Set objFS = Nothing

'______________________FUNCTIONS & SUB ROUTINES_______________________

Function CreateFileList(objFolder, bRecursive)
	'// <summary> 
	'// 	Creates a List containing all Files
	'// </summary> 
	'// <param name="objFolder">Root-Folder for searching</param> 	
	'// <param name="bRecursive">Search recursive</param>
	Dim objFile, objSubFolder

        For each objFile in objFolder.Files
        	CreateFileList = CreateFileList & objFile.Path & vbCr
	Next

	If bRecursive = true then
		For each objSubFolder in objFolder.Subfolders
			CreateFileList = CreateFileList & CreateFileList(objSubFolder, true)
	        Next
	End If
End Function
Read More
Programming Windows

VBScript: Ping Function

Just another useful function using the Windows Management Infractstructre (WMI) for doing a ICMP Ping. I’ve used this function on all my network related scripts to verify a host is available on the network.

' #####################################################################
' ##
' ## (C) 2009 Michael Miklis (michaelmiklis.de)
' ##
' ## 
' ## Filename:      Ping.vbs
' ##
' ## Version:	    1.0
' ##
' ## Release:	    Final 
' ##
' ## Requirements:  -none-
' ## 
' ## Description:   Pings a network host or device
' ##
' ## This script is provided 'AS-IS'.  The author does not provide 
' ## any guarantee or warranty, stated or implied.  Use at your own 
' ## risk. You are free to reproduce, copy & modify the code, but 
' ## please give the author credit. 
' ##
' ####################################################################
Option Explicit

If Ping("www.google.com") = true then
	wscript.echo "alive"
End If

'______________________FUNCTIONS & SUB ROUTINES_______________________

Function Ping(strHost)
	'// <summary> 
	'// Well Known Ping command
	'// </summary>
	'// <param name="strHost">Name or IP-Address</param>


	Dim objPing			'WMI Ping Object
	Dim objStatus			'PingStatus Object

	Ping = false

	Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}")._
	ExecQuery("SELECT * FROM Win32_PingStatus where address = '" & strHost & "'")

	'// Query Win32_PingStatus.StatusCode -> 0 = reachable
	For each objStatus in objPing
		If objStatus.StatusCode = 0 then
			Ping = true
			Exit Function
		End If
	Next
End Function
Read More
Featured Programming

Creating VMware Virtual Machines using PowerCLI

During one of my current projects, I needed to create lots of virtual machines on a VMware vSphere 5 environment. These virtual machines were used as Citrix XenApp Worker servers provisioned by Citrix Provisioning Services (PVS). Therefore, we additionally needed to configure a static MAC address on each virtual machine.

For faster deployment and better documentation, I decided to do the word with the VMware Powershell interface called PowerCLI:

http://www.vmware.com/go/powercli


# --------------------------------------------------
# Connect to vCenter Server
# --------------------------------------------------
connect-viserver –server "myVCenter.domain.local"

# --------------------------------------------------
# Create new VMs from Template
# --------------------------------------------------
New-VM -Name NewVM01 -Template W2K8R2_Datacenter_ENU -Datastore "SAN-Datastore-01" -VMHost "esx01.domain.local"
New-VM -Name NewVM02 -Template W2K8R2_Datacenter_ENU -Datastore "SAN-Datastore-01" -VMHost "esx02.domain.local"

# --------------------------------------------------
# Setting DRS Rules to separate NewVM01 and NEWVM02
# --------------------------------------------------
New-DrsRule -Name "Never on the same Host" -Cluster "Production" -Enabled $true -KeepTogether $false -VM "NewVM01", "NewVM02"

# --------------------------------------------------
# Setting static MAC Addresses
# --------------------------------------------------
Get-VM "NewVM01" | Get-NetworkAdapter | Set-NetworkAdapter -MacAddress "00:50:56:1A:00:01" -Confirm:$false
Get-VM "NewVM02" | Get-NetworkAdapter | Set-NetworkAdapter -MacAddress "00:50:56:1A:00:02" -Confirm:$false

Read More
Programming Windows

Changing a Template or Templatepath in Word Documents via Script

During a fileserver migration I encountered a problem – users started to report that it takes unusually long to open Microsoft Word Documents. I did some investigations on this and found out that Word is saving the FQDN of the template path (*.dot) file. You can see this if you open a document in the Word splash screen.

You can manually change the template path within the document options in word – but what if you have thousands of files and you even don’t know which one are affected?

Here’s the answer: I just wrote a little script that will modify all documents within the given path.

You just need to modify the lines 45, 46, 47 to fit your environment

' #####################################################################
' ##
' ## (C) 2012 Michael Miklis (michaelmiklis.de)
' ##
' ## 
' ## Filename:      ChangeWordDocumentTemplate.vbs
' ##
' ## Version:	    1.0
' ##
' ## Release:	    Final 
' ##
' ## Requirements:  -none-
' ## 
' ## Description:   Changes the template in doc files
' ##
' ## This script is provided 'AS-IS'.  The author does not provide 
' ## any guarantee or warranty, stated or implied.  Use at your own 
' ## risk. You are free to reproduce, copy & modify the code, but 
' ## please give the author credit. 
' ##
' ####################################################################
Option Explicit

Dim strFilePath
Dim strPath
Dim intCounter
Dim strFileName
Dim OldServer
Dim NewServer
Dim objDoc
Dim objTemplate
Dim dlgTemplate
Dim objWord
Dim strFileArr
Dim objFs
Dim i

Const wdDialogToolsTemplates = 87

Set objFS = CreateObject("Scripting.Filesystemobject")

Set objWord = CreateObject("Word.Application")
objWord.Visible = false

strFilePath = "C:\Testfiles"
OldServer = "\\server_old\share\folder1\folder1.1" 
NewServer = "\\server_new\share\folder1\folder1.1"


If Right(strFilePath, 1) = "\" Then strFilePath = Left(strFilePath, Len(strFilePath) - 1)

strFileArr = Split(CreateFileList(objFS.GetFolder(strFilePath),true), vbCr)

For i=0 to UBound(strFileArr)
	If NOT strFileArr(i) = "" then
		strFileName = strFileArr(i)

		wscript.echo "--------------------------------------------------"
		wscript.echo "Processing File: " & strFilename

		Set objDoc = objWord.Documents.Open(strFileName)    
		Set objTemplate = objDoc.AttachedTemplate    
		Set dlgTemplate = objWord.Dialogs(wdDialogToolsTemplates)    
		strPath = dlgTemplate.Template

		wscript.echo "Old Template Name: " & strPath

		'// Only process templates based on old server
		If LCase(Left(strPath, Len(OldServer))) = LCase(OldServer) Then
			wscript.echo "Template needs to be changed..."    
			objDoc.AttachedTemplate = NewServer & Mid(strPath, Len(OldServer) + 1)
			wscript.echo "New Template Name: " & NewServer & Mid(strPath, Len(OldServer) + 1)
		End If    

		objDoc.Save                  
		objDoc.Close

		wscript.echo "--------------------------------------------------"
		wscript.echo ""
	End If
Next 

Set objDoc = Nothing
Set objTemplate = Nothing
Set dlgTemplate = Nothing  

'// Close Word
objWord.Quit (False)

'______________________FUNCTIONS & SUB ROUTINES_______________________

Function CreateFileList(objFolder, bRecursive)
	'// <summary> 
	'// 	Creates a List containing all Files
	'// </summary> 
	'// <param name="objFolder">Root-Folder for searching</param> 	
	'// <param name="bRecursive">Search recursive</param>
	Dim objFile, objSubFolder


        For each objFile in objFolder.Files
		If Right(lcase(objFile),4) = ".doc" OR Right(lcase(objFile),5) = ".docx" AND NOT Left(objFile.Name,1) = "~" then
	        	CreateFileList = CreateFileList & objFile.Path & vbCr
		End If
	Next

	If bRecursive = true then
		For each objSubFolder in objFolder.Subfolders
			CreateFileList = CreateFileList & CreateFileList(objSubFolder, true)
	        Next
	End If
End Function

Read More
Featured Programming

VBScript: Include Function

Another interesting VBScript Function I created in the past for larger scripting projects. This will give you the ability to “outsource” code from your main script file. This function is known and built into other languages such as C++, .NET, PHP, etc. for years.

PHP-Include Reference: http://php.net/manual/de/function.include.php
(functionality is pretty much the same in my VBScript function)

' #####################################################################
' ##
' ## (C) 2011 Michael Miklis (michaelmiklis.de)
' ##
' ## 
' ## Filename:      Include.vbs
' ##
' ## Version:	    1.0
' ##
' ## Release:	    Final 
' ##
' ## Requirements:  -none-
' ## 
' ## Description:   Include function for external Code-Files
' ##
' ## This script is provided 'AS-IS'.  The author does not provide 
' ## any guarantee or warranty, stated or implied.  Use at your own 
' ## risk. You are free to reproduce, copy &amp; modify the code, but 
' ## please give the author credit. 
' ##
' ####################################################################
Option Explicit

Include(&quot;C:code.inc.vbs&quot;)

'______________________FUNCTIONS &amp; SUB ROUTINES_______________________

Sub Include(strFilename)
	'// &lt;summary&gt; 
	'// Include function for C-Style include from
	'// external script files
	'// &lt;/summary&gt;
	'// &lt;param name=&quot;strFilename&quot;&gt;external code file&lt;/param&gt; 
	Dim objFSO, objHANDLE


	Set objFSO = CreateObject(&quot;Scripting.FileSystemObject&quot;)
	Set objHANDLE = objFSO.OpenTextFile(strFilename)

	ExecuteGlobal objHANDLE.ReadAll
	objHANDLE.Close()

	Set objHANDLE = Nothing
	Set objFSO = Nothing
End Sub


Read More
1 2