Class: PuppetX::PuppetLabs::ScheduledTask::Task
- Inherits:
-
Object
- Object
- PuppetX::PuppetLabs::ScheduledTask::Task
- Defined in:
- lib/puppet_x/puppetlabs/scheduled_task/task.rb
Overview
Installs and manages Windows Scheduled Tasks.
Defined Under Namespace
Classes: TASK_ACTION_TYPE, TASK_COMPATIBILITY, TASK_CREATION, TASK_ENUM_FLAGS, TASK_INSTANCES_POLICY, TASK_LOGON_TYPE, TASK_PROCESSTOKENSID_TYPE, TASK_RUNLEVEL_TYPE, TASK_RUN_FLAGS, TASK_STATE
Constant Summary collapse
- ROOT_FOLDER =
The name of the root folder for tasks
'\\'
- V1_COMPATIBILITY =
API v1 Compatibility list
[ TASK_COMPATIBILITY::TASK_COMPATIBILITY_AT, TASK_COMPATIBILITY::TASK_COMPATIBILITY_V1, ].freeze
- V2_COMPATIBILITY =
API v2 Compatibility list
[ TASK_COMPATIBILITY::TASK_COMPATIBILITY_V2_4, TASK_COMPATIBILITY::TASK_COMPATIBILITY_V2_3, TASK_COMPATIBILITY::TASK_COMPATIBILITY_V2_2, TASK_COMPATIBILITY::TASK_COMPATIBILITY_V2_1, TASK_COMPATIBILITY::TASK_COMPATIBILITY_V2, TASK_COMPATIBILITY::TASK_COMPATIBILITY_AT, TASK_COMPATIBILITY::TASK_COMPATIBILITY_V1, ].freeze
- RESERVED_FOR_FUTURE_USE =
Reserved for furure use
0
Class Method Summary collapse
-
.create_folder(path) ⇒ Object
create_folder returns “S_OK” if created or an HRESULT error code.
-
.delete(task_name) ⇒ Object
Delete the specified task name.
-
.enum_task_names(folder_path = ROOT_FOLDER, enum_options = {}) ⇒ Object
Returns an array of scheduled task names.
-
.exists?(task_path) ⇒ Boolean
Returns whether or not the scheduled task exists.
-
.folder_path_from_task_path(task_path) ⇒ Object
Get task path folder.
-
.task(task_path) ⇒ Object
Gets the task with a specified task path.
-
.task_name_from_task_path(task_path) ⇒ Object
Get task name from task path.
-
.task_service ⇒ Object
:stopdoc:.
-
.tasks(compatibility = V2_COMPATIBILITY) ⇒ Object
Returns an array of scheduled task names.
Instance Method Summary collapse
-
#account_information ⇒ Object
Returns the user associated with the task or nil if no user has yet been associated with the task.
-
#action_at(index) ⇒ Object
Gets the action item with the specified index.
-
#append_trigger(manifest_hash) ⇒ Object
Appends a new trigger for the currently active task.
-
#application_name ⇒ Object
Returns the name of the application associated with the task.
-
#application_name=(app) ⇒ Object
Sets the application name associated with the task.
-
#clear_triggers ⇒ Object
Deletes all triggers.
-
#compatibility ⇒ Object
Gets task compatibility.
-
#compatibility=(value) ⇒ Object
Sets task compatibility.
-
#default_action(options = {}) ⇒ Object
Find the first TASK_ACTION_EXEC action.
-
#delete_trigger(index) ⇒ Object
Deletes the trigger at the specified index.
-
#enabled ⇒ Object
Checks if task is enabled.
-
#enabled=(value) ⇒ Object
Sets the enabled value.
-
#initialize(task_name, compatibility_level = nil) ⇒ Task
constructor
Returns a new TaskScheduler object.
-
#parameters ⇒ Object
Returns the command line parameters for the task.
-
#parameters=(param) ⇒ Object
Sets the parameters for the task.
-
#save ⇒ Object
Creates or Updates an existing task with the supplied task definition Tasks must be saved before they can be activated.
-
#set_account_information(user, password) ⇒ Object
Sets the
user
andpassword
for the given task. -
#trigger(index) ⇒ Object
Returns a hash that describes the trigger at the given index for the current task.
-
#trigger_at(index) ⇒ Object
Returns a Win32OLE Trigger Object for the trigger at the given index for the supplied definition.
-
#triggers ⇒ Object
Returns a set of trigger hashes with their indexes, for supported trigger types.
-
#working_directory ⇒ Object
Returns the working directory for the task.
-
#working_directory=(dir) ⇒ Object
Sets the working directory for the task.
Constructor Details
#initialize(task_name, compatibility_level = nil) ⇒ Task
Returns a new TaskScheduler object. An existing task named task_name will be returned if one exists, otherwise a new task is created by that name (but not yet saved to the system).
214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 214 def initialize(task_name, compatibility_level = nil) raise TypeError unless task_name.is_a?(String) @full_task_path = ROOT_FOLDER + task_name # definition populated when task exists, otherwise new @task, @definition = self.class.task(@full_task_path) task_userid = @definition.Principal.UserId || '' if compatibility_level == :v1_compatibility self.compatibility = TASK_COMPATIBILITY::TASK_COMPATIBILITY_V1 end set_account_information(task_userid, nil) end |
Class Method Details
.create_folder(path) ⇒ Object
create_folder returns “S_OK” if created or an HRESULT error code. It will create the full path specified, not just a the last child.
501 502 503 504 505 506 507 508 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 501 def self.create_folder(path) task_service.GetFolder(path) rescue WIN32OLERuntimeError => e unless Error.com_error_type?(e, Error::ERROR_FILE_NOT_FOUND) raise Puppet::Error.new(_('GetFolder failed with: %{error}') % { error: e }, e) end task_service.GetFolder(ROOT_FOLDER).CreateFolder(path) end |
.delete(task_name) ⇒ Object
Delete the specified task name.
305 306 307 308 309 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 305 def self.delete(task_name) task_path = ROOT_FOLDER + task_name task_folder = task_service.GetFolder(folder_path_from_task_path(task_path)) task_folder.DeleteTask(task_name_from_task_path(task_path), 0) end |
.enum_task_names(folder_path = ROOT_FOLDER, enum_options = {}) ⇒ Object
Returns an array of scheduled task names. By default EVERYTHING is enumerated option hash
include_child_folders: recurses into child folders for tasks. Default true
include_compatibility: Only include tasks which have any of the specified compatibility levels. Default empty array (everything is permitted)
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 265 def self.enum_task_names(folder_path = ROOT_FOLDER, = {}) raise TypeError unless folder_path.is_a?(String) = { include_child_folders: true, include_compatibility: [], }.merge() array = [] task_folder = task_service.GetFolder(folder_path) filter_compatibility = ![:include_compatibility].empty? task_folder.GetTasks(TASK_ENUM_FLAGS::TASK_ENUM_HIDDEN).each do |task| next if filter_compatibility && ![:include_compatibility].include?(task.Definition.Settings.Compatibility) array << task.Path end return array unless [:include_child_folders] task_folder.GetFolders(RESERVED_FOR_FUTURE_USE).each do |child_folder| array += enum_task_names(child_folder.Path, ) end array end |
.exists?(task_path) ⇒ Boolean
Returns whether or not the scheduled task exists.
291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 291 def self.exists?(task_path) raise TypeError unless task_path.is_a?(String) begin task_folder = task_service.GetFolder(folder_path_from_task_path(task_path)) # https://msdn.microsoft.com/en-us/library/windows/desktop/aa381363(v=vs.85).aspx _task = task_folder.GetTask(task_name_from_task_path(task_path)) rescue return false end true end |
.folder_path_from_task_path(task_path) ⇒ Object
Get task path folder
493 494 495 496 497 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 493 def self.folder_path_from_task_path(task_path) path = task_path.rpartition('\\')[0] path.empty? ? ROOT_FOLDER : path end |
.task(task_path) ⇒ Object
Gets the task with a specified task path
511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 511 def self.task(task_path) raise TypeError unless task_path.is_a?(String) service = task_service begin task_folder = service.GetFolder(folder_path_from_task_path(task_path)) # https://msdn.microsoft.com/en-us/library/windows/desktop/aa381363(v=vs.85).aspx task = task_folder.GetTask(task_name_from_task_path(task_path)) return task, task.Definition rescue WIN32OLERuntimeError => e unless Error.com_error_type?(e, Error::ERROR_FILE_NOT_FOUND) raise Puppet::Error.new(_('GetTask failed with: %{error}') % { error: e }, e) end end [nil, service.NewTask(0)] end |
.task_name_from_task_path(task_path) ⇒ Object
Get task name from task path
488 489 490 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 488 def self.task_name_from_task_path(task_path) task_path.rpartition('\\')[2] end |
.task_service ⇒ Object
:stopdoc:
478 479 480 481 482 483 484 485 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 478 def self.task_service return @service unless @service.nil? @service = WIN32OLE.new('Schedule.Service') @service.connect @service end |
.tasks(compatibility = V2_COMPATIBILITY) ⇒ Object
Returns an array of scheduled task names.
248 249 250 251 252 253 254 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 248 def self.tasks(compatibility = V2_COMPATIBILITY) enum_task_names(ROOT_FOLDER, include_child_folders: true, include_compatibility: compatibility).map do |item| item.partition('\\')[2] end end |
Instance Method Details
#account_information ⇒ Object
Returns the user associated with the task or nil if no user has yet been associated with the task.
375 376 377 378 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 375 def account_information principal = @definition.Principal principal.nil? ? nil : principal.UserId end |
#action_at(index) ⇒ Object
Gets the action item with the specified index
545 546 547 548 549 550 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 545 def action_at(index) @definition.Actions.Item(index) rescue WIN32OLERuntimeError => err raise unless Error.com_error_type?(err, Error::E_INVALIDARG) nil end |
#append_trigger(manifest_hash) ⇒ Object
Appends a new trigger for the currently active task.
463 464 465 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 463 def append_trigger(manifest_hash) Trigger::V2.append_trigger(@definition, manifest_hash) end |
#application_name ⇒ Object
Returns the name of the application associated with the task.
382 383 384 385 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 382 def application_name action = default_action(create_if_missing: false) action.nil? ? nil : action.Path end |
#application_name=(app) ⇒ Object
Sets the application name associated with the task.
389 390 391 392 393 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 389 def application_name=(app) action = default_action(create_if_missing: true) action.Path = app app end |
#clear_triggers ⇒ Object
Deletes all triggers
457 458 459 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 457 def clear_triggers @definition.Triggers.Clear() end |
#compatibility ⇒ Object
Gets task compatibility
428 429 430 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 428 def compatibility @definition.Settings.Compatibility end |
#compatibility=(value) ⇒ Object
Sets task compatibility
433 434 435 436 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 433 def compatibility=(value) # https://msdn.microsoft.com/en-us/library/windows/desktop/aa381846(v=vs.85).aspx @definition.Settings.Compatibility = value end |
#default_action(options = {}) ⇒ Object
Find the first TASK_ACTION_EXEC action
529 530 531 532 533 534 535 536 537 538 539 540 541 542 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 529 def default_action( = {}) action = nil (1..@definition.Actions.count).each do |i| index_action = action_at(i) action = index_action if index_action.Type == TASK_ACTION_TYPE::TASK_ACTION_EXEC break if action end if action.nil? && .fetch(:create_if_missing, false) action = @definition.Actions.Create(TASK_ACTION_TYPE::TASK_ACTION_EXEC) end action end |
#delete_trigger(index) ⇒ Object
Deletes the trigger at the specified index.
447 448 449 450 451 452 453 454 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 447 def delete_trigger(index) # The older V1 API uses a starting index of zero, wherease the V2 API uses one. # Need to increment by one to maintain the same behavior index += 1 @definition.Triggers.Remove(index) index end |
#enabled ⇒ Object
Checks if task is enabled
468 469 470 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 468 def enabled @definition.Settings.Enabled end |
#enabled=(value) ⇒ Object
Sets the enabled value
473 474 475 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 473 def enabled=(value) @definition.Settings.Enabled = value end |
#parameters ⇒ Object
Returns the command line parameters for the task.
397 398 399 400 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 397 def parameters action = default_action(create_if_missing: false) action.nil? ? nil : action.Arguments end |
#parameters=(param) ⇒ Object
Sets the parameters for the task. These parameters are passed as command line arguments to the application the task will run. To clear the command line parameters set it to an empty string.
406 407 408 409 410 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 406 def parameters=(param) action = default_action(create_if_missing: true) action.Arguments = param param end |
#save ⇒ Object
Creates or Updates an existing task with the supplied task definition Tasks must be saved before they can be activated.
The .job file itself is typically stored in the C:WINDOWSTasks folder.
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 315 def save task_path = @task ? @task.Path : @full_task_path self.class.create_folder(self.class.folder_path_from_task_path(task_path)) task_folder = self.class.task_service.GetFolder(self.class.folder_path_from_task_path(task_path)) task_user = nil task_password = nil case @definition.Principal.LogonType when TASK_LOGON_TYPE::TASK_LOGON_PASSWORD, TASK_LOGON_TYPE::TASK_LOGON_INTERACTIVE_TOKEN_OR_PASSWORD task_user = @definition.Principal.UserId task_password = @task_password end saved = task_folder.RegisterTaskDefinition( self.class.task_name_from_task_path(task_path), @definition, TASK_CREATION::TASK_CREATE_OR_UPDATE, task_user, task_password, @definition.Principal.LogonType ) @task ||= saved end |
#set_account_information(user, password) ⇒ Object
Sets the user
and password
for the given task. If the user and password are set properly then true is returned.
In some cases the job may be created, but the account information was bad. In this case the task is created but a warning is generated and false is returned.
Note that if intending to use SYSTEM, specify an empty user and nil password
This must be done prior to the 1st save() call for the task to be properly registered and visible through the MMC snap-in / schtasks.exe
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 352 def set_account_information(user, password) @task_password = password @definition.Principal.RunLevel = TASK_RUNLEVEL_TYPE::TASK_RUNLEVEL_HIGHEST if user.nil? || user == '' # Setup for the local system account @definition.Principal.UserId = 'SYSTEM' @definition.Principal.LogonType = TASK_LOGON_TYPE::TASK_LOGON_SERVICE_ACCOUNT else @definition.Principal.UserId = user @definition.Principal.LogonType = if @task_password || user[-1] == '$' TASK_LOGON_TYPE::TASK_LOGON_PASSWORD else TASK_LOGON_TYPE::TASK_LOGON_INTERACTIVE_TOKEN end end true end |
#trigger(index) ⇒ Object
Returns a hash that describes the trigger at the given index for the current task.
569 570 571 572 573 574 575 576 577 578 579 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 569 def trigger(index) # The older V1 API uses a starting index of zero, wherease the V2 API uses one. # Need to increment by one to maintain the same behavior trigger_object = trigger_at(index + 1) if trigger_object.nil? || Trigger::V2::TYPE_MANIFEST_MAP[trigger_object.Type].nil? # nil trigger definitions are unsupported ITrigger types nil else Trigger::V2.to_manifest_hash(trigger_object).merge!('index' => index) end end |
#trigger_at(index) ⇒ Object
Returns a Win32OLE Trigger Object for the trigger at the given index for the supplied definition.
Returns nil if the index does not exist
Note - This is a 1 based array (not zero)
559 560 561 562 563 564 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 559 def trigger_at(index) @definition.Triggers.Item(index) rescue WIN32OLERuntimeError => err raise unless Error.com_error_type?(err, Error::E_INVALIDARG) nil end |
#triggers ⇒ Object
Returns a set of trigger hashes with their indexes, for supported trigger types. Returns nil for each unknown trigger types in the collection.
441 442 443 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 441 def triggers Array.new(@definition.Triggers.count) { |i| trigger(i) } end |
#working_directory ⇒ Object
Returns the working directory for the task.
414 415 416 417 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 414 def working_directory action = default_action(create_if_missing: false) action.nil? ? nil : action.WorkingDirectory end |
#working_directory=(dir) ⇒ Object
Sets the working directory for the task.
421 422 423 424 425 |
# File 'lib/puppet_x/puppetlabs/scheduled_task/task.rb', line 421 def working_directory=(dir) action = default_action(create_if_missing: false) action.WorkingDirectory = dir dir end |