VBscript: how to do a "testonly" argument to simulate output?

I have a script and will be writing more in VBscript.

I'd like to know a way to do something like wscript.exe script testonly

So that testonly is an argument I can pass to my script that will make the script(s) only a run a testcase and output what it would have done to a text file for review.

That way I can test my scripts without actually making any changes to production until I was assured they worked right.

Thanks.
LVL 23
TheCleanerAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

David LeeCommented:
Hi, TheCleaner.

You'll want to use WScript's Arguments object.  Something like this
Dim varTestOnly
varTestOnly = False
 
If WScript.Arguments.Count > 0 Then
    Set objArgs = WScript.Arguments
    For Each varArg In objArgs
        If LCase(varArg) = "testonly" Then
            varTestOnly = True
        End If
    Next
End If
 
'For any output action
If varTestOnly Then
    'Some code for writing output to a file
Else
    'Some code for performing the actual script action
End If

Open in new window

0
RobSampsonCommented:
BDF is right.  There is no "built in" ability to test commands only, you have to write it yourself.

So, by running
cscript MyScript.vbs testonly

(you would use cscript, instead of wscript, so that your WScript.Echo statements appeared at the command line instead of message boxes)

you can then write your VBS (as BDF has done) to test whether the parameter "testonly" was passed, and then use:

'=============
Dim varTestOnly
varTestOnly = False
 
If WScript.Arguments.Count > 0 Then
    Set objArgs = WScript.Arguments
    For Each varArg In objArgs
        If LCase(varArg) = "testonly" Then
            varTestOnly = True
        End If
    Next
End If

If varTestOnly Then
      WScript.Echo "THIS SCRIPT IS RUNNING IN OUTPUT ONLY MODE."
      WScript.Echo "NO MODIFICATIONS WILL TAKE PLACE."
Else
      WScript.Echo "THIS SCRIPT IS RUNNING IN MODIFICATION MODE."
      WScript.Echo "MODIFICATIONS WILL OCCUR. DO YOU WANT TO CONTINUE?"
      strResponse = InputBox("Do you want to continue running in modification mode? (Y/N)", "Continue?")
      If strResponse = "" Then
            WScript.Quit
      ElseIf Left(UCase(strResponse), 1) = "N" Then
            WScript.Quit
      ElseIf Left(UCase(strResponse), 1) = "Y" Then
            WScript.Echo "Script will continue in modification mode."
      Else
            WScript.Echo "Invalid reponse."
            WScript.Quit
      End If
End If

'For any output action
strValue = "test"
strNewValue = "change"
If varTestOnly Then
    'Some code for writing output to a file
    WScript.Echo "OUTPUT: " & strValue & " would change to " & strNewValue
Else
    'Some code for performing the actual script action
    strValue = strNewValue
    WScript.Echo "CHANGE: " & strValue & " has been changed to " & strNewValue
End If
'=============


Regards,

Rob
0
TheCleanerAuthor Commented:
It seems like you are saying my actual script would be where "Some code for performing the actual script action" would go...is that right?

Maybe I'm reading it wrong...would I just insert this into my existing scripts?  
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

David LeeCommented:
Yes, to both.  Maybe I should have phrased it this way
If varTestOnly Then
    'Some code for performing the test case
    'Could be a call to a sub or function that performs the test case
Else
    'Some code for performing the actual script action
    'Could be a call to a sub or function that performs the actual script action
End If

Open in new window

0
RobSampsonCommented:
That's right, you need to modify your existing script to check for TestOnly at each statment that would make a change.

So I took a bit of time (but haven't tested it, so hopefully it works) to modify the script from your previous question to accomodate this "testonly" flag.

'==========================================================================
'
' VBScript Source File -- Created with SAPIEN Technologies PrimalScript 2007
'
' NAME: Import user attributes into AD from Strategy CSV export
'
'
' COMMENT: Do not modify this script without permission, you can break stuff
'
'==========================================================================

'====================
' Search_LDAP_Using_ADO_To_Update_User_Info_From_Excel.vbs
' http://www.experts-exchange.com/Programming/Languages/Scripting/Q_22912145.html

' SECTION 1 SETS UP SCRIPTING LANGUAGE AND IDENTIFIES TEST MODE (OUTPUT ONLY)

' Force script to run in CScript so we can see output via WScript.Echo statements
If Right(LCase(WScript.FullName), 11) = "wscript.exe" Then
      Set objShell = CreateObject("WScript.Shell")
      If WScript.Arguments.Count > 0 Then
            objShell.Run "cmd /k cscript """ & WScript.ScriptFullName & """ " & WScript.Arguments.Item(0), 1, False
    Else
          objShell.Run "cmd /k cscript """ & WScript.ScriptFullName & """", 1, False
      Set objShell = Nothing
      WScript.Quit
End If

' Check whether the testonly command line argument has been passed to the script
varTestOnly = False

If WScript.Arguments.Count > 0 Then
    Set objArgs = WScript.Arguments
    For Each varArg In objArgs
        If LCase(varArg) = "testonly" Then
            varTestOnly = True
        End If
    Next
End If

If varTestOnly Then
      WScript.Echo "THIS SCRIPT IS RUNNING IN OUTPUT ONLY MODE."
      WScript.Echo "NO MODIFICATIONS WILL TAKE PLACE."
Else
      WScript.Echo "THIS SCRIPT IS RUNNING IN MODIFICATION MODE."
      WScript.Echo "MODIFICATIONS WILL OCCUR. DO YOU WANT TO CONTINUE?"
      strResponse = InputBox("Do you want to continue running in modification mode? (Y/N)", "Continue?")
      If strResponse = "" Then
            WScript.Quit
      ElseIf Left(UCase(strResponse), 1) = "N" Then
            WScript.Quit
      ElseIf Left(UCase(strResponse), 1) = "Y" Then
            WScript.Echo "Script will continue in modification mode."
      Else
            WScript.Echo "Invalid reponse."
            WScript.Quit
      End If
End If

' SECTION 1 End

' SECTION 2 GETS EXCEL SPREADSHEET INPUT FILE, READS FILE

' INPUT EXCEL FILE FOR IMPORTING (path required if not in the same directory as the script)
strExcelFile = "Users_To_Update.xls"

Const xlUp = -4162
Const ADS_PROPERTY_CLEAR = 1

Set objExcel = CreateObject("Excel.Application")
Set objWB = objExcel.Workbooks.Open(Replace(WScript.ScriptFullName, WScript.ScriptName, "") & strExcelFile)
objExcel.Visible = True

For intRow = 2 To objWB.ActiveSheet.Cells(65536, "A").End(xlUp).Row ' (sets start row to row 2 and finds last non-empty row)
      ' Get the details per row from the Excel file
      strEmpID = objWB.ActiveSheet.Cells(intRow, "A").Value
      strLastName = objWB.ActiveSheet.Cells(intRow, "B").Value
      strFirstName = objWB.ActiveSheet.Cells(intRow, "C").Value
      strTitle = objWB.ActiveSheet.Cells(intRow, "D").Value
      strDepartment = objWB.ActiveSheet.Cells(intRow, "E").Value
      strManagerEmpID = objWB.ActiveSheet.Cells(intRow, "F").Value

' SECTION 2 End

' SECTION 3 Calls the Function and then updates attributes in AD based on function results
' SECTION 3 Function gets User account where ipPhone = EmployeeID from spreadsheet and creates a
' SECTION 3 recordset of all attributes in that user account for modifying below
      strUserADsPath = Get_LDAP_User_Properties("user", "ipPhone", strEmpID, "adsPath")
      If InStr(UCase(strUserADsPath), "LDAP://") > 0 Then
            Set objUser = GetObject(strUserADsPath)
            WScript.Echo "Processing " & strUserADsPath
            ' If Trim(strFirstName) <> "" Then
'                        If varTestOnly Then
                            'Some code for writing output to a file
'                            WScript.Echo "OUTPUT: " & objUser.DisplayName & " > First Name would change from " & objUser.givenName & " to " & strFirstName
'                        Else
                            'Some code for performing the actual script action
'                    WScript.Echo "CHANGE: " & objUser.DisplayName & " > First Name has been changed from " & objUser.givenName & " to " & strFirstName
'                   objUser.givenName = CStr(strFirstName)
'                        End If
'             End If
'             If Trim(strLastName) <> "" Then
'                        If varTestOnly Then
                            'Some code for writing output to a file
'                            WScript.Echo "OUTPUT: " & objUser.DisplayName & " > Last Name would change from " & objUser.sn & " to " & strLastName
'                        Else
                            'Some code for performing the actual script action
'                    WScript.Echo "CHANGE: " & objUser.DisplayName & " > Last Name has been changed from " & objUser.sn & " to " & strLastName
'                   objUser.sn = CStr(strLastName)
'                        End If
'            End If
            If Trim(strDepartment) <> "" Then
                        If varTestOnly Then
                            'Some code for writing output to a file
                            WScript.Echo "OUTPUT: " & objUser.DisplayName & " > Department would change from " & objUser.Department & " to " & strDeparment
                        Else
                            'Some code for performing the actual script action
                    WScript.Echo "CHANGE: " & objUser.DisplayName & " > Department has been changed from " & objUser.Department & " to " & strDeparment
                    objUser.department = CStr(strDepartment)
                End If
            End If
            If Trim(strTitle) <> "" Then
                        If varTestOnly Then
                            'Some code for writing output to a file
                            WScript.Echo "OUTPUT: " & objUser.DisplayName & " > Title would change from " & objUser.Title & " to " & strTitle
                        Else
                            'Some code for performing the actual script action
                    WScript.Echo "CHANGE: " & objUser.DisplayName & " > Title has been changed from " & objUser.Title & " to " & strTitle
                    objUser.title = CStr(strTitle)
                End If
            End If
            If Trim(strManagerEmpID) <> "" Then
                  strManagerADsPath = Get_LDAP_User_Properties("user", "ipPhone", strManagerEmpID, "adsPath")
                  If InStr(UCase(strManagerADsPath), "LDAP://") > 0 Then
                        strUserName = Mid(strManagerADsPath, 8, InStr(strManagerADsPath, ",") - 8)
                              If varTestOnly Then
                                  'Some code for writing output to a file
                                  WScript.Echo "OUTPUT: " & objUser.DisplayName & " > Manager would change from " & objUser.Manager & " to " & strUserName
                              Else
                                  'Some code for performing the actual script action
                              'WScript.Echo "Clearing the Manager of " & objUser.DisplayName
                              On Error Resume Next
                             ' objUser.PutEx ADS_PROPERTY_CLEAR, "managedBy", 0
                             ' objUser.SetInfo
                              On Error GoTo 0
                                WScript.Echo "CHANGE: " & objUser.DisplayName & " > Manager has been changed from " & objUser.Manager & " to " & strUserName
                              objUser.Manager = Mid(strManagerADsPath, 8)
                              objUser.SetInfo
                      End If
                  Else
                        WScript.Echo "Could not find ADsPath for manager with employee ID: " & strManagerEmpID
                  End If
            End If
            objUser.SetInfo
      Else
            WScript.Echo "Could not find ADsPath for employee ID: " & strEmpID
      End If

Next

' SECTION 3 END

' SECTION 4 Closes spreadsheet and ends Script

objExcel.Quit
Set objExcel = Nothing

WScript.Echo "Done"
MsgBox "Done"

' SECTION 4 End

' SECTION 5 FUNCTION that queries AD and matches users in AD to the EmployeeID (ipPhone) column in the spreadsheet

Function Get_LDAP_User_Properties(strObjectType, strSearchField, strObjectToGet, strCommaDelimProps)
     
      ' This is a custom function that connects to the Active Directory, and returns the specific
      ' Active Directory attribute value, of a specific Object.
      ' strObjectType: usually "User" or "Computer"
      ' strSearchField: the field by which to search the AD by. This acts like an SQL Query's WHERE clause.
      '                        It filters the results by the value of strObjectToGet
      ' strObjectToGet: the value by which the results are filtered by, according the strSearchField.
      '                        For example, if you are searching based on the user account name, strSearchField
      '                        would be "samAccountName", and strObjectToGet would be that speicific account name,
      '                        such as "jsmith".  This equates to "WHERE 'samAccountName' = 'jsmith'"
      '      strCommaDelimProps: the field from the object to actually return.  For example, if you wanted
      '                        the home folder path, as defined by the AD, for a specific user, this would be
      '                        "homeDirectory".  If you want to return the ADsPath so that you can bind to that
      '                        user and get your own parameters from them, then use "ADsPath" as a return string,
      '                        then bind to the user: Set objUser = GetObject("LDAP://" & strReturnADsPath)
     
      ' Now we're checking if the user account passed may have a domain already specified,
      ' in which case we connect to that domain in AD, instead of the default one.
      If InStr(strObjectToGet, "\") > 0 Then
            arrGroupBits = Split(strObjectToGet, "\")
            strDC = arrGroupBits(0)
            strDNSDomain = strDC & "/" & "DC=" & Replace(Mid(strDC, InStr(strDC, ".") + 1), ".", ",DC=")
            strObjectToGet = arrGroupBits(1)
      Else
      ' Otherwise we just connect to the default domain
            Set objRootDSE = GetObject("LDAP://RootDSE")
            strDNSDomain = objRootDSE.Get("defaultNamingContext")
      End If

      strBase = "<LDAP://" & strDNSDomain & ">"
      ' Setup ADO objects.
      Set adoCommand = CreateObject("ADODB.Command")
      Set adoConnection = CreateObject("ADODB.Connection")
      adoConnection.Provider = "ADsDSOObject"
      adoConnection.Open "Active Directory Provider"
      adoCommand.ActiveConnection = adoConnection

 
      ' Filter on user objects.
      'strFilter = "(&(objectCategory=person)(objectClass=user))"
      strFilter = "(&(objectClass=" & strObjectType & ")(" & strSearchField & "=" & strObjectToGet & "))"

      ' Comma delimited list of attribute values to retrieve.
      strAttributes = strCommaDelimProps
      arrProperties = Split(strCommaDelimProps, ",")

      ' Construct the LDAP syntax query.
      strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
      adoCommand.CommandText = strQuery
      ' Define the maximum records to return
      adoCommand.Properties("Page Size") = 100
      adoCommand.Properties("Timeout") = 30
      adoCommand.Properties("Cache Results") = False

      ' Run the query.
      Set adoRecordset = adoCommand.Execute
      ' Enumerate the resulting recordset.
      strReturnVal = ""
      Do Until adoRecordset.EOF
          ' Retrieve values and display.    
          For intCount = LBound(arrProperties) To UBound(arrProperties)
                If strReturnVal = "" Then
                      strReturnVal = adoRecordset.Fields(intCount).Value
                Else
                      strReturnVal = strReturnVal & VbCrLf & adoRecordset.Fields(intCount).Value
                End If
          Next
          ' Move to the next record in the recordset.
          adoRecordset.MoveNext
      Loop

      ' Clean up.
      adoRecordset.Close
      adoConnection.Close
      Get_LDAP_User_Properties = strReturnVal

End Function
'====================

Regads,

Rob.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
TheCleanerAuthor Commented:
Thank you both very much...I see what you are doing there and will work on getting what I needed on a personal level.  I'll post back my final script as a comment for others in the future.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
VB Script

From novice to tech pro — start learning today.