How do I reset the stream of StdOut in VBScript - vbscript

I want to use a VB script (full script in the Pastebin) to check that certain servers are up (responding to pings) every time I log in to my work computer.
However, it seems that as I am grabbing the full results of the output...
strPingResultsFull = LCase(WshExec.StdOut.ReadAll)
...before I loop through the individual lines...
Do Until WshExec.StdOut.AtEndOfStream
...that WshExec.StdOut is already AtEndOfStream, so I'm never getting any results.
The first part of my questing - is this theory correct (or likely to be correct)? The second part - How do I sort this out (i.e. reset the stream so that I can check every line individually)? Thanks.
' Set the targets to ping
strTarget(0) = "192.168.1.6" ' TTSA
strTarget(1) = "192.168.1.7" ' TTSB
strTarget(2) = "192.168.1.14" ' TTSC
strTarget(3) = "192.168.1.12" ' TTSD
Set WshShell = WScript.CreateObject("WScript.Shell")
' Loop through all of the targets to ping
For i = 0 To UBound(strTarget)
' Ping the target
Set WshExec = WshShell.Exec("ping -n 2 -w 500 " & strTarget(i)) ' Send 2 echo requests, waiting 0.5 seconds maximum
' Grab the full results of the ping
strPingResultsFull = LCase(WshExec.StdOut.ReadAll)
' Set 'strPingResultsPart' to an empty string
strPingResultsPart = ""
' Grab the results of the ping
Do Until WshExec.StdOut.AtEndOfStream
strSingleLine = WshExec.StdOut.ReadLine()
If Instr(strSingleLine, "Ping statistics for") <> 0 Or Instr(strSingleLine, "Packets:") <> 0 Then
strPingResultsPart = strPingResultsPart & strSingleLine
End If
Loop
' Check that there is something to output (there should be, even if the pings all fail)
If strPingResultsPart <> "" Then
Msgbox "Not empty - " & strPingResultsPart
' Add the ping results to the correct results strings
If InStr(strPingResultsFull, "reply from") Then
strOutputSuccess = strOutputSuccess & strPingResultsPart & VBCrLf
Else
strOutputFailure = strOutputFailure & strPingResultsPart & VBCrLf
End If
End If
Set WshExec = Nothing
Next

After first call WshExec.StdOut.ReadAll you're already at AtEndOfStream therefore...
Do Until WshExec.StdOut.AtEndOfStream
...will do nothing. You can't seek back StdOut to read from it multiple times.

Related

VBScript's Shell Command Will Not Execute Unless An Output File Is Specified

I'm trying to run a shell command for google speech recognition. I'm able to run the command only if I provide an output file to the command string.
As you can see my test code sample below, I would attach the ">outputFile" if one is provided and also coded in a timeout loop to abort the process after a set time limit.
strCommand = "cmd /c ipconfig /all"
If outputFile <> "" Then
strCommand = strCommand & " > """ & outputFile & """"
End If
Set wshShellExec = wshShell.Exec(strCommand)
expiration = DateAdd("s", 600, Now)
Do While wshShellExec.Status = WshRunning And Now < expiration
WScript.Sleep 5000
Loop
Select Case wshShellExec.Status
Case WshRunning
wshShellExec.Terminate
TestFunction = "{""error"": ""TestFunction Command Timed Out""}"
Case WshFinished
TestFunction = WshShellExec.StdOut.ReadAll()
Case WshFailed
TestFunction = wshShellExec.StdErr.ReadAll()
End Select
If I leave outputFile empty and try to expect the output to be returned from the function, all it does is sit still for 5 minutes before timing out and sending me my error message.
Why does it need an output file to run?
If I run the command line manually on a Command Prompt, it runs perfectly fine.
Output buffers have limited capacity. If your command writes too much text to stdout the buffer will fill up and block the command from writing more until you clear the buffer (e.g. by reading from it). ReadAll can't be used for that, though, because that method will only return after the command has finished and block otherwise, thus creating a deadlock.
Your best option is to redirect output to one or more (temp) files, and read the output from those files after the command has finished.
outfile = "C:\out.txt"
errfile = "C:\err.txt"
cmd = "cmd /c ipconfig /all >""" & outfile & """ 2>""" & errfile & """"
timeout = DateAdd("s", 600, Now)
Set sh = CreateObject("WScript.Shell")
Set ex = sh.Exec(cmd)
Do While ex.Status = WshRunning And Now < timeout
WScript.Sleep 200
Loop
Set fso = CreateObject("Scripting.FileSystemObject")
outtxt = fso.OpenTextFile(outfile).ReadAll
errtxt = fso.OpenTextFile(errfile).ReadAll
If you don't want to do that for some reason you must read from StdOut repeatedly.
outtxt = ""
errtxt = ""
cmd = "ipconfig /all"
timeout = DateAdd("s", 600, Now)
Set sh = CreateObject("WScript.Shell")
Set ex = sh.Exec(cmd)
Do While ex.Status = WshRunning And Now < timeout
WScript.Sleep 200
outtxt = outtxt & ex.StdOut.ReadLine & vbNewLine
Loop
Note that you may also need to read from StdErr, because that buffer might fill up too if there is too much error output. However, reading both buffers might create another deadlock, because IIRC ReadLine blocks until it can read a full line, so if the script might hang waiting for error output that never appears. You might be able to work around that by using Read instead of ReadLine, but it'll still be very fragile.
So, again, your best option is to redirect command output to files and read those files after the command terminates.
Once the wshShellExec is terminated in the WshRunning case, instead of assigning the error message, the output should be assigned.
Select Case wshShellExec.Status
Case WshRunning
wshShellExec.Terminate
TestFunction = "Terminated: " & vbcrlf & WshShellExec.StdOut.ReadAll()
Case WshFinished
TestFunction = "Finished: " & vbcrlf & WshShellExec.StdOut.ReadAll()
Case WshFailed
TestFunction = wshShellExec.StdErr.ReadAll()
End Select

VBS Object required error, 800A01A8

Hello I'm trying to debug this script that I inherited below. The error is on line 71 char 6. Object required 'oFile'
I don't have any vbs experience so please be gentle. This script takes a scan and uploads it to a doc archive server, gives it unique filename etc. I haven't figured out what 'ofile' is yet :/
'Feb 18, 2005
Dim oFSO
Set oFSO = CreateObject("Scripting.FileSystemObject")
hiddenCount = 0
'Wscript.Echo Wscript.Arguments(0)
If Wscript.Arguments.Count = 1 And oFSO.FolderExists(Wscript.Arguments(0)) Then
Set scanFiles = oFSO.GetFolder(Wscript.Arguments(0)).Files
For Each oFile In scanFiles
If oFile.Attributes and 2 Then
hiddenCount = hiddenCount + 1
End If
Next
Else
Set scanFiles = WScript.Arguments
End If
fileCount = scanFiles.Count - hiddenCount
'Wscript.Echo hiddenCount
'WScript.Echo fileCount
'WScript.Quit()
Set oIE = WScript.CreateObject("InternetExplorer.Application")
oIE.left=50 ' window position
oIE.top = 100 ' and other properties
oIE.height = 300
oIE.width = 350
oIE.menubar = 0 ' no menu
oIE.toolbar = 0
oIE.statusbar = 1
oIE.navigate "http://gisweb/apps/doc_archive/scan_login.php?file_count="&fileCount
'WScript.Echo fileCount
oIE.visible = 1
' Important: wait till MSIE is ready
Do While (oIE.Busy)
Loop
' Wait till the user clicks the OK button
' Use the CheckVal function
' Attention: Thanks to a note from M. Harris, we can make
' the script a bit more fool proof. We need to catch the case
' that the user closes the form without clicking the OK button.
On Error Resume Next
Do ' Wait till OK button is clicked
WScript.Sleep 400
Loop While (oIE.document.script.CheckVal()=0)
' If an error occur, because the form is closed, quit the
' script
If err <> 0 Then
WScript.Echo "Sorry, a run-time error occured during checking" & _
" the OK button " & vbCRLF & _
"Error: " & err.number & " " & _
"I guess the form was getting closed..."
WScript.Quit ' end script
End if
On Error Goto 0 ' switch error handling off
' User has clicked the OK button, retrieve the values
docList = oIE.Document.ValidForm.doc_id_list.Value
'MsgBox doc_id
For i = 0 To 100000
x = 1
Next
oIE.Quit() ' close Internet Explorer
Set oIE = Nothing ' reset object variable
docArray = Split(docList,",")
i = 0
For Each oFile In scanFiles
If Not oFile.Attributes And 2 Then **ERROR HERE**
ext = oFSO.GetExtensionName(oFile)
filename = "p"&right("000000"&docArray(i),6)&"."&ext
base = Int(docArray(i) / 500) * 500
subdir = "d"&right("000000"&base,6)
oFSO.CopyFile oFile, "\\ditgis02\Enterprise_GIS\doc_archive\raw\"&subdir&"\"&filename, True
i = i + 1
End If
Next
If Wscript.Arguments.Count = 1 And oFSO.FolderExists(Wscript.Arguments(0)) Then
Set WshShell = WScript.CreateObject("WScript.Shell")
intButton = WshShell.Popup (fileCount&" file(s) logged and copied! Do you want to delete temporary scan files?",0,"Done!",4)
If intButton = 6 Then
For Each oFile In scanFiles
oFile.Delete
Next
End If
Else
WScript.Echo(fileCount&" file(s) logged and copied!")
End If
WScript.Quit() ' Ready
' End
It looks the problem may arise if your initial test fails:
If Wscript.Arguments.Count = 1 And oFSO.FolderExists(Wscript.Arguments(0)) Then
...
Else
Set scanFiles = WScript.Arguments
End If
You're setting the scanFiles variable to a collection of arguments, not files. Later on, near line 71 (where your error occurs), you're treating scanFiles as if it's a Files collection and attempting to access the Attributes property of one of its File objects:
For Each oFile In scanFiles
If Not oFile.Attributes And 2 Then **ERROR HERE**
...
Next
This won't be possible since scanFiles is an Arguments collection instead. So I think you need to fix your initial Else clause to either terminate your script or provide some kind of "default" Files collection.

measuring print job time programmatically

I need to measure print job time, which means time between 'send print command' and 'print job disappear from the print queue'
so I am trying to do these things by script
search all pdf files
print a file
get the print time (as above)
go to next file and do all above for all files
this is my work so far(i omit some parts)
For Each file In objFolder.Items
' check for the extension
if objFSO.GetExtensionName(file.name) = "pdf" then
' invoke to print
file.InvokeVerbEx( "Print" )
' select print jobs
Set Printers = objWMIService.ExecQuery _
("Select * from Win32_PrintJob")
For Each objPrinter in Printers
DateTime.Value = objPrinter.TimeSubmitted
TimeinQueue = DateDiff("n", actualTime, Now)
Wscript.Echo TimeinQueue
Next
end if
next
mainly i need to ask how can i get the time when print job disappear from the print queue.
And I need to keep next job till one print job ends.
any ideas ?
There's no simple way to obtain that information from inside your script, because when the job is removed from the print queue it's gone. You could set up an event monitor for the print spooler like this:
Set wmi = GetObject("winmgmts://./root/cimv2")
Set wbemDateTime = CreateObject("WbemScripting.SWbemDateTime")
qry = "SELECT * FROM __InstanceOperationEvent WITHIN 1 " & _
"WHERE TargetInstance ISA 'Win32_PrintJob'"
Set mon = wmi.ExecNotificationQuery(qry)
Do
Set evt = mon.NextEvent
If evt.Path_.Class = "__InstanceDeletionEvent" Then
wbemDateTime.Value = evt.TargetInstance.TimeSubmitted
WScript.Echo evt.TargetInstance.Document & ": " & _
DateDiff("n", wbemDateTime.GetVarDate, Now)
End If
Loop
However, you'd have to run that from a different script, because VBScript doesn't support multi-threading (i.e. running things in parallel), so the event handler loop would block the rest of your script operations.
If you want a rough value from within your script, you could try something like this, but don't expect queue times to be very accurate:
'singleton SWbemDateTime instance for time conversions
Set wbemDateTime = CreateObject("WbemScripting.SWbemDateTime")
'global list to keep track of printing documents
'MUST NOT BE MODIFIED FROM ANYWHERE EXCEPT CheckPrintQueue!
Set printingDocs = CreateObject("Scripting.Dictionary")
Function CheckPrintQueue
Set printJobs = objWMIService.ExecQuery("SELECT * FROM Win32_PrintJob")
Set currentDocs = CreateObject("Scripting.Dictionary")
'get currently printing jobs from queue
For Each job In printJobs
currentDocs.Add job.Document, job.TimeSubmitted
Next
'compare global list to current list, print the queue time for documents
'that are no longer queued, and remove them from the global list
For Each doc In printingDocs.Keys
If Not currentDocs.Exists(doc) Then
wbemDateTime.Value = printingDocs(doc)
WScript.Echo doc & ": " & DateDiff("n", wbemDateTime.GetVarDate, Now)
printingDocs.Remove doc
End If
Next
'add new documents to global list
For Each doc In currentDocs.Keys
If Not printingDocs.Exists(doc) Then printingDocs.Add doc, currentDocs(doc)
Next
CheckPrintQueue = printJobs.Count
End Function
For Each file In objFolder.Items
If objFSO.GetExtensionName(file.name) = "pdf" Then
file.InvokeVerbEx "Print"
CheckPrintQueue
End If
Next
'wait until all jobs finished printing
Do While CheckPrintQueue > 0
WScript.Sleep 100
Loop
I was looking for exact thing and I simply summurized ansgar's script to get what I want.
its take every pdf files and print 5 times each(so i can get a avarage which better) while getting the time.finally print them in to a csv file. and untill one going to desapear from the print queue others wait waits. Not 100% acuurate but enough for the perfomance comparision
may be it may usefull (please correct my mistakes if any)
Dim objFSO, outFile
const forAppending = 8
const useDefault = -2
'Output File name
fileName = ".\output.csv"
Set objFSO = CreateObject("Scripting.FileSystemObject")
set outFile = objFSO.OpenTextFile(fileName, forAppending, true, useDefault)
'write heading to output file
outFile.WriteLine("Filename,1,2,3,4,5")
'get current Folder
strFolder = Replace(wscript.scriptfullname,wscript.scriptname,".\")
strFolder = objFSO.getFolder(strFolder)
'Open the Shell Folders object
Set objShell = CreateObject( "Shell.Application" )
'Create an object for the specified file's parent folder
Set objFolder = objShell.Namespace( strFolder )
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
For Each file In objFolder.Items
If objFSO.GetExtensionName(file.name) = "pdf" Then
'write in to out file
outFile.write(file.name)
outFile.writeLine ""
'outer loop for 5 times per each file
index = 0
do while index < 5
'if already doing a printing do not start a new one
if CheckPrintQueue() = 0 then
file.InvokeVerbEx "Print"
startTime = timer
waitTostart
'if first time on outer loop it should be empty queue
else
if index = 0 then
wscript.echo "queue doesnt empty"
finish
end if
end if
'wait until all jobs finished printing
waitToEnd
'count time
ellapsTime = timer - startTime
'write in to out file
outFile.write(",")
outFile.Write(ellapsTime)
index = index + 1
loop
End If
Next
outFile.Close
'----------------function CheckPrintQueue-----------------------
Function CheckPrintQueue()
Set printJobs = objWMIService.ExecQuery("SELECT * FROM Win32_PrintJob")
Set currentDocs = CreateObject("Scripting.Dictionary")
CheckPrintQueue = printJobs.Count
End Function
'----------------end of function-----------------
sub waitTostart
Do
WScript.Sleep 100
'check print queue
printJobCount = CheckPrintQueue()
Loop until printJobCount > 0
end sub
sub waitToEnd
Do
WScript.Sleep 100
'check print queue
printJobCount = CheckPrintQueue()
Loop until printJobCount = 0
end sub
sub finish
outFile.Close
objFSO = nothing
objFolder = nothing
objShell = nothing
objWMIService = nothing
wscript.quit 1
end sub

VB script run time error input past end of file

I'm taking a scripting class and im having some issues with my script. According to the lab assignment all my syntax is correct. However i keep getting a input past end of file error on line 60,1. I've starred at the program forever and checked all lines letter for letter for quite some time with no luck. Any help would be greatly appreciated. Here is the script.
dim ipAddress(5,3)
ipAddress(0,0)="192.168.10.11"
ipAddress(0,1)="192.168.10.12"
ipAddress(0,2)="192.168.10.13"
ipAddress(0,3)="192.168.10.14"
ipAddress(1,0)="192.168.10.19"
ipAddress(1,1)="192.168.10.20"
ipAddress(1,2)="192.168.10.21"
ipAddress(1,3)="192.168.10.22"
ipAddress(2,0)="192.168.10.27"
ipAddress(2,1)="192.168.10.28"
ipAddress(2,2)="192.168.10.29"
ipAddress(2,3)="192.168.10.30"
ipAddress(3,0)="192.168.10.35"
ipAddress(3,1)="192.168.10.36"
ipAddress(3,2)="192.168.10.37"
ipAddress(3,3)="192.168.10.38"
ipAddress(4,0)="192.168.10.43"
ipAddress(4,1)="192.168.10.44"
ipAddress(4,2)="192.168.10.45"
ipAddress(4,3)="192.168.10.46"
ipAddress(5,0)="192.168.10.51"
ipAddress(5,1)="192.168.10.52"
ipAddress(5,2)="192.168.10.53"
ipAddress(5,3)="192.168.10.54"
const READ = 1
const WRITE = 2
const APPEND = 8
const ASCII = 0
dim fileName
fileName = "IP_Addresses.csv"
dim ipAddrStr
ipAddrStr = ""
dim fso
Set fso = Wscript.CreateObject("Scripting.FileSystemObject")
Set ipFileObj = fso.CreateTextFile(fileName,True,ASCII)
For room = 0 to 5
For computer = 0 to 3
ipAddrSr = CStr(room+100) & "," & CStr(computer+1) & "," ipAddress(room,computer)
& vbCrlf
ipFileObj.write(ipAddrStr)
Next
Next
ipFileObj.close
Set ipFileObj = fso.OpenTextFile(fileName,READ,ASCII)
WScript.Echo ipFileObj.ReadAll **' this is line 60**
ipFileObj.Close
As you don't use "Option Explicit", you get what you deserve: You (try to) concatenate the lines into ipAddrSr but write ipAddrStr to the file. So nothing gets written to the file.
Fix the syntax error and the bad name to:
ipAddrStr = CStr(room+100) & "," & CStr(computer+1) & "," & ipAddress(room,computer) & vbCrlf
Assuming that the file isn't empty, perhaps you need to specify the directory the file is in? I think this can be done either in your script:
fileName = "c:\your_directory\IP_Addresses.csv"
Or if you run it in the command line via cscript...
cscript.exe your.vbs "c:\your_directory\IP_Addresses.csv"
You can check the file size before executing your Echo if you like...
if fileName.size > 0 then
Set ipFileObj = fso.OpenTextFile(fileName,READ,ASCII)
WScript.Echo ipFileObj.ReadAll **' this is line 60**
ipFileObj.Close
else
WScript.Echo = "File was empty"
end if
See details of passing an argument to your script here.

VBScript Renaming Windows Computer with Options

You guys did great helping me with one VBScript, so I'm going to throw another your way. Perhaps you can help me iron out the wrinkles.
My intention with this script is to rename the PC. The computer name is a combination of prompted text (something I provide, say a location code), a hyphen, and the last 10 digits of the computer's serial number called from WMIC. i.e. 1275-XXXXXXXXXX
My problems here are the following:
If my code is over 10 characters, it just errors out. I want to fix
that. I'm sure it's just the way I have it coded and nothing to do
with pulling from WMIC.
If it does error out pulling the serial number from WMIC, say because there's no value, I want to be prompted to enter something in it's place. Then at the end it will take Input1 (the location code) and Input2 (what I provide if the SN pull fails), smack a hyphen in the middle, and apply it.
My error out isn't working if it does fail. I don't know why.
I've found so many different solutions for renaming PC's either what I type in or specifically for pulling the SN, but not for my specific situation. Any help would be GREATLY appreciated, as always. :)
Here's my code:
'Rename computer by serial # v1.0 November 2009
dim Bios, BiosSerial, objFSO, objTextFile
'Const ForReading = 1, ForWriting = 2, ForAppending = 8
'get PropertyID
strInput = UserInput( "Enter the BHMS Property ID:" )
Function UserInput( myPrompt )
' This function prompts the user for some input.
' When the script runs in CSCRIPT.EXE, StdIn is used,
' otherwise the VBScript InputBox( ) function is used.
' myPrompt is the the text used to prompt the user for input.
' The function returns the input typed either on StdIn or in InputBox( ).
' Written by Rob van der Woude
' http://www.robvanderwoude.com
' Check if the script runs in CSCRIPT.EXE
If UCase( Right( WScript.FullName, 12 ) ) = "\CSCRIPT.EXE" Then
' If so, use StdIn and StdOut
WScript.StdOut.Write myPrompt & " "
UserInput = WScript.StdIn.ReadLine
Else
' If not, use InputBox( )
UserInput = InputBox( myPrompt )
End If
End Function
'Obtain Serial Number.
for each Bios in GetObject("winmgmts:").InstancesOf ("win32_bios")
BiosSerial = Bios.SerialNumber
exit for
next
strNewSN = BiosSerial
' If the SN is longer than 10 characters, truncate to the last 10.
If Len(strNewSN) < 9 Then
strNewSN = Right(BiosSerial, 10)
strNewPCName = strInput+"-"+strNewSN
End If
Set WshNetwork = WScript.CreateObject("WScript.Network")
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colComputers = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")
For Each objComputer in colComputers
err = objComputer.Rename(strNewPCName)
if err <> 0 then
wscript.echo "There was an error renaming the PC. Please restart and try again, or rename it manually."
else
wscript.echo "PC successfully renamed: " & strNewPCName
end if
Next
5/29/2013 EDIT: I've made some changes based on your suggestion, and I'm getting on error on line 36 char 1 "Expected Statement" Code 800A0400. It looks fine to me so what am I missing? Here's a new paste of my code with line 36 notated.
dim Bios, BiosSerial, objFSO, objTextFile
'Const ForReading = 1, ForWriting = 2, ForAppending = 8
' Prompt for PropertyID
strInput = UserInput( "Enter the BHMS Property ID:" )
Function UserInput( myPrompt )
' Check if the script runs in CSCRIPT.EXE
If UCase( Right( WScript.FullName, 12 ) ) = "\CSCRIPT.EXE" Then
' If so, use StdIn and StdOut
WScript.StdOut.Write myPrompt & " "
UserInput = WScript.StdIn.ReadLine
Else
' If not, use InputBox( )
UserInput = InputBox( myPrompt )
End If
End Function
' Obtain Serial Number.
for each Bios in GetObject("winmgmts:").InstancesOf ("win32_bios")
BiosSerial = Bios.SerialNumber
exit for
next
strNewSN = BiosSerial
If IsEmpty(BiosSerial) Then
strNewSN = UserInput("There is no serial number listed in the BIOS. Provide an alternative: ")
Else
strNewSN = BiosSerial
End If
' If the SN is longer than 10 characters, truncate to the last 10.
If Len(strNewSN) > 10 Then strNewSN = Right(BiosSerial, 10)
strNewPCName = strInput & "-" & strNewSN
End If 'LINE36'
Set WshNetwork = WScript.CreateObject("WScript.Network")
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colComputers = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")
For Each objComputer in colComputers
err = objComputer.Rename(strNewPCName)
On Error <> 0 Then
wscript.echo "There was an error renaming the PC. Please restart and try again, or rename it manually."
Else
wscript.echo "PC successfully renamed: " & strNewPCName
end if
Next
If my code is over 10 characters, it just errors out. I want to fix that. I'm sure it's just the way I have it coded and nothing to do with pulling from WMIC.
' If the SN is longer than 10 characters, truncate to the last 10.
If Len(strNewSN) < 9 Then
strNewSN = Right(BiosSerial, 10)
strNewPCName = strInput+"-"+strNewSN
End If
Your comment says that you want to use the last 10 characters from the serial number if the serial number is longer than that, but your code takes the last 10 characters only if the serial number is shorter than 9 characters. Change that into
If Len(strNewSN) > 10 Then strNewSN = Right(BiosSerial, 10)
strNewPCName = strInput & "-" & strNewSN
If it does error out pulling the serial number from WMIC, say because there's no value, I want to be prompted to enter something in it's place. Then at the end it will take Input1 (the location code) and Input2 (what I provide if the SN pull fails), smack a hyphen in the middle, and apply it.
You could use IsEmpty() to check if the BiosSerial variable has a value:
If IsEmpty(BiosSerial) Then
strNewSN = UserInput("Enter fake serial number:")
Else
strNewSN = BiosSerial
End If
My error out isn't working if it does fail. I don't know why.
Define "isn't working". What result do you get, and how is it different from the result you expect?
BTW, you shouldn't use err as a name for a variable. Err is an intrinsic object that VBScript provides in the context of handling terminating errors.
Edit: You have a spurious End If in line 36:
If Len(strNewSN) > 10 Then strNewSN = Right(BiosSerial, 10)
strNewPCName = strInput & "-" & strNewSN
End If
Remove that line and the error will disappear.
In VBSCript an If statement can have two forms:
With closing End If:
If condition Then
instruction
End If
When using this form, instruction must not be on the same line as the Then keyword.
Without closing End If:
If condition Then instruction
When using this form, instruction must be on the same line as the Then keyword and must not be followed by an End If.
In line 34 of your code you truncate the serial number to 10 characters if it's longer than that, and then execute the next line regardless of whether the serial number had to be truncated or not (that line must be executed unconditionally, so I removed it from the Then branch):
If Len(strNewSN) > 10 Then strNewSN = Right(BiosSerial, 10)
strNewPCName = strInput & "-" & strNewSN
which is equivalent to this:
If Len(strNewSN) > 10 Then
strNewSN = Right(BiosSerial, 10)
End If
strNewPCName = strInput & "-" & strNewSN

Resources