Board index » Visual Studio » Please Help Optimize This Code

Please Help Optimize This Code

Visual Studio146
Hello,



I have a script that reads a text file into memory and modifies the IIS

metabase for the sites listed in the text file and updates the UNCPath key

for those site's virtual directories. I have written this code myself, but

I am no programmer. I have a feeling that there is a better way to loop

through the metabase than the way I am doing it. It does work currently,

but I would rather have the code optimized since I will be using it quite a

bit moving forward. Can someone please take a look and see if there is a

better way to do this?



Dim arrSiteList()



Set WshNetwork = CreateObject("WScript.Network")

ComputerName = WshNetwork.ComputerName



Const ForReading = 1



'make FileSystemObject call

Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objTextFile = objFSO.OpenTextFile ("c:\temp\sites.txt", ForReading)



'read in the number of lines in the text file

j = 0

Do Until objTextFile.AtEndOfStream

objTextFile.Readline

j = j + 1

Loop



'reset the FileSystemObject call

Set objFSO = Nothing

Set objTextFile = Nothing



'resize my array to the number of lines in the text file

'0 based indexing so there's really 1 less than j

ReDim arrSiteList(j-1)



'call a new FileSystemObject

Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objTextFile = objFSO.OpenTextFile ("c:\temp\sites.txt", ForReading)



'populate newly sized array

i = 0

Do Until objTextFile.AtEndOfStream

arrSiteList(i) = objTextFile.Readline

wscript.echo arrSiteList(i)

i = i + 1

Loop



Count = 0

Path = "\\Server\Share\"

SitePoint = ComputerName & "/W3SVC"

Set Parent = GetObject("IIS://" & SitePoint)

For Each Child In Parent

For Each Child2 In Child

For Each Child3 In Child2

strPath = Path & Child3.Name

for i = 0 to ubound(arrSiteList)

'if Child3.Name is in the array of Sites then execute the following code

if arrSiteList(i) = Child3.Name Then

'Set fso = CreateObject ("Scripting.FileSystemObject")

If Not objFSO.FolderExists(Child3.Name) Then

objFSO.CreateFolder(Child3.Name)

End If

Select Case Child3.Name

'just skip over these

Case "localstart.asp"

Case "Printers"

Case "IISHelp"

Case "iisadmin"

Case "$D"

Case "D"

Case Else

For Each Child4 In Child3

If Child4.Name = "REPORTOUTPUT" Then

SitePoint = ComputerName & "/W3SVC/" &

Child.Name _

& "/" & Child2.Name

_

& "/" & Child3.Name

_

& "/" & Child4.Name

Count = Count + 1

ModifyUNCPath SitePoint, strPath

End If

Next

End Select

End If

Next

Next

Next

Next



''''''''''''''''''''''''''

'

' ModifyUNCUsername

'

' Modifies the UNCUsername Key Under the Virtual Directories in the

Metabase.

'

''''''''''''''''''''''''''

Sub ModifyUNCPath(SitePoint, strPath)

' MsgBox ("SitePoint " & SitePoint)

On Error Resume Next

Set Site = GetObject("IIS://" & SitePoint)

On Error GoTo 0

WScript.Echo Space(Level*2 + 1) & "Changing Site #" & Count & " - " &

SitePoint

Site.Path = strPath

Site.SetInfo

End Sub





Thanks,

Robbie


-
 

Re:Please Help Optimize This Code

Hi,



First, there is no need to recreate the FSO object. You only need the first

"Set objFSO". Next, I would close the file before reopening it. I cannot

find a method to return to the beginning, except to use OpenTextFile again.

For example



objTextFile.Close

Set objTextFile = objFSO.OpenTextFile("c:\temp\sites.txt", ForReading)



A minor point, is that I would account for the possiblity that some lines in

the text file could be blank. In particular, if the file ends with a

carriage return, it can have a blank last line. I would use:



j = 0

Do Until objTextFile.AtEndOfStream

strLine = Trim(objTextFile.ReadLine)

If strLine <>"" Then

j = j + 1

End If

Loop



...



i = 0

Do Until objTextFile.AtEndOfStream

strLine = Trim(objTextFile.ReadLine)

If strLine <>"" Then

arrSiteList(i) = strLine

i = i + 1

Wscript.Echo arrSiteList(i)

End If

Loop



Next, the big question is which is slower - Reading the text file twice, or

ReDim'ing the array repeatedly in the first loop. When I test, both methods

are so fast that I cannot tell. Maybe someone else knows. Still, my first

inclination would be to read the file once and ReDim in the loop, as

follows:



j = 0

Do Until objTextFile.AtEndOfStream

strLine = Trim(objTextFile.ReadLine)

If strLine <>"" Then

ReDim Preserve arrSiteList(j)

arrSiteList(j) = strLine

Wscript.Echo arrSiteList(j)

j = j + 1

End If

Loop



Then, a final idea would be to use a dictionary object instead of a dynamic

array. If I understand your code, the purpose of arrSiteList is to check

each Child3.Name to see if it is in the list. The dictionary object has an

Exists method, so you don't have to loop through the entire array to test if

the name is in the list. For example, I would try:



Set objSiteList = CreateObject("Scripting.Dictionary")

objSiteList.CompareMode = vbTextCompare



Do Until objTextFile.AtEndOfStream

strLine = Trim(objTextFile.ReadLine)

If strLine <>"" Then

objSiteList(strLine) = True

End If

Loop



Then, in place of:



strPath = Path & Child3.Name

For i = 0 To UBound(arrSiteList)

If arrSiteList(i) = Child3.Name Then

...



I would use:



strPath = Path & Child3.Name

If objSiteList(Child3.Name).Exists Then

...



This way, the file is read only once, the dictionary object is populated,

and you never have to loop through all entries in this object. That should

be the fastest.



--

Richard

Microsoft MVP Scripting and ADSI

HilltopLab web site - www.rlmueller.net">www.rlmueller.net

--



"Robert Elliott" <relliott@procard.com>wrote in message

Quote
Hello,



I have a script that reads a text file into memory and modifies the IIS

metabase for the sites listed in the text file and updates the UNCPath key

for those site's virtual directories. I have written this code myself,

but

I am no programmer. I have a feeling that there is a better way to loop

through the metabase than the way I am doing it. It does work currently,

but I would rather have the code optimized since I will be using it quite

a

bit moving forward. Can someone please take a look and see if there is a

better way to do this?



Dim arrSiteList()



Set WshNetwork = CreateObject("WScript.Network")

ComputerName = WshNetwork.ComputerName



Const ForReading = 1



'make FileSystemObject call

Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objTextFile = objFSO.OpenTextFile ("c:\temp\sites.txt", ForReading)



'read in the number of lines in the text file

j = 0

Do Until objTextFile.AtEndOfStream

objTextFile.Readline

j = j + 1

Loop



'reset the FileSystemObject call

Set objFSO = Nothing

Set objTextFile = Nothing



'resize my array to the number of lines in the text file

'0 based indexing so there's really 1 less than j

ReDim arrSiteList(j-1)



'call a new FileSystemObject

Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objTextFile = objFSO.OpenTextFile ("c:\temp\sites.txt", ForReading)



'populate newly sized array

i = 0

Do Until objTextFile.AtEndOfStream

arrSiteList(i) = objTextFile.Readline

wscript.echo arrSiteList(i)

i = i + 1

Loop



Count = 0

Path = "\\Server\Share\"

SitePoint = ComputerName & "/W3SVC"

Set Parent = GetObject("IIS://" & SitePoint)

For Each Child In Parent

For Each Child2 In Child

For Each Child3 In Child2

strPath = Path & Child3.Name

for i = 0 to ubound(arrSiteList)

'if Child3.Name is in the array of Sites then execute the following

code

if arrSiteList(i) = Child3.Name Then

'Set fso = CreateObject ("Scripting.FileSystemObject")

If Not objFSO.FolderExists(Child3.Name) Then

objFSO.CreateFolder(Child3.Name)

End If

Select Case Child3.Name

'just skip over these

Case "localstart.asp"

Case "Printers"

Case "IISHelp"

Case "iisadmin"

Case "$D"

Case "D"

Case Else

For Each Child4 In Child3

If Child4.Name = "REPORTOUTPUT" Then

SitePoint = ComputerName & "/W3SVC/" &

Child.Name _

& "/" &

Child2.Name

_

& "/" &

Child3.Name

_

& "/" &

Child4.Name

Count = Count + 1

ModifyUNCPath SitePoint, strPath

End If

Next

End Select

End If

Next

Next

Next

Next



''''''''''''''''''''''''''

'

' ModifyUNCUsername

'

' Modifies the UNCUsername Key Under the Virtual Directories in the

Metabase.

'

''''''''''''''''''''''''''

Sub ModifyUNCPath(SitePoint, strPath)

' MsgBox ("SitePoint " & SitePoint)

On Error Resume Next

Set Site = GetObject("IIS://" & SitePoint)

On Error GoTo 0

WScript.Echo Space(Level*2 + 1) & "Changing Site #" & Count & " - " &

SitePoint

Site.Path = strPath

Site.SetInfo

End Sub





Thanks,

Robbie









-

Re:Please Help Optimize This Code

Richard,



Thanks for the input. I had a feeling there were a number of things that I

didn't have optimized. I appreciate your input. I will change the areas

you mentioned.



Richard, do you know how to recurse through the IIS metabase? I have one

site with 350 virtual directories. Each virtual directory has another

virtual directory which contains a UNCPath that I need to update only for

certain sites (that I read in from the text file). Currently I am doing the

for each loops for each level of the heirarchy. I have a script that a

friend helped me with that recurses a folder structure, but I am not sure

how to make that logic work with the metabase. Below is the script that

recurses subfolders.



I guess my real question is what would I pass into my sub for path if it is

the metabase? Can this even be done? What would you do?





Dim fso, oFile, oFolder

Set fso = CreateObject("Scripting.FileSystemObject")

strPath = InputBox ("Enter Folder To Process.")

Set oRootFolder = fso.GetFolder(strPath)



If fso.FolderExists(oRootFolder) Then

ProcessFiles(oRootFolder)

End If



''''''''''''''''''''''''''''''''''''''''''''''

'Pass the path into the function

'Recurse sub folders and process files in all subfolders

'

''''''''''''''''''''''''''''''''''''''''''''''



Sub ProcessFiles (oPath)

'MsgBox "oPath is " & oPath

For Each oFile In oPath.Files

If Right(oFile.Name, 3) = "dll" Then

WScript.Echo oFile.Path & vbTab & " (" &

fso.GetFileVersion(oFile.Path) & ")"

End If

Next



For Each oFolder In oPath.SubFolders

'MsgBox "oFolder is " & oFolder

ProcessFiles (oFolder)

Next



End Sub









"Richard Mueller [MVP]" <rlmueller-nospam@ameritech.net>wrote in message

Quote
Hi,



First, there is no need to recreate the FSO object. You only need the

first

"Set objFSO". Next, I would close the file before reopening it. I cannot

find a method to return to the beginning, except to use OpenTextFile

again.

For example



objTextFile.Close

Set objTextFile = objFSO.OpenTextFile("c:\temp\sites.txt", ForReading)



A minor point, is that I would account for the possiblity that some lines

in

the text file could be blank. In particular, if the file ends with a

carriage return, it can have a blank last line. I would use:



j = 0

Do Until objTextFile.AtEndOfStream

strLine = Trim(objTextFile.ReadLine)

If strLine <>"" Then

j = j + 1

End If

Loop



...



i = 0

Do Until objTextFile.AtEndOfStream

strLine = Trim(objTextFile.ReadLine)

If strLine <>"" Then

arrSiteList(i) = strLine

i = i + 1

Wscript.Echo arrSiteList(i)

End If

Loop



Next, the big question is which is slower - Reading the text file twice,

or

ReDim'ing the array repeatedly in the first loop. When I test, both

methods

are so fast that I cannot tell. Maybe someone else knows. Still, my first

inclination would be to read the file once and ReDim in the loop, as

follows:



j = 0

Do Until objTextFile.AtEndOfStream

strLine = Trim(objTextFile.ReadLine)

If strLine <>"" Then

ReDim Preserve arrSiteList(j)

arrSiteList(j) = strLine

Wscript.Echo arrSiteList(j)

j = j + 1

End If

Loop



Then, a final idea would be to use a dictionary object instead of a

dynamic

array. If I understand your code, the purpose of arrSiteList is to check

each Child3.Name to see if it is in the list. The dictionary object has an

Exists method, so you don't have to loop through the entire array to test

if

the name is in the list. For example, I would try:



Set objSiteList = CreateObject("Scripting.Dictionary")

objSiteList.CompareMode = vbTextCompare



Do Until objTextFile.AtEndOfStream

strLine = Trim(objTextFile.ReadLine)

If strLine <>"" Then

objSiteList(strLine) = True

End If

Loop



Then, in place of:



strPath = Path & Child3.Name

For i = 0 To UBound(arrSiteList)

If arrSiteList(i) = Child3.Name Then

...



I would use:



strPath = Path & Child3.Name

If objSiteList(Child3.Name).Exists Then

...



This way, the file is read only once, the dictionary object is populated,

and you never have to loop through all entries in this object. That should

be the fastest.



--

Richard

Microsoft MVP Scripting and ADSI

HilltopLab web site - www.rlmueller.net">www.rlmueller.net

--



"Robert Elliott" <relliott@procard.com>wrote in message

news:%23iVIrV$wDHA.2556@TK2MSFTNGP10.phx.gbl...

>Hello,

>

>I have a script that reads a text file into memory and modifies the IIS

>metabase for the sites listed in the text file and updates the UNCPath

key

>for those site's virtual directories. I have written this code myself,

but

>I am no programmer. I have a feeling that there is a better way to loop

>through the metabase than the way I am doing it. It does work

currently,

>but I would rather have the code optimized since I will be using it

quite

a

>bit moving forward. Can someone please take a look and see if there is

a

>better way to do this?

>

>Dim arrSiteList()

>

>Set WshNetwork = CreateObject("WScript.Network")

>ComputerName = WshNetwork.ComputerName

>

>Const ForReading = 1

>

>'make FileSystemObject call

>Set objFSO = CreateObject("Scripting.FileSystemObject")

>Set objTextFile = objFSO.OpenTextFile ("c:\temp\sites.txt", ForReading)

>

>'read in the number of lines in the text file

>j = 0

>Do Until objTextFile.AtEndOfStream

>objTextFile.Readline

>j = j + 1

>Loop

>

>'reset the FileSystemObject call

>Set objFSO = Nothing

>Set objTextFile = Nothing

>

>'resize my array to the number of lines in the text file

>'0 based indexing so there's really 1 less than j

>ReDim arrSiteList(j-1)

>

>'call a new FileSystemObject

>Set objFSO = CreateObject("Scripting.FileSystemObject")

>Set objTextFile = objFSO.OpenTextFile ("c:\temp\sites.txt", ForReading)

>

>'populate newly sized array

>i = 0

>Do Until objTextFile.AtEndOfStream

>arrSiteList(i) = objTextFile.Readline

>wscript.echo arrSiteList(i)

>i = i + 1

>Loop

>

>Count = 0

>Path = "\\Server\Share\"

>SitePoint = ComputerName & "/W3SVC"

>Set Parent = GetObject("IIS://" & SitePoint)

>For Each Child In Parent

>For Each Child2 In Child

>For Each Child3 In Child2

>strPath = Path & Child3.Name

>for i = 0 to ubound(arrSiteList)

>'if Child3.Name is in the array of Sites then execute the following

code

>if arrSiteList(i) = Child3.Name Then

>'Set fso = CreateObject ("Scripting.FileSystemObject")

>If Not objFSO.FolderExists(Child3.Name) Then

>objFSO.CreateFolder(Child3.Name)

>End If

>Select Case Child3.Name

>'just skip over these

>Case "localstart.asp"

>Case "Printers"

>Case "IISHelp"

>Case "iisadmin"

>Case "$D"

>Case "D"

>Case Else

>For Each Child4 In Child3

>If Child4.Name = "REPORTOUTPUT" Then

>SitePoint = ComputerName & "/W3SVC/" &

>Child.Name _

>& "/" &

Child2.Name

>_

>& "/" &

Child3.Name

>_

>& "/" &

Child4.Name

>Count = Count + 1

>ModifyUNCPath SitePoint, strPath

>End If

>Next

>End Select

>End If

>Next

>Next

>Next

>Next

>

>''''''''''''''''''''''''''

>'

>' ModifyUNCUsername

>'

>' Modifies the UNCUsername Key Under the Virtual Directories in the

>Metabase.

>'

>''''''''''''''''''''''''''

>Sub ModifyUNCPath(SitePoint, strPath)

>' MsgBox ("SitePoint " & SitePoint)

>On Error Resume Next

>Set Site = GetObject("IIS://" & SitePoint)

>On Error GoTo 0

>WScript.Echo Space(Level*2 + 1) & "Changing Site #" & Count & " - "

&

>SitePoint

>Site.Path = strPath

>Site.SetInfo

>End Sub

>

>

>Thanks,

>Robbie

>

>









-

Re:Please Help Optimize This Code

I'm not familiar with the IIS metabase, but a recursive subroutine seems the

way to go. The following enumerates the entire structure.



Dim objParent = GetObject("IIS://MyServer/W3SVC")

Wscript.Echo objParent.Name

Call EnumIIS(objParent, "--")



Sub EnumIIS(objParent, strOffset)

Dim objChild

For Each objChild In objParent

Wscript.Echo strOffset & objChild.Name

Call EnumIIS(objChild, strOffset & "--")

Next

End Sub



--

Richard

Microsoft MVP Scripting and ADSI

HilltopLab web site - www.rlmueller.net">www.rlmueller.net

--

"Robert Elliott" <relliott@procard.com>wrote in message

Quote
Richard,



Thanks for the input. I had a feeling there were a number of things that

I

didn't have optimized. I appreciate your input. I will change the areas

you mentioned.



Richard, do you know how to recurse through the IIS metabase? I have one

site with 350 virtual directories. Each virtual directory has another

virtual directory which contains a UNCPath that I need to update only for

certain sites (that I read in from the text file). Currently I am doing

the

for each loops for each level of the heirarchy. I have a script that a

friend helped me with that recurses a folder structure, but I am not sure

how to make that logic work with the metabase. Below is the script that

recurses subfolders.



I guess my real question is what would I pass into my sub for path if it

is

the metabase? Can this even be done? What would you do?





Dim fso, oFile, oFolder

Set fso = CreateObject("Scripting.FileSystemObject")

strPath = InputBox ("Enter Folder To Process.")

Set oRootFolder = fso.GetFolder(strPath)



If fso.FolderExists(oRootFolder) Then

ProcessFiles(oRootFolder)

End If



''''''''''''''''''''''''''''''''''''''''''''''

'Pass the path into the function

'Recurse sub folders and process files in all subfolders

'

''''''''''''''''''''''''''''''''''''''''''''''



Sub ProcessFiles (oPath)

'MsgBox "oPath is " & oPath

For Each oFile In oPath.Files

If Right(oFile.Name, 3) = "dll" Then

WScript.Echo oFile.Path & vbTab & " (" &

fso.GetFileVersion(oFile.Path) & ")"

End If

Next



For Each oFolder In oPath.SubFolders

'MsgBox "oFolder is " & oFolder

ProcessFiles (oFolder)

Next



End Sub









"Richard Mueller [MVP]" <rlmueller-nospam@ameritech.net>wrote in message

news:ezCmGRAxDHA.1576@TK2MSFTNGP11.phx.gbl...

>Hi,

>

>First, there is no need to recreate the FSO object. You only need the

first

>"Set objFSO". Next, I would close the file before reopening it. I cannot

>find a method to return to the beginning, except to use OpenTextFile

again.

>For example

>

>objTextFile.Close

>Set objTextFile = objFSO.OpenTextFile("c:\temp\sites.txt", ForReading)

>

>A minor point, is that I would account for the possiblity that some

lines

in

>the text file could be blank. In particular, if the file ends with a

>carriage return, it can have a blank last line. I would use:

>

>j = 0

>Do Until objTextFile.AtEndOfStream

>strLine = Trim(objTextFile.ReadLine)

>If strLine <>"" Then

>j = j + 1

>End If

>Loop

>

>...

>

>i = 0

>Do Until objTextFile.AtEndOfStream

>strLine = Trim(objTextFile.ReadLine)

>If strLine <>"" Then

>arrSiteList(i) = strLine

>i = i + 1

>Wscript.Echo arrSiteList(i)

>End If

>Loop

>

>Next, the big question is which is slower - Reading the text file twice,

or

>ReDim'ing the array repeatedly in the first loop. When I test, both

methods

>are so fast that I cannot tell. Maybe someone else knows. Still, my

first

>inclination would be to read the file once and ReDim in the loop, as

>follows:

>

>j = 0

>Do Until objTextFile.AtEndOfStream

>strLine = Trim(objTextFile.ReadLine)

>If strLine <>"" Then

>ReDim Preserve arrSiteList(j)

>arrSiteList(j) = strLine

>Wscript.Echo arrSiteList(j)

>j = j + 1

>End If

>Loop

>

>Then, a final idea would be to use a dictionary object instead of a

dynamic

>array. If I understand your code, the purpose of arrSiteList is to check

>each Child3.Name to see if it is in the list. The dictionary object has

an

>Exists method, so you don't have to loop through the entire array to

test

if

>the name is in the list. For example, I would try:

>

>Set objSiteList = CreateObject("Scripting.Dictionary")

>objSiteList.CompareMode = vbTextCompare

>

>Do Until objTextFile.AtEndOfStream

>strLine = Trim(objTextFile.ReadLine)

>If strLine <>"" Then

>objSiteList(strLine) = True

>End If

>Loop

>

>Then, in place of:

>

>strPath = Path & Child3.Name

>For i = 0 To UBound(arrSiteList)

>If arrSiteList(i) = Child3.Name Then

>...

>

>I would use:

>

>strPath = Path & Child3.Name

>If objSiteList(Child3.Name).Exists Then

>...

>

>This way, the file is read only once, the dictionary object is

populated,

>and you never have to loop through all entries in this object. That

should

>be the fastest.

>

>--

>Richard

>Microsoft MVP Scripting and ADSI

>HilltopLab web site - www.rlmueller.net">www.rlmueller.net

>--

>

>"Robert Elliott" <relliott@procard.com>wrote in message

>news:%23iVIrV$wDHA.2556@TK2MSFTNGP10.phx.gbl...

>>Hello,

>>

>>I have a script that reads a text file into memory and modifies the

IIS

>>metabase for the sites listed in the text file and updates the UNCPath

key

>>for those site's virtual directories. I have written this code

myself,

>but

>>I am no programmer. I have a feeling that there is a better way to

loop

>>through the metabase than the way I am doing it. It does work

currently,

>>but I would rather have the code optimized since I will be using it

quite

>a

>>bit moving forward. Can someone please take a look and see if there

is

a

>>better way to do this?

>>

>>Dim arrSiteList()

>>

>>Set WshNetwork = CreateObject("WScript.Network")

>>ComputerName = WshNetwork.ComputerName

>>

>>Const ForReading = 1

>>

>>'make FileSystemObject call

>>Set objFSO = CreateObject("Scripting.FileSystemObject")

>>Set objTextFile = objFSO.OpenTextFile ("c:\temp\sites.txt",

ForReading)

>>

>>'read in the number of lines in the text file

>>j = 0

>>Do Until objTextFile.AtEndOfStream

>>objTextFile.Readline

>>j = j + 1

>>Loop

>>

>>'reset the FileSystemObject call

>>Set objFSO = Nothing

>>Set objTextFile = Nothing

>>

>>'resize my array to the number of lines in the text file

>>'0 based indexing so there's really 1 less than j

>>ReDim arrSiteList(j-1)

>>

>>'call a new FileSystemObject

>>Set objFSO = CreateObject("Scripting.FileSystemObject")

>>Set objTextFile = objFSO.OpenTextFile ("c:\temp\sites.txt",

ForReading)

>>

>>'populate newly sized array

>>i = 0

>>Do Until objTextFile.AtEndOfStream

>>arrSiteList(i) = objTextFile.Readline

>>wscript.echo arrSiteList(i)

>>i = i + 1

>>Loop

>>

>>Count = 0

>>Path = "\\Server\Share\"

>>SitePoint = ComputerName & "/W3SVC"

>>Set Parent = GetObject("IIS://" & SitePoint)

>>For Each Child In Parent

>>For Each Child2 In Child

>>For Each Child3 In Child2

>>strPath = Path & Child3.Name

>>for i = 0 to ubound(arrSiteList)

>>'if Child3.Name is in the array of Sites then execute the

following

>code

>>if arrSiteList(i) = Child3.Name Then

>>'Set fso = CreateObject ("Scripting.FileSystemObject")

>>If Not objFSO.FolderExists(Child3.Name) Then

>>objFSO.CreateFolder(Child3.Name)

>>End If

>>Select Case Child3.Name

>>'just skip over these

>>Case "localstart.asp"

>>Case "Printers"

>>Case "IISHelp"

>>Case "iisadmin"

>>Case "$D"

>>Case "D"

>>Case Else

>>For Each Child4 In Child3

>>If Child4.Name = "REPORTOUTPUT" Then

>>SitePoint = ComputerName & "/W3SVC/" &

>>Child.Name _

>>& "/" &

>Child2.Name

>>_

>>& "/" &

>Child3.Name

>>_

>>& "/" &

>Child4.Name

>>Count = Count + 1

>>ModifyUNCPath SitePoint, strPath

>>End If

>>Next

>>End Select

>>End If

>>Next

>>Next

>>Next

>>Next

>>

>>''''''''''''''''''''''''''

>>'

>>' ModifyUNCUsername

>>'

>>' Modifies the UNCUsername Key Under the Virtual Directories in the

>>Metabase.

>>'

>>''''''''''''''''''''''''''

>>Sub ModifyUNCPath(SitePoint, strPath)

>>' MsgBox ("SitePoint " & SitePoint)

>>On Error Resume Next

>>Set Site = GetObject("IIS://" & SitePoint)

>>On Error GoTo 0

>>WScript.Echo Space(Level*2 + 1) & "Changing Site #" & Count & " -

"

&

>>SitePoint

>>Site.Path = strPath

>>Site.SetInfo

>>End Sub

>>

>>

>>Thanks,

>>Robbie

>>

>>

>

>









-

Re:Please Help Optimize This Code

Thanks again Richard.



I will play with this subroutine.



Robbie



"Richard Mueller [MVP]" <rlmueller-nospam@ameritech.net>wrote in message

Quote
I'm not familiar with the IIS metabase, but a recursive subroutine seems

the

way to go. The following enumerates the entire structure.



Dim objParent = GetObject("IIS://MyServer/W3SVC")

Wscript.Echo objParent.Name

Call EnumIIS(objParent, "--")



Sub EnumIIS(objParent, strOffset)

Dim objChild

For Each objChild In objParent

Wscript.Echo strOffset & objChild.Name

Call EnumIIS(objChild, strOffset & "--")

Next

End Sub



--

Richard

Microsoft MVP Scripting and ADSI

HilltopLab web site - www.rlmueller.net">www.rlmueller.net

--

"Robert Elliott" <relliott@procard.com>wrote in message

news:eHcqgnAxDHA.3116@TK2MSFTNGP11.phx.gbl...

>Richard,

>

>Thanks for the input. I had a feeling there were a number of things

that

I

>didn't have optimized. I appreciate your input. I will change the

areas

>you mentioned.

>

>Richard, do you know how to recurse through the IIS metabase? I have

one

>site with 350 virtual directories. Each virtual directory has another

>virtual directory which contains a UNCPath that I need to update only

for

>certain sites (that I read in from the text file). Currently I am doing

the

>for each loops for each level of the heirarchy. I have a script that a

>friend helped me with that recurses a folder structure, but I am not

sure

>how to make that logic work with the metabase. Below is the script that

>recurses subfolders.

>

>I guess my real question is what would I pass into my sub for path if it

is

>the metabase? Can this even be done? What would you do?

>

>

>Dim fso, oFile, oFolder

>Set fso = CreateObject("Scripting.FileSystemObject")

>strPath = InputBox ("Enter Folder To Process.")

>Set oRootFolder = fso.GetFolder(strPath)

>

>If fso.FolderExists(oRootFolder) Then

>ProcessFiles(oRootFolder)

>End If

>

>''''''''''''''''''''''''''''''''''''''''''''''

>'Pass the path into the function

>'Recurse sub folders and process files in all subfolders

>'

>''''''''''''''''''''''''''''''''''''''''''''''

>

>Sub ProcessFiles (oPath)

>'MsgBox "oPath is " & oPath

>For Each oFile In oPath.Files

>If Right(oFile.Name, 3) = "dll" Then

>WScript.Echo oFile.Path & vbTab & " (" &

>fso.GetFileVersion(oFile.Path) & ")"

>End If

>Next

>

>For Each oFolder In oPath.SubFolders

>'MsgBox "oFolder is " & oFolder

>ProcessFiles (oFolder)

>Next

>

>End Sub

>

>

>

>

>"Richard Mueller [MVP]" <rlmueller-nospam@ameritech.net>wrote in

message

>news:ezCmGRAxDHA.1576@TK2MSFTNGP11.phx.gbl...

>>Hi,

>>

>>First, there is no need to recreate the FSO object. You only need the

>first

>>"Set objFSO". Next, I would close the file before reopening it. I

cannot

>>find a method to return to the beginning, except to use OpenTextFile

>again.

>>For example

>>

>>objTextFile.Close

>>Set objTextFile = objFSO.OpenTextFile("c:\temp\sites.txt", ForReading)

>>

>>A minor point, is that I would account for the possiblity that some

lines

>in

>>the text file could be blank. In particular, if the file ends with a

>>carriage return, it can have a blank last line. I would use:

>>

>>j = 0

>>Do Until objTextFile.AtEndOfStream

>>strLine = Trim(objTextFile.ReadLine)

>>If strLine <>"" Then

>>j = j + 1

>>End If

>>Loop

>>

>>...

>>

>>i = 0

>>Do Until objTextFile.AtEndOfStream

>>strLine = Trim(objTextFile.ReadLine)

>>If strLine <>"" Then

>>arrSiteList(i) = strLine

>>i = i + 1

>>Wscript.Echo arrSiteList(i)

>>End If

>>Loop

>>

>>Next, the big question is which is slower - Reading the text file

twice,

>or

>>ReDim'ing the array repeatedly in the first loop. When I test, both

>methods

>>are so fast that I cannot tell. Maybe someone else knows. Still, my

first

>>inclination would be to read the file once and ReDim in the loop, as

>>follows:

>>

>>j = 0

>>Do Until objTextFile.AtEndOfStream

>>strLine = Trim(objTextFile.ReadLine)

>>If strLine <>"" Then

>>ReDim Preserve arrSiteList(j)

>>arrSiteList(j) = strLine

>>Wscript.Echo arrSiteList(j)

>>j = j + 1

>>End If

>>Loop

>>

>>Then, a final idea would be to use a dictionary object instead of a

>dynamic

>>array. If I understand your code, the purpose of arrSiteList is to

check

>>each Child3.Name to see if it is in the list. The dictionary object

has

an

>>Exists method, so you don't have to loop through the entire array to

test

>if

>>the name is in the list. For example, I would try:

>>

>>Set objSiteList = CreateObject("Scripting.Dictionary")

>>objSiteList.CompareMode = vbTextCompare

>>

>>Do Until objTextFile.AtEndOfStream

>>strLine = Trim(objTextFile.ReadLine)

>>If strLine <>"" Then

>>objSiteList(strLine) = True

>>End If

>>Loop

>>

>>Then, in place of:

>>

>>strPath = Path & Child3.Name

>>For i = 0 To UBound(arrSiteList)

>>If arrSiteList(i) = Child3.Name Then

>>...

>>

>>I would use:

>>

>>strPath = Path & Child3.Name

>>If objSiteList(Child3.Name).Exists Then

>>...

>>

>>This way, the file is read only once, the dictionary object is

populated,

>>and you never have to loop through all entries in this object. That

should

>>be the fastest.

>>

>>--

>>Richard

>>Microsoft MVP Scripting and ADSI

>>HilltopLab web site - www.rlmueller.net">www.rlmueller.net

>>--

>>

>>"Robert Elliott" <relliott@procard.com>wrote in message

>>news:%23iVIrV$wDHA.2556@TK2MSFTNGP10.phx.gbl...

>>>Hello,

>>>

>>>I have a script that reads a text file into memory and modifies the

IIS

>>>metabase for the sites listed in the text file and updates the

UNCPath

>key

>>>for those site's virtual directories. I have written this code

myself,

>>but

>>>I am no programmer. I have a feeling that there is a better way to

loop

>>>through the metabase than the way I am doing it. It does work

>currently,

>>>but I would rather have the code optimized since I will be using it

>quite

>>a

>>>bit moving forward. Can someone please take a look and see if there

is

>a

>>>better way to do this?

>>>

>>>Dim arrSiteList()

>>>

>>>Set WshNetwork = CreateObject("WScript.Network")

>>>ComputerName = WshNetwork.ComputerName

>>>

>>>Const ForReading = 1

>>>

>>>'make FileSystemObject call

>>>Set objFSO = CreateObject("Scripting.FileSystemObject")

>>>Set objTextFile = objFSO.OpenTextFile ("c:\temp\sites.txt",

ForReading)

>>>

>>>'read in the number of lines in the text file

>>>j = 0

>>>Do Until objTextFile.AtEndOfStream

>>>objTextFile.Readline

>>>j = j + 1

>>>Loop

>>>

>>>'reset the FileSystemObject call

>>>Set objFSO = Nothing

>>>Set objTextFile = Nothing

>>>

>>>'resize my array to the number of lines in the text file

>>>'0 based indexing so there's really 1 less than j

>>>ReDim arrSiteList(j-1)

>>>

>>>'call a new FileSystemObject

>>>Set objFSO = CreateObject("Scripting.FileSystemObject")

>>>Set objTextFile = objFSO.OpenTextFile ("c:\temp\sites.txt",

ForReading)

>>>

>>>'populate newly sized array

>>>i = 0

>>>Do Until objTextFile.AtEndOfStream

>>>arrSiteList(i) = objTextFile.Readline

>>>wscript.echo arrSiteList(i)

>>>i = i + 1

>>>Loop

>>>

>>>Count = 0

>>>Path = "\\Server\Share\"

>>>SitePoint = ComputerName & "/W3SVC"

>>>Set Parent = GetObject("IIS://" & SitePoint)

>>>For Each Child In Parent

>>>For Each Child2 In Child

>>>For Each Child3 In Child2

>>>strPath = Path & Child3.Name

>>>for i = 0 to ubound(arrSiteList)

>>>'if Child3.Name is in the array of Sites then execute the

following

>>code

>>>if arrSiteList(i) = Child3.Name Then

>>>'Set fso = CreateObject ("Scripting.FileSystemObject")

>>>If Not objFSO.FolderExists(Child3.Name) Then

>>>objFSO.CreateFolder(Child3.Name)

>>>End If

>>>Select Case Child3.Name

>>>'just skip over these

>>>Case "localstart.asp"

>>>Case "Printers"

>>>Case "IISHelp"

>>>Case "iisadmin"

>>>Case "$D"

>>>Case "D"

>>>Case Else

>>>For Each Child4 In Child3

>>>If Child4.Name = "REPORTOUTPUT" Then

>>>SitePoint = ComputerName & "/W3SVC/" &

>>>Child.Name _

>>>& "/" &

>>Child2.Name

>>>_

>>>& "/" &

>>Child3.Name

>>>_

>>>& "/" &

>>Child4.Name

>>>Count = Count + 1

>>>ModifyUNCPath SitePoint, strPath

>>>End If

>>>Next

>>>End Select

>>>End If

>>>Next

>>>Next

>>>Next

>>>Next

>>>

>>>''''''''''''''''''''''''''

>>>'

>>>' ModifyUNCUsername

>>>'

>>>' Modifies the UNCUsername Key Under the Virtual Directories in the

>>>Metabase.

>>>'

>>>''''''''''''''''''''''''''

>>>Sub ModifyUNCPath(SitePoint, strPath)

>>>' MsgBox ("SitePoint " & SitePoint)

>>>On Error Resume Next

>>>Set Site = GetObject("IIS://" & SitePoint)

>>>On Error GoTo 0

>>>WScript.Echo Space(Level*2 + 1) & "Changing Site #" & Count &

" -

"

>&

>>>SitePoint

>>>Site.Path = strPath

>>>Site.SetInfo

>>>End Sub

>>>

>>>

>>>Thanks,

>>>Robbie

>>>

>>>

>>

>>

>

>









-