Announcement

Collapse
No announcement yet.

How to use script parameters...

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to use script parameters...

    Hi, guys.
    I wrote this script, to stop and disable a service on computers in my network. I want that the service's name will be taken from the command line that runs the script.
    How do I do that? Somehow couldn't find it. Microsoft only says it's possible
    And I would like to hear what do you think of the script (my first one, more complicated than copying files from here to there).

    TIA

    Code:
    '   This script checks the status of a service on a computer and
    ' if it's running, it will be stopped and disabled.
    ' The script logs the status of the service.
    ' The script checks that the computername shows in the log file and if not,
    ' the script will run (to avoid running all the time).
    
    
    On Error Resume Next
    
    Const FOR_READING = 1        ' To open a file for reading
    Const FOR_WRITING = 2        ' To open a file for writing
    Const FOR_APPENDING = 8      ' To open a file for adding
    Const CREATE_FILE = "True"   ' Create the file if it does not exist
    
    strFile = "\\[server]\[share]\service.stopped.txt"  ' The log file
    
    Set objComputer = CreateObject("Shell.LocalMachine")
    computerName = objComputer.MachineName    ' Now I have the computer's name
    
    '  If the file does not exist,  it will be created and an empty line will
    ' be inserted
    
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    If Not objFSO.FileExists(strFile) Then
      Set objFile = objFSO.CreateTextFile (strFile)
      Set objFile = objFSO.OpenTextFile (strFile, FOR_APPENDING)
      objFile.WriteLine "."
      objFile.Close
    End If
    
    
    '  Check if the computer already shows in the log file. If not, runs the script.
    
    Set objTextStream = objFSO.OpenTextFile _
     (strFile, FOR_READING)
     logContents = objTextStream.ReadAll
    
    If (InStr(logContents, computerName) = 0) Then    ' the computer was not found
      Set objFile = objFSO.OpenTextFile _
        (strFile, FOR_APPENDING)
    
      Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
      Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Service" & _
        " WHERE Name='Dhcp'")
    
      For Each objItem In colItems
        If objItem.State = "Running" Then
          objItem.StopService()
          objItem.ChangeStartMode("Disabled")
          objFile.WriteLine computerName & " @ " & Now & _
              " : The " & objItem.Name & " service is now stopped and disabled."
        Else
          objFile.WriteLine computerName & " @ " & Now &  _
             " : " & " The " & objItem.Name & " service wasn't running."
        End If
      Next  ' Next Service
    
    End If
    
    objTextStream.Close
    
    objFile.Close

    Sorin Solomon


    In order to succeed, your desire for success should be greater than your fear of failure.
    -

  • #2
    Re: How to use script parameters...

    Example here:

    http://cis.stvincent.edu/html/tutorials/wsh/args.html

    It was the third result in a google search of "vbs command line parameters"
    Server 2000 MCP
    Development: ASP, ASP.Net, PHP, VB, VB.Net, MySQL, MSSQL - Check out my blog http://tonyyeb.blogspot.com

    ** Remember to give credit where credit is due and leave reputation points sigpic where appropriate **

    Comment


    • #3
      Re: How to use script parameters...

      10nx
      I searched another (alightly different) string, and only in Microsoft's reference.

      Sorin Solomon


      In order to succeed, your desire for success should be greater than your fear of failure.
      -

      Comment


      • #4
        Re: How to use script parameters...

        Originally posted by sorinso View Post
        10nx
        I searched another (alightly different) string, and only in Microsoft's reference.
        No probs!
        Server 2000 MCP
        Development: ASP, ASP.Net, PHP, VB, VB.Net, MySQL, MSSQL - Check out my blog http://tonyyeb.blogspot.com

        ** Remember to give credit where credit is due and leave reputation points sigpic where appropriate **

        Comment


        • #5
          Re: How to use script parameters...

          It is a nice script

          Now you planned to use script arguments you have to modify the script, so it can work with parameters.
          If you are running this script with a computer GPO, you can put the parameters at the scriptparameters bar in the GPO

          The part I personaly would change* in your script is the reading for computername from logfile. Better is to read the last written "state", so you would be able later-on to change setting with the same script if needed. (but then you have to separate logfiles per computer though. EDIT: But do keep in mind that the logfile can only be opened for appending or for writing by just one computer and one event the same time!)

          example:
          Code:
          '// This script checks the status of a service on a computer and
          '// if it's running, it will be stopped and disabled.
          '// The script logs the status of the service.
          '// The script checks that the computername shows in the log file and if not,
          '// the script will run (to avoid running all the time).
          
          
          strService      = "Dhcp"      '<---ServiceName will be Added by command-line
          sNextState      = "Stopped"   '<---Values are: "Stopped" or "Running"
          sNextStartMode  = "Disabled" '<---Values are: "Disabled", "Manual", "Automatic", "System" or "Boot"
          
          Set objComputer = CreateObject("Shell.LocalMachine")  'Get the name of this computer;
          strComputer     = objComputer.MachineName 
          
          strLogFile      = "\\[server]\[share]\service("&strComputer&")log.txt"  ' The output file,"per computer" this time, <- needed for the checking method I used in this example (just for the idea)
          
          Const FOR_READING   = 1      ' To open a file for reading
          Const FOR_WRITING   = 2      ' To open a file for writing
          Const FOR_APPENDING = 8      ' To open a file for adding
          Const CREATE_FILE   = "True" ' Create the file if it does not exist
          
          'Naming correction
          logStartMode = sNextStartMode  'But if...
          If sNextStartMode = "Automatic" then logStartMode = "Auto"
          
          Set objFSO = CreateObject("Scripting.FileSystemObject")
          
          '// If the logfile does not exist, it will be created and an empty line will
          '// be inserted. And if the logfile do exist, it reads the last_state from it. 
          
               If Not objFSO.FileExists(strLogFile) Then
                  Set objFile = objFSO.CreateTextFile(strLogFile)
                  'Set objFile = objFSO.OpenTextFile(strLogFile, FOR_WRITING)
                  'objFile.WriteLine vbCr 'new empty line (or: vbCrLf & "this text on new line")
                  objFile.Close
                          logContents = Null
               Else
                  'On Error Resume Next
                  'logContents = objFSO.OpenTextFile(strLogFile).ReadAll
                  'On Error GoTo 0
                '*** Read only the last, not_empty, line of the log file
                Set objFile = objFSO.OpenTextFile(strLogFile, FOR_READING)
                    Do Until objFile.AtEndOfStream
                       strNextLine = objFile.ReadLine
                       If Len(strNextLine) > 0 Then
                          logContents = strNextLine
                       End If
                    Loop
                 objFile.Close
               End If
          
          '// open the log file for appending, 
          '// first reads its content as a routine Check wether the script already
          '// has stopped the service on this computer. If not, change the running service.
          
          '*** Check the last state written by this script to the logfile
          If InStr(UCase(logContents), UCase _
          ("service is "&sNextState&" and startup type is "&logStartMode))=0 then
             Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
             Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Service " _
                            & "WHERE Name= '"& strService &"'")
          
                 For Each objItem In colItems
                     If UCase(sNextState) = "RUNNING" Then objItem.StartService()
                     If UCase(sNextState) = "STOPPED" Then objItem.StopService()
                     objItem.ChangeStartMode(sNextStartMode)
                     exit For  '<-- there can be no other service with the same name.
                 Next  'or continue finding the right Service
          
          '// Now check the new current_state and write to log
             On Error Resume Next
             WScript.Sleep 1111  '<--- hold-on while service is stopping (milisecs)
             Set objFile = objFSO.OpenTextFile(strLogFile, FOR_APPENDING)
          
             For Each objItem In colItems
                 objFile.WriteLine strComputer & " @ " & Now & _
                   " : The " & objItem.Name & " service is " & _
                   objItem.State & " and startup type is " & objItem.StartMode
                 exit For
             Next
             On Error GoTo 0
             objFile.Close
          End If
          
          Set colItems = Nothing
          wscript.quit
          But even better and more reliable would be if you let the script perform a quick pre-check on the actual service settings if they matches the parameters then Quit, If not then continue the script to change settings and add changes to logfile. (and now there is no need to create separate logfiles any more, like my other suggestion). Besites the flexibility advantages these changes can give, I also think the second option can even make the script run faster because I expect that checking the actual state will be quicker that opening and searching the log file.

          - - - - - -
          With script parameters you can controle the variables "strService", "sNextState" and "sNextStartMode" (names I used in the example).
          There are to ways you can use script arguments,
          w/out switches -=or=- w/ switches (named arguments)
          Without the switches it works the same as commandline_variables for batchfiles, the order you put the parameters is very important

          With the switches you have more flexibility to use parameters.
          If you like to use switches, then these are the lines you can use in the script:

          Code:
          'Run with command-line switches !
          '--------------------------------
          '   ScriptName.vbs /s: /r: /m:
          '--------------------------------
          '  /s: = ServiceName
          '  /r: = NextState    (Values are: "Stopped" or "Running")
          '  /m: = NextMode   (Values are: "Disabled", "Manual", "Automatic", "System" or "Boot")
          'e.g.  ScriptName.vbs /s:ServiceName /r:NextState /m:NextMode 
          
          
          'Reading the arguments
          '------------------------------------------------------
          strService           = Null
          sNextState         = Null
          sNextStartMode = Null
           Set Named = WScript.Arguments.Named
           If Named.Exists("s") Then
              strService = Named.Item("s")
           Else
             wscript.echo "You must at leased provide a name of the /s:ServiceName and one option, to run this script"
             wscript.quit
           End If
           If Named.Exists("r") Then sNextState  = Named.Item("r")
           If Named.Exists("m") Then sNextStartMode = Named.Item("m")
          *If you don't use all the parameters, nomally that would be no problem,
          but it will if you use this part of the script I added;
          '*** Check the last state written by this script to the logfile <....lines 57 and 58...>
          But If you instead just checking the computername like you did, or perform a quick pre-check of the current state, that will avoid an unnessesary grow of the logfile in this case.

          \Rems
          Last edited by Rems; 28th March 2007, 16:26. Reason: correct some typos, added colors, note:about.the.If.Then.conditions.I.introduced

          This posting is provided "AS IS" with no warranties, and confers no rights.

          __________________

          ** Remember to give credit where credit's due **
          and leave Reputation Points for meaningful posts

          Comment


          • #6
            Re: How to use script parameters...

            10nx for your feedback, Rems. It is most important for me, this is the way to learn new things.
            The check on the log file comes to solve the issue of running the logon script more than once, generally speaking. In this case, we're talking about a service, that's why is easy to check its present state and change it if need it. But when we are talking about something else, it might be a problem. I saw here in the forum people writing files on the disk or keys in the registry to assure running only once.
            Anyway, I will thoroughly study your script. I will probably have more questions.
            Thanks for your help.

            Sorin Solomon


            In order to succeed, your desire for success should be greater than your fear of failure.
            -

            Comment


            • #7
              Re: How to use script parameters...

              Originally posted by sorinso View Post
              In this case, we're talking about a service, that's why is easy to check its present state and change it if need it.
              But when we are talking about something else, it might be a problem. I saw here in the forum people writing files on the disk or keys in the registry to assure running only once.
              Yes services are easy to check for a script.
              (btw the "startup type" of services can also be managed by GPO).

              I liked the idea though of using a central log that records all wat is changed by specific adminstrative-scripts (in this case it was managing services) on the computer.
              And, if you want to use that log-file the same time as an indicator for a script whether it has or hasn't already runned once on the computer it needs someting extra.

              So lets stick to that idea creating one central log for different administrative-scripts for a while.
              The most reliable way would be one logfile per computer, because a logfile can only be in-use by one computer the time.
              And then it properly is better to store the logfile on the computer it self.
              That can all be written in the script. Then there are two things left to accomplish;
              1. Not every kind of script can check a 'state' to determine whether it has runned already. So we need an indicator.
              2. If the log is stored on the local computer then it is central for all script events on one computer, but it is not together with logs from all the computers.

              A solution for 2. can be..
              the script could, besites writing in the local logfile, also copy the entire log to a share when it has written someting to the log. It will overwrite the previous saved log. On that share there are ways how you can later on merge the logs from all the computers together if desired.
              But copying to the share is optional, not realy needed if you do not personally want to check the logs. You always could run a script then that can read a log on a remote computer.

              The solution for 1.
              you mensioned that answer already.
              - give every script a code# (or determine the unique name of the script and use that as a 'code').
              When the script runs on the computer, it will first seach the logfile if there is already a line starting with this unique code#. If exist Then the script Quits.
              If Not exists Then it will do its thing... and afterwards it writes -the event (completely between "quotes"), -the computername, -the script code# and -date in a certain order to one new line in the logfile.
              (Each line in the log must have the same lay-out (containing always the same set of types of values in always the same order. That will make the file a usable csv-file), which is nessesary if you want the possibility to import or merge the file).

              For protecting the log file you could store it in a specialy created folder in the %SystemRoot%. The logfile can only be edited by scripts runned as computer start-up script or by an administrator.


              So here are all the extra administrative features you have to add everytime to each administrative-script:
              - if not exist create the folder and logfile,
              - handle the code#
              - get results and write lines
              - copying the log to a share (when needed)
              For writing such script there is not much difference between the options; writing the runones-indicators by all the scripts in one and the same logfile, or, place 'markers' somewhere in separate files or as registrykeys on the computer. You still have to consider the features above when writing an administrative-script.

              Like in this link, a good place for that particular marker is properly to attach it to its 'purpose', but that is not always possible for every kind of process.
              Or.. it can have bennefits for an administrator if all markers are written to a central logfile on the computer.


              \Rem

              tip
              It is recommended to always use 'On Error resume next' in scripts that opens files for writing. Then add 'On Error goTo 0' just before the line that will close the file. That way if an error occur the script won't leave the file opend.

              This posting is provided "AS IS" with no warranties, and confers no rights.

              __________________

              ** Remember to give credit where credit's due **
              and leave Reputation Points for meaningful posts

              Comment

              Working...
              X