Subscript out of range error in vbs script - scripting

I'm trying to move my entire User folder in Vista to a non-system partition. To do so with a minimum hassle I'm following the directions provided at Ben's Blog, specifically the vbs script he provides. However executing the script throws up an error which I can't resolve myself. Here's the vbs code followed by the text file it calls on, and finally my error message. Can someone help me correct the problem? (I really don't know much about VBS, so please write as simple as possible.)
VBS Code:
'# Perform dir /a c:\users > c:\dir.txt
'# place this script file in c:\ too
'# double click to run it
'# run resulting script.bat from recovery mode
repprefix = " Directory of..." ' Modify to your language
sourcedrive = "C:\"
targetdrive = "D:\"
altsourcedrive = "C:\" 'leave same as target drive unless otherwise indicated
alttargetdrive = "E:\" 'leave same as target drive unless otherwise indicated
inname = "dir.txt"
outname = "script.bat"
userroot = "Users"
set fso = CreateObject("Scripting.FileSystemObject")
' construct batch commands for saving rights, then link, the recreating rights
Function GetCommand(curroot, line, typ, keyword)
' first need to get source and target
pos = Instr(line, keyword) + Len(keyword)
tuple = Trim(Mid(line, pos))
arr = Split(tuple, "[")
oldtarget = Replace(arr(1), "]", "")
oldlink = curroot & "\" & Trim(arr(0))
' need to determine if we are pointing back to old disk
newlink = replace(oldlink, sourcedrive, targetdrive)
if(Instr(oldtarget, sourcedrive & userroot)) then
newtarget = Replace(oldtarget, sourcedrive, targetdrive)
else
newtarget = oldtarget ' still pointing to original target
end if
' comment
out = "echo " & newlink & " --- " & newtarget & vbCrLf
' save permissions
out = out & "icacls """ & replace(oldlink, sourcedrive, altsourcedrive) & """ /L /save " & altsourcedrive & "permissions.txt" & vbCrLf
' create link
newlink = replace(newlink, targetdrive, alttargetdrive)
if typ = "junction" then
out = out & "mklink /j """ & newlink & """ """ & newtarget & """" & vbCrLf
else ' typ = "symlink"
out = out & "mklink /d """ & newlink & """ """ & newtarget & """" & vbCrLf
end if
'set hidden attribute
out = out & "attrib +h """ & newlink & """ /L" & vbCrLf
' apply permissions
shortlink = Left(newlink, InstrRev(newlink, "\") - 1) 'icacls works strangely - non-orthogonal for restore
out = out & "icacls """ & shortlink & """ /L /restore " & altsourcedrive & "permissions.txt" & vbCrLf
GetCommand = out & vbCrLf
End Function
Sub WriteToFile(file, text)
ForWriting = 2
Create = true
set outfile = fso.OpenTextFile(file, ForWriting, Create)
Call outfile.Write(text)
Call outfile.Close()
End Sub
outtext = "ROBOCOPY " & altsourcedrive & userroot & " " & alttargetdrive & userroot & " /E /COPYALL /XJ" & vbCrLf & vbCrLf
set intext = fso.OpenTextFile(inname)
while not intext.AtEndOfStream
line = intext.ReadLine()
if Instr(line, repprefix) then
curroot = Replace(line, repprefix, "")
elseif Instr(line, juncname) then
outtext = outtext & GetCommand(curroot, line, "junction", juncname)
elseif Instr(line, linkname) then
outtext = outtext & GetCommand(curroot, line, "symlink", linkname)
end if
Wend
outtext = outtext & "icacls " & altsourcedrive & userroot & " /L /save " & altsourcedrive & "permissions.txt" & vbCrLf
outtext = outtext & "ren " & altsourcedrive & userroot & " _" & userroot & vbCrLf
outtext = outtext & "mklink /j " & altsourcedrive & userroot & " " & targetdrive & userroot & vbCrLf
outtext = outtext & "icacls " & altsourcedrive & " /L /restore " & altsourcedrive & "permissions.txt"
Call intext.Close()
Call WriteToFile(outname, outtext)
MsgBox("Done writing to " & outname)
dir.txt:
Volume in drive C is ACER
Volume Serial Number is 08D7-C0CC
Directory of c:\users
07/16/2009 12:29 PM <DIR
07/16/2009 12:29 PM <DIR> ..
11/02/2006 09:02 AM <SYMLINKD> All Users [C:\ProgramData]
11/02/2006 09:02 AM <DIR> Default
11/02/2006 09:02 AM <JUNCTION> Default User [C:\Users\Default]
08/21/2008 08:37 AM 174 desktop.ini
11/02/2006 08:50 AM <DIR> Public
07/19/2009 08:54 PM <DIR> Steve
1 File(s) 174 bytes
7 Dir(s) 5,679,947,776 bytes free
Error Message:
Windows Script Host
Script: C:\userlocationchange.vbs
Line: 25
Char: 2
Error: Subscript out of range: '[number: 1]'
Code: 800A0009
Source: Microsoft VBScript runtime error

The problem is at these lines:
arr = Split(tuple, "[")
oldtarget = Replace(arr(1), "]", "")
I assume that arr(1) is giving the error because arr has only one entry - and since arrays are zero-based in VBS, that entry should be accessed as arr(0).
Hmmm... if there's only one entry, then presumably no "[" was found. The code probably needs to check for that (by testing whether UBound(arr) > 1).
What that means in a wider context - i.e. why there's no "[" I can't say.
EDIT: OK, I took a look at the blog you referred to, and the exact same problem was reported. The blog author replied:
A couple of pointers: look in the txt
file output by the dir command. On my
system, the targets of the symlinks
are shown in square brackets [].
Apparently in your case there aren't
any - in any case that is a hypothesis
that would explain why the script
can't parse out the link targets.
...which pretty much confirms my theory. I suggest you do as he suggests and take a look at the txt file to see if some other character is used.
Note that this isn't really a problem with the script per se - it's just that the script expects some input that it's not getting.

#Gary, I'm the same one who reported the problem on that blog.
I posted the txt file here under the VBS code. My txt file also has the symlink-junction targets within square brackets. Is there anything else I'm missing?

Related

WScript and com ref issue

wscript no longer uses run? and other gets a com reference issue,
the code is for editing current session for downloading the csv file.
every to this point works as it should.
If Dir(cf) = "" Then CreateObject("WScript.Shell").RUN "cmd.exe /s /c echo TEXT&echo.Enter your pin&echo.&echo. & " & f & " --aea --cookie-jar " & cf, vbNormalFocus, True
C = CreateObject("New:0D43FE01-F093-11CF-8940-00A0C9054228").OpenTextFile(cf).ReadAll
If InStr(C, vbTab) = 0 Or InStr(C, vbCrLf) = 0 Then JasperDruif = True: GoTo doitagain
Set t = CreateObject("New:47DFBE54-CF76-11D3-B38F-00105A1F473A")
t.SetVarDate Now
If Right(Split(C, vbTab & "session")(0), 10) / 1 < ((t.getVarDate(False) - 25569) * 86400) Then CreateObject("WScript.Shell").RUN "cmd.exe /s /c echo TEXT.&echo.Enter your pin&echo.&echo. & " & f & " --aea --cookie-jar " & cf, vbNormalFocus, True: C = CreateObject("New:0D43FE01-F093-11CF-8940-00A0C9054228").OpenTextFile(cf).ReadAll
Cookie = "session=" & Split(Split(C, "session" & vbTab)(1), vbCrLf)(0)
any idea how to make this work in vb.net, worked fine in vb6 and even on excel vba.

how to give line feed in the body msg of the mail for sending

I want to send a mail to my colleagues in an automated format. For this I have a code but the issue is I am unable to give line feed or hard enter in between the lines. Here is my code:
Dim s
Set s = CreateObject("WScript.Shell")
inputCont = Wscript.Arguments.Item(0)
inputCust = Wscript.Arguments.Item(1)
processCust = Wscript.Arguments.Item(2)
msgbody = "Hi All " & chr(13) & "fine"
s.run Chr(34) & "c:\Program Files\mozilla thunderbird\thunderbird.exe" & Chr(34) & " -compose mailto:aaa#gmail.com?subject=subject-crash" & inputCont & "&body=" & msgbody & ""
WScript.Sleep 10000
s.SendKeys "^{ENTER}"
WScript.Sleep 1000
Regards
B. Jithesh

vbs script upload only the file name without inside data

The problem of this script is that it shows an unknown error Message while running the script.
I called the function by echo method in my ftp which is "filezilla".
every thing is working fine as it logs into the server check for the path, open channel for data writing. Still dont know where is the problem
Function FTPUpload(sSite, sUsername, sPassword, sLocalFile, sRemotePath)
'This script is provided under the Creative Commons license located
'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not
'be used for commercial purposes with out the expressed written consent
'of NateRice.com
Const OpenAsDefault = -2
Const FailIfNotExist = 0
Const ForReading = 1
Const ForWriting = 2
Set oFTPScriptFSO = CreateObject("Scripting.FileSystemObject")
Set oFTPScriptShell = CreateObject("WScript.Shell")
sRemotePath = Trim(sRemotePath)
sLocalFile = Trim(sLocalFile)
'----------Path Checks---------
'Here we willcheck the path, if it contains
'spaces then we need to add quotes to ensure
'it parses correctly.
If InStr(sRemotePath, " ") > 0 Then
If Left(sRemotePath, 1) <> """" And Right(sRemotePath, 1) <> """" Then
sRemotePath = """" & sRemotePath & """"
End If
End If
If InStr(sLocalFile, " ") > 0 Then
If Left(sLocalFile, 1) <> """" And Right(sLocalFile, 1) <> """" Then
sLocalFile = """" & sLocalFile & """"
End If
End If
'Check to ensure that a remote path was
'passed. If it's blank then pass a "\"
If Len(sRemotePath) = 0 Then
'Please note that no premptive checking of the
'remote path is done. If it does not exist for some
'reason. Unexpected results may occur.
sRemotePath = "\"
End If
'Check the local path and file to ensure
'that either the a file that exists was
'passed or a wildcard was passed.
If InStr(sLocalFile, "*") Then
If InStr(sLocalFile, " ") Then
FTPUpload = "Error: Wildcard uploads do not work if the path contains a " & _
"space." & vbCRLF
FTPUpload = FTPUpload & "This is a limitation of the Microsoft FTP client."
Exit Function
End If
ElseIf Len(sLocalFile) = 0 Or Not oFTPScriptFSO.FileExists(sLocalFile) Then
'nothing to upload
FTPUpload = "Error: File Not Found."
Exit Function
End If
'--------END Path Checks---------
'build input file for ftp command
sFTPScript = sFTPScript & "USER " & sUsername & vbCRLF
sFTPScript = sFTPScript & sPassword & vbCRLF
sFTPScript = sFTPScript & "cd " & sRemotePath & vbCRLF
sFTPScript = sFTPScript & "binary" & vbCRLF
sFTPScript = sFTPScript & "prompt n" & vbCRLF
sFTPScript = sFTPScript & "put " & sLocalFile & vbCRLF
sFTPScript = sFTPScript & "quit" & vbCRLF & "quit" & vbCRLF & "quit" & vbCRLF
sFTPTemp = oFTPScriptShell.ExpandEnvironmentStrings("%TEMP%")
sFTPTempFile = sFTPTemp & "\" & oFTPScriptFSO.GetTempName
sFTPResults = sFTPTemp & "\" & oFTPScriptFSO.GetTempName
'Write the input file for the ftp command
'to a temporary file.
Set fFTPScript = oFTPScriptFSO.CreateTextFile(sFTPTempFile, True)
fFTPScript.WriteLine(sFTPScript)
fFTPScript.Close
Set fFTPScript = Nothing
oFTPScriptShell.Run "%comspec% /c FTP -n -s:" & sFTPTempFile & " " & sSite & _
" > " & sFTPResults, 0, TRUE
Wscript.Sleep 1000
'Check results of transfer.
Set fFTPResults = oFTPScriptFSO.OpenTextFile(sFTPResults, ForReading, _
FailIfNotExist, OpenAsDefault)
sResults = fFTPResults.ReadAll
fFTPResults.Close
oFTPScriptFSO.DeleteFile(sFTPTempFile)
oFTPScriptFSO.DeleteFile (sFTPResults)
If InStr(sResults, "226 Transfer complete.") > 0 Then
FTPUpload = True
ElseIf InStr(sResults, "File not found") > 0 Then
FTPUpload = "Error: File Not Found"
ElseIf InStr(sResults, "cannot log in.") > 0 Then
FTPUpload = "Error: Login Failed."
Else
FTPUpload = "Error: Unknown."
End If
Set oFTPScriptFSO = Nothing
Set oFTPScriptShell = Nothing
WScript.Echo "Process Completed (" & Now & ")"
End Function

Move file into dynamically created folder with VB Script

I am working on a backup script in VBS that creates a folder and then copies a powerpoint file into the most recently created folder.
Everything works great except MoveFile command at the bottom
Here is what I got so far (the bottom code is most important but just so everyone can understand where I am coming from):
sourceDir = "T:\Team"
destinationDir = "T:\Team\Archive\Archive"
const OverwriteExisting = True
intNum = 1
strDirectory = destinationDir & "_" & replace(date,"/",".") & "_" & intNum
'This checks if the folder exists and if not it will create a folder with the date and increment the folder name incase there are multiple updates in a single day.
if not filesys.FolderExists(destinationDir) then
While filesys.FolderExists(destinationDir & "_" & replace(date,"/",".") & "_" & intNum) = True
intNum = intNum + 1
Wend
Set archivefolder = filesys.CreateFolder(destinationDir & "_" & replace(date,"/",".") & "_" & intNum)
Else
Set archivefolder = filesys.CreateFolder(destinationDir)
Set objFolder = fso.CreateFolder(strDirectory)
End if
Dim thisday, thisdayy, thisdayyy
Today_Date()
' This is the problem code
filesys.MoveFile "T:\Arriva\Project_Organigram_" & thisday & "." & thisdayy & "." & thisdayyy & ".pptm", "destinationDir & "\" & Project_Organigram_" & thisday & "." & thisdayy & "." & thisdayyy & ".pptm"
Function Today_Date()
thisday=Right(Day(Date),2)
thisdayy=Right("0" & Month(Date),2)
thisdayyy=Right("0" & Year(Date),2)
End Function
This results in a folder being created as "T:\Team\Archive\Archive_03.12.2014_1
My goal is to be able to move the file in T:\Team to the dynamically created folder above.
Everything works great until the MoveFile part. The destination is the part throwing a "type mismatch" at the line where I define the strDirectory
I am just learning this type of programming so please let me know if I can provide any further details!
Thank you in advance!
You have a couple syntax errors with your quotes that are cancelling each other out. Change your line to this:
filesys.MoveFile "T:\Team\Project_Organigram_" & thisday & "." & thisdayy & "." & thisdayyy & ".pptm", "destinationDir" & "_" & replace(date,"/",".") & "_" & intNum & "\" & "Project_Organigram_" & thisday & "." & thisdayy & "." & thisdayyy & ".pptm"

VB.NET - using textfile as source for menus and textboxes

this is probably a bit tense and I'm not sure if this is possible at all.
But basically, I'm trying to create a small application which contains alot of PowerShell-code which I want to run in an easy matter.
I've managed to create everything myself and it does work. But all of the PowerShell code is manually hardcoded and this gives me a huge disadvantage.
What I was thinking was creating some sort of dynamic structure where I can read a couple of text files (possible a numerous amount of text files) and use these as the source for both the comboboxes and the richtextbox which provovides as the string used to run in PowerShell.
I was thinking something like this:
Combobox - "Choose cmdlet" - Use "menucode.txt" as source
Richtextbox - Use "code.txt" as source
But, the thing is, Powershell snippets need a few arguments in order for them to work.
So I've got a couple of comboboxes and a few textboxes which provides as input for these arguments. And this is done manually as it is right now. So rewriting this small application should also search the textfile for some keywords and have the comboboxes and textboxes to replace those keywords. And I'm not sure how to do this.
So, would this requre a whole lot of textfiles? Or could I use one textfile and separate each PowerShell cmdlet snippets with something? Like some sort of a header?
Right now, I've got this code at the eventhandler (ComboBox_SelectedIndexChanged)
If ComboBoxFunksjon.Text = "Set attribute" Then
TxtBoxUsername.Visible = True
End If
If chkBoxTextfile.Checked = True Then
If txtboxBrowse.Text = "" Then
MsgBox("You haven't choses a textfile as input for usernames")
End If
LabelAttribute.Visible = True
LabelUsername.Visible = False
ComboBoxAttribute.Visible = True
TxtBoxUsername.Visible = False
txtBoxCode.Text = "$users = Get-Content " & txtboxBrowse.Text & vbCrLf & "foreach ($a in $users)" & vbCrLf & "{" & vbCrLf & "Set-QADUser -Identity $a -ObjectAttributes #{" & ComboBoxAttribute.SelectedItem & "='" & TxtBoxValue.Text & "'}" & vbCrLf & "}"
If ComboBoxAttribute.SelectedItem = "Outlook WebAccess" Then
TxtBoxValue.Visible = False
CheckBoxValue.Visible = True
CheckBoxValue.Text = "OWA Enabled?"
txtBoxCode.Text = "$users = Get-Content " & txtboxBrowse.Text & vbCrLf & "foreach ($a in $users)" & vbCrLf & "{" & vbCrLf & "Set-CASMailbox -Identity $a -OWAEnabled" & " " & "$" & CheckBoxValue.Checked & " '}" & vbCrLf & "}"
End If
If ComboBoxAttribute.SelectedItem = "MobileSync" Then
TxtBoxValue.Visible = False
CheckBoxValue.Visible = True
CheckBoxValue.Text = "MobileSync Enabled?"
Dim value
If CheckBoxValue.Checked = True Then
value = "0"
Else
value = "7"
End If
txtBoxCode.Text = "$users = Get-Content " & txtboxBrowse.Text & vbCrLf & "foreach ($a in $users)" & vbCrLf & "{" & vbCrLf & "Set-QADUser -Identity $a -ObjectAttributes #{msExchOmaAdminWirelessEnable='" & value & " '}" & vbCrLf & "}"
End If
Else
LabelAttribute.Visible = True
LabelUsername.Visible = True
ComboBoxAttribute.Visible = True
txtBoxCode.Text = "Set-QADUser -Identity " & TxtBoxUsername.Text & " -ObjectAttributes #{" & ComboBoxAttribute.SelectedItem & "='" & TxtBoxValue.Text & " '}"
If ComboBoxAttribute.SelectedItem = "Outlook WebAccess" Then
TxtBoxValue.Visible = False
CheckBoxValue.Visible = True
CheckBoxValue.Text = "OWA Enabled?"
txtBoxCode.Text = "Set-CASMailbox " & TxtBoxUsername.Text & " -OWAEnabled " & "$" & CheckBoxValue.Checked
End If
If ComboBoxAttribute.SelectedItem = "MobileSync" Then
TxtBoxValue.Visible = False
CheckBoxValue.Visible = True
CheckBoxValue.Text = "MobileSync Enabled?"
Dim value
If CheckBoxValue.Checked = True Then
value = "0"
Else
value = "7"
End If
txtBoxCode.Text = "Set-QADUser " & TxtBoxUsername.Text & " -ObjectAttributes #{msExchOmaAdminWirelessEnable='" & value & "'}"
End If
End If
Now, this snippet above lets me either use a text file as a source for each username used in the powershell snippet. Just so you know :) And I know, this is probably coded as stupidly as it gets. But it does work! :)
It'll probably get fairly horrible to debug when you've been away from it for a year and are trying to figure out how it hangs together, but if you're doing it I'd suggest that this might be a good time to use XML, since you can then create a nice structure to the files easily that will be fairly easy to understand.
<commands>
<command>
<name>Cmd1</name>
<buttonText>NiceName</buttonText>
<parameters>
<parameter>textBox1</parameter>
<parameter>textBox2</parameter>
<parameter>comboBox1</parameter>
</parameters>
<code>your code here</code>
</command>
<command>
...
</command>
</commands>
You'd have to be careful if your script code contains any characters that can interfere with the xml though.