def run(opts = {})
      opts[:target] ||= '/'
      opts[:p1] ||= @parameters[:parameter4]
      opts[:p2] ||= @parameters[:parameter5]
      opts[:p3] ||= @parameters[:parameter6]
      opts[:p4] ||= @parameters[:parameter7]
      opts[:p5] ||= @parameters[:parameter8]
      opts[:p6] ||= @parameters[:parameter9]
      opts[:p7] ||= @parameters[:parameter10]
      opts[:p8] ||= @parameters[:parameter11]

      dp_mount_pt = nil
      delete_exec = false

      begin

        # do we have the code already? if so, save it out and make it executable
        if @script_contents && !@script_contents.empty?

          script_path = JSS::Client::DOWNLOADS_FOLDER

          executable = script_path + @filename

          executable.jss_touch
          executable.chmod 0o700
          executable.jss_save @script_contents
          delete_exec = true

        # otherwise, get it from the dist. point
        else
          dist_point = JSS::DistributionPoint.my_distribution_point api: @api

          ### how do we access our dist. point?
          if dist_point.http_downloads_enabled
            script_path = dist_point.http_url + "/#{DIST_POINT_SCRIPTS_FOLDER}/"

          else
            dp_mount_pt = dist_point.mount opts[:ro_pw]

            script_path = (dp_mount_pt + DIST_POINT_SCRIPTS_FOLDER)

          end # if http enabled

        end # if @script_contents and (not @script_contents.empty?)

        # build the command as an array.
        command_arry = ['-script', @filename, '-path', script_path.to_s]

        command_arry << '-target'
        command_arry << opts[:target].to_s

        command_arry << '-computerName' if opts[:computer_name]
        command_arry << opts[:computer_name] if opts[:computer_name]

        command_arry << '-username' if opts[:username]
        command_arry << opts[:username] if opts[:username]

        command_arry << '-p1' if opts[:p1]
        command_arry << opts[:p1] if opts[:p1]

        command_arry << '-p2' if opts[:p2]
        command_arry << opts[:p2] if opts[:p2]

        command_arry << '-p3' if opts[:p3]
        command_arry << opts[:p3] if opts[:p3]

        command_arry << '-p4' if opts[:p4]
        command_arry << opts[:p4] if opts[:p4]

        command_arry << '-p5' if opts[:p5]
        command_arry << opts[:p5] if opts[:p5]

        command_arry << '-p6' if opts[:p6]
        command_arry << opts[:p6] if opts[:p6]

        command_arry << '-p7' if opts[:p7]
        command_arry << opts[:p7] if opts[:p7]

        command_arry << '-p8' if opts[:p8]
        command_arry << opts[:p8] if opts[:p8]

        command_arry << '-verbose' if opts[:verbose]

        command = command_arry.shelljoin

        jamf_output =  JSS::Client.run_jamf 'runScript', command, opts[:show_output]

        jamf_output =~ /^.*Script exit code: (\d+)(\D|$)/

        script_exitstatus = Regexp.last_match(1).to_i

      ensure
        executable.delete if delete_exec && executable.exist?
        dist_point.unmount if dp_mount_pt && dp_mount_pt.mountpoint? && opts[:unmount]
      end # begin/ensure

      [script_exitstatus, jamf_output]
    end
def run(opts = {})
      opts[:target] ||= '/'
      opts[:p1] ||= @parameters[:parameter4]
      opts[:p2] ||= @parameters[:parameter5]
      opts[:p3] ||= @parameters[:parameter6]
      opts[:p4] ||= @parameters[:parameter7]
      opts[:p5] ||= @parameters[:parameter8]
      opts[:p6] ||= @parameters[:parameter9]
      opts[:p7] ||= @parameters[:parameter10]
      opts[:p8] ||= @parameters[:parameter11]

      dp_mount_pt = nil
      delete_exec = false

      begin

        # do we have the code already? if so, save it out and make it executable
        if @script_contents && !@script_contents.empty?

          script_path = JSS::Client::DOWNLOADS_FOLDER

          executable = script_path + @filename

          executable.jss_touch
          executable.chmod 0o700
          executable.jss_save @script_contents
          delete_exec = true

        # otherwise, get it from the dist. point
        else
          dist_point = JSS::DistributionPoint.my_distribution_point api: @api

          ### how do we access our dist. point?
          if dist_point.http_downloads_enabled
            script_path = dist_point.http_url + "/#{DIST_POINT_SCRIPTS_FOLDER}/"

          else
            dp_mount_pt = dist_point.mount opts[:ro_pw]

            script_path = (dp_mount_pt + DIST_POINT_SCRIPTS_FOLDER)

          end # if http enabled

        end # if @script_contents and (not @script_contents.empty?)

        # build the command as an array.
        command_arry = ['-script', @filename, '-path', script_path.to_s]

        command_arry << '-target'
        command_arry << opts[:target].to_s

        command_arry << '-computerName' if opts[:computer_name]
        command_arry << opts[:computer_name] if opts[:computer_name]

        command_arry << '-username' if opts[:username]
        command_arry << opts[:username] if opts[:username]

        command_arry << '-p1' if opts[:p1]
        command_arry << opts[:p1] if opts[:p1]

        command_arry << '-p2' if opts[:p2]
        command_arry << opts[:p2] if opts[:p2]

        command_arry << '-p3' if opts[:p3]
        command_arry << opts[:p3] if opts[:p3]

        command_arry << '-p4' if opts[:p4]
        command_arry << opts[:p4] if opts[:p4]

        command_arry << '-p5' if opts[:p5]
        command_arry << opts[:p5] if opts[:p5]

        command_arry << '-p6' if opts[:p6]
        command_arry << opts[:p6] if opts[:p6]

        command_arry << '-p7' if opts[:p7]
        command_arry << opts[:p7] if opts[:p7]

        command_arry << '-p8' if opts[:p8]
        command_arry << opts[:p8] if opts[:p8]

        command_arry << '-verbose' if opts[:verbose]

        command = command_arry.shelljoin

        jamf_output =  JSS::Client.run_jamf 'runScript', command, opts[:show_output]

        jamf_output =~ /^.*Script exit code: (\d+)(\D|$)/

        script_exitstatus = Regexp.last_match(1).to_i

      ensure
        executable.delete if delete_exec && executable.exist?
        dist_point.unmount if dp_mount_pt && dp_mount_pt.mountpoint? && opts[:unmount]
      end # begin/ensure

      [script_exitstatus, jamf_output]
    end
Run this script on the current machine using the "jamf runScript" command.

 If the script code is available in the {#script_contents} attribute, then that
 code is saved to a tmp file, and executed. Otherwise, the script is assumed
 to be stored on the distribution point.

 If the dist. point has http downloads enabled, then the URL is used as the path with the
 'jamf runScript' command.

 If http is not an option, the dist.point is mounted, and the script copied locally before running.
 In this case the options must include :ro_pw => 'somepass'
 to provide the read-only password for mounting the distribution point. If :unmount => true
 is provided, the dist. point will be unmounted immediately after copying
 the script locally.  Otherwise it will remain mounted, in case there's further need of it.

 Any local on-disk copies of the script are removed after running.

 After the script runs, this method returns a two-item Array.
 - the first item is an Integer, the exit status of the script itself (0 means success)
 - the second item is a String, the output (stdout + stderr) of the jamf binary, which will include
   the script output.
 The exit status of the jamf binary process will be available as a Process::Status object
 in $? immediately after running.

 @param opts[Hash] the options for running the script

 @option opts :target[String,Pathname] the 'target drive', passed to the script as the first commandline option.
   Defaults to '/'

 @option opts :computer_name[String] the name of the computer, passed to the script as the second commandline
   option. Defaults to the name of the current machine

 @option opts :username[String] the username to be passed to the script as the third commandline option.

 @option opts :p1..:p8[String] the values to be passed as the 4th - 11th commandline options, overriding
   those defined with the script in the JSS

 @option opts :ro_pw[String] the read-only password for mounting the distribution point, if needed

 @option opts :unmount[Boolean} should the dist. point be unmounted when finished, if we mounted it?

 @option opts :verbose[Boolean] should the 'jamf runScript' command be verbose?

 @option opts :show_output[Boolean] should the output (stdout + stderr) of 'jamf runScript' be copied to
  stdout in realtime, as well as returned?

 @return [Array<(Integer,String)>] the exit status of the *script* and stdout+stderr of 'jamf runScript'.
   The exit status of the jamf binary will be available in $? immediately after running.

 *NOTE* In the WEB UI and API, the definable parameters are numbered 4-11, since 1, 2, & 3 are the
 target drive, computer name, and user name respectively.  However, the jamf binary refers to them as
 p1-p8, and that's how they are expected as options to #run. So if :p1=> "new param" is given as an
 aption to #run, it will override any value that the API provided in @parameters[:parameter4]