Merge pull request #1136 from PowerShell/vors/scheduledjobs

PSScheduledJobs Module
This commit is contained in:
Sergei Vorobev 2016-06-17 11:26:24 -07:00 committed by GitHub
commit 299d7798ce
50 changed files with 12462 additions and 38 deletions

View File

@ -873,25 +873,22 @@ function Start-ResGen
[CmdletBinding()]
param()
@("Microsoft.PowerShell.Commands.Management",
"Microsoft.PowerShell.Commands.Utility",
"Microsoft.PowerShell.ConsoleHost",
"Microsoft.PowerShell.CoreCLR.Eventing",
"Microsoft.PowerShell.LocalAccounts",
"Microsoft.PowerShell.Security",
"System.Management.Automation") | % {
$module = $_
Get-ChildItem "$PSScriptRoot/src/$module/resources" -Filter '*.resx' | % {
$className = $_.Name.Replace('.resx', '')
$xml = [xml](Get-Content -raw $_.FullName)
Get-ChildItem $PSScriptRoot/src -Directory | ? {
Get-ChildItem (Join-Path $_.FullName 'resources') -ErrorAction SilentlyContinue} | % {
$_. Name} | % {
$fileName = $className
$genSource = Get-StronglyTypeCsFileForResx -xml $xml -ModuleName $module -ClassName $className
$outPath = "$PSScriptRoot/src/$module/gen/$fileName.cs"
Write-Verbose "ResGen for $outPath"
New-Item -Type Directory -ErrorAction SilentlyContinue (Split-Path $outPath) > $null
Set-Content -Encoding Ascii -Path $outPath -Value $genSource
}
$module = $_
Get-ChildItem "$PSScriptRoot/src/$module/resources" -Filter '*.resx' | % {
$className = $_.Name.Replace('.resx', '')
$xml = [xml](Get-Content -raw $_.FullName)
$fileName = $className
$genSource = Get-StronglyTypeCsFileForResx -xml $xml -ModuleName $module -ClassName $className
$outPath = "$PSScriptRoot/src/$module/gen/$fileName.cs"
Write-Verbose "ResGen for $outPath"
New-Item -Type Directory -ErrorAction SilentlyContinue (Split-Path $outPath) > $null
Set-Content -Encoding Ascii -Path $outPath -Value $genSource
}
}
}

View File

@ -1,10 +1,6 @@
{
"name": "Microsoft.PowerShell.Commands.Diagnostics",
"version": "1.0.0-*",
"authors": [
"cchen",
"sevoroby"
],
"buildOptions": {
"keyFile": "../signing/visualstudiopublic.snk",
"delaySign": true,

View File

@ -1,7 +1,6 @@
{
"name": "Microsoft.PowerShell.Commands.Management",
"version": "1.0.0-*",
"authors": [ "garretts", "andschwa" ],
"buildOptions": {
"keyFile": "../signing/visualstudiopublic.snk",

View File

@ -1,7 +1,6 @@
{
"name": "Microsoft.PowerShell.Commands.Utility",
"version": "1.0.0-*",
"authors": [ "garretts", "andschwa" ],
"buildOptions": {
"keyFile": "../signing/visualstudiopublic.snk",

View File

@ -0,0 +1,33 @@
@{
ModuleToProcess = 'Microsoft.PowerShell.ScheduledJob.dll'
ModuleVersion = '1.1.0.0'
GUID = '50cdb55f-5ab7-489f-9e94-4ec21ff51e59'
Author = 'Microsoft Corporation'
CompanyName = 'Microsoft Corporation'
Copyright = '© Microsoft Corporation. All rights reserved.'
PowerShellVersion = '3.0'
CLRVersion = '4.0'
TypesToProcess = 'PSScheduledJob.types.ps1xml'
FormatsToProcess="PSScheduledJob.Format.ps1xml"
CmdletsToExport = 'New-JobTrigger', 'Add-JobTrigger', 'Remove-JobTrigger',
'Get-JobTrigger', 'Set-JobTrigger', 'Enable-JobTrigger',
'Disable-JobTrigger', 'New-ScheduledJobOption', 'Get-ScheduledJobOption',
'Set-ScheduledJobOption', 'Register-ScheduledJob', 'Get-ScheduledJob',
'Set-ScheduledJob', 'Unregister-ScheduledJob', 'Enable-ScheduledJob',
'Disable-ScheduledJob'
AliasesToExport = @()
FunctionsToExport = @()
HelpInfoURI = 'http://go.microsoft.com/fwlink/?linkid=390816'
}

View File

@ -32,5 +32,8 @@
"monad/miscfiles/modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1": "Modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1",
"monad/src/singleshell/installer/EngineInstaller.cs": "singleshell/installer/EngineInstaller.cs",
"monad/src/host/msh/ConsoleHostRawUserInterface.cs": "host/msh/ConsoleHostRawUserInterface.cs",
"monad/src/host/msh/ConsoleHost.cs": "host/msh/ConsoleHost.cs"
"monad/src/host/msh/ConsoleHost.cs": "host/msh/ConsoleHost.cs",
"monad/src/ScheduledJob/PSScheduledJob.Format.ps1xml": "Modules/PSScheduledJob/PSScheduledJob.Format.ps1xml",
"monad/src/ScheduledJob/PSScheduledJob.psd1": "Modules/PSScheduledJob/PSScheduledJob.psd1",
"monad/src/ScheduledJob/PSScheduledJob.types.ps1xml": "Modules/PSScheduledJob/PSScheduledJob.types.ps1xml"
}

View File

@ -2,7 +2,6 @@
"name": "Microsoft.PowerShell.ConsoleHost",
"version": "1.0.0-*",
"description": "PowerShell Host",
"authors": [ "sevoroby", "andschwa" ],
"buildOptions": {
"keyFile": "../signing/visualstudiopublic.snk",
@ -50,6 +49,9 @@
}
},
"net451": {
"dependencies" : {
"Microsoft.PowerShell.ScheduledJob": "1.0.0-*"
}
}
}
}

View File

@ -1,7 +1,6 @@
{
"name": "Microsoft.PowerShell.CoreCLR.AssemblyLoadContext",
"version": "1.0.0-*",
"authors": [ "andschwa" ],
"buildOptions": {
"keyFile": "../signing/visualstudiopublic.snk",

View File

@ -1,7 +1,6 @@
{
"name": "Microsoft.PowerShell.CoreCLR.Eventing",
"version": "1.0.0-*",
"authors": [ "sevoroby" ],
"buildOptions": {
"keyFile": "../signing/visualstudiopublic.snk",

View File

@ -1,7 +1,6 @@
{
"name": "Microsoft.PowerShell.LocalAccounts",
"version": "1.0.0-*",
"authors": [ "OPS" ],
"buildOptions": {
"keyFile": "../signing/visualstudiopublic.snk",

View File

@ -1,7 +1,6 @@
{
"name": "Microsoft.PowerShell.PSReadLine",
"version": "1.0.0-*",
"authors": [ "andschwa" ],
"buildOptions": {
"keyFile": "../signing/visualstudiopublic.snk",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,393 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Management.Automation;
using System.Security.Permissions;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This class contains Windows Task Scheduler options.
/// </summary>
[Serializable]
public sealed class ScheduledJobOptions : ISerializable
{
#region Private Members
// Power settings
private bool _startIfOnBatteries;
private bool _stopIfGoingOnBatteries;
private bool _wakeToRun;
// Idle settings
private bool _startIfNotIdle;
private bool _stopIfGoingOffIdle;
private bool _restartOnIdleResume;
private TimeSpan _idleDuration;
private TimeSpan _idleTimeout;
// Security settings
private bool _showInTaskScheduler;
private bool _runElevated;
// Misc
private bool _runWithoutNetwork;
private bool _donotAllowDemandStart;
private TaskMultipleInstancePolicy _multipleInstancePolicy;
// ScheduledJobDefinition object associated with this options object.
private ScheduledJobDefinition _jobDefAssociation;
#endregion
#region Public Properties
/// <summary>
/// Start task if on batteries.
/// </summary>
public bool StartIfOnBatteries
{
get { return _startIfOnBatteries; }
set { _startIfOnBatteries = value; }
}
/// <summary>
/// Stop task if computer is going on batteries.
/// </summary>
public bool StopIfGoingOnBatteries
{
get { return _stopIfGoingOnBatteries; }
set { _stopIfGoingOnBatteries = value; }
}
/// <summary>
/// Wake computer to run task.
/// </summary>
public bool WakeToRun
{
get { return _wakeToRun; }
set { _wakeToRun = value; }
}
/// <summary>
/// Start task only if computer is not idle.
/// </summary>
public bool StartIfNotIdle
{
get { return _startIfNotIdle; }
set { _startIfNotIdle = value; }
}
/// <summary>
/// Stop task if computer is no longer idle.
/// </summary>
public bool StopIfGoingOffIdle
{
get { return _stopIfGoingOffIdle; }
set { _stopIfGoingOffIdle = value; }
}
/// <summary>
/// Restart task on idle resuming.
/// </summary>
public bool RestartOnIdleResume
{
get { return _restartOnIdleResume; }
set { _restartOnIdleResume = value; }
}
/// <summary>
/// How long computer must be idle before task starts.
/// </summary>
public TimeSpan IdleDuration
{
get { return _idleDuration; }
set { _idleDuration = value; }
}
/// <summary>
/// How long task manager will wait for required idle duration.
/// </summary>
public TimeSpan IdleTimeout
{
get { return _idleTimeout; }
set { _idleTimeout = value; }
}
/// <summary>
/// When true task is not shown in Task Scheduler UI.
/// </summary>
public bool ShowInTaskScheduler
{
get { return _showInTaskScheduler; }
set { _showInTaskScheduler = value; }
}
/// <summary>
/// Run task with elevated privileges.
/// </summary>
public bool RunElevated
{
get { return _runElevated; }
set { _runElevated = value; }
}
/// <summary>
/// Run task even if network is not available.
/// </summary>
public bool RunWithoutNetwork
{
get { return _runWithoutNetwork; }
set { _runWithoutNetwork = value; }
}
/// <summary>
/// Do not allow a task to be started on demand.
/// </summary>
public bool DoNotAllowDemandStart
{
get { return _donotAllowDemandStart; }
set { _donotAllowDemandStart = value; }
}
/// <summary>
/// Multiple task instance policy.
/// </summary>
public TaskMultipleInstancePolicy MultipleInstancePolicy
{
get { return _multipleInstancePolicy; }
set { _multipleInstancePolicy = value; }
}
/// <summary>
/// ScheduledJobDefinition object associated with this options object.
/// </summary>
public ScheduledJobDefinition JobDefinition
{
get { return _jobDefAssociation; }
internal set { _jobDefAssociation = value; }
}
#endregion
#region Constructors
/// <summary>
/// Default constructor.
/// </summary>
public ScheduledJobOptions()
{
_startIfOnBatteries = false;
_stopIfGoingOnBatteries = true;
_wakeToRun = false;
_startIfNotIdle = true;
_stopIfGoingOffIdle = false;
_restartOnIdleResume = false;
_idleDuration = new TimeSpan(0, 10, 0);
_idleTimeout = new TimeSpan(1, 0, 0);
_showInTaskScheduler = true;
_runElevated = false;
_runWithoutNetwork = true;
_donotAllowDemandStart = false;
_multipleInstancePolicy = TaskMultipleInstancePolicy.IgnoreNew;
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="startIfOnBatteries"></param>
/// <param name="stopIfGoingOnBatters"></param>
/// <param name="wakeToRun"></param>
/// <param name="startIfNotIdle"></param>
/// <param name="stopIfGoingOffIdle"></param>
/// <param name="restartOnIdleResume"></param>
/// <param name="idleDuration"></param>
/// <param name="idleTimeout"></param>
/// <param name="showInTaskScheduler"></param>
/// <param name="runElevated"></param>
/// <param name="runWithoutNetwork"></param>
/// <param name="donotAllowDemandStart"></param>
/// <param name="multipleInstancePolicy"></param>
internal ScheduledJobOptions(
bool startIfOnBatteries,
bool stopIfGoingOnBatters,
bool wakeToRun,
bool startIfNotIdle,
bool stopIfGoingOffIdle,
bool restartOnIdleResume,
TimeSpan idleDuration,
TimeSpan idleTimeout,
bool showInTaskScheduler,
bool runElevated,
bool runWithoutNetwork,
bool donotAllowDemandStart,
TaskMultipleInstancePolicy multipleInstancePolicy)
{
_startIfOnBatteries = startIfOnBatteries;
_stopIfGoingOnBatteries = stopIfGoingOnBatters;
_wakeToRun = wakeToRun;
_startIfNotIdle = startIfNotIdle;
_stopIfGoingOffIdle = stopIfGoingOffIdle;
_restartOnIdleResume = restartOnIdleResume;
_idleDuration = idleDuration;
_idleTimeout = idleTimeout;
_showInTaskScheduler = showInTaskScheduler;
_runElevated = runElevated;
_runWithoutNetwork = runWithoutNetwork;
_donotAllowDemandStart = donotAllowDemandStart;
_multipleInstancePolicy = multipleInstancePolicy;
}
/// <summary>
/// Copy Constructor.
/// </summary>
/// <param name="copyOptions">Copy from</param>
internal ScheduledJobOptions(
ScheduledJobOptions copyOptions)
{
if (copyOptions == null)
{
throw new PSArgumentNullException("copyOptions");
}
_startIfOnBatteries = copyOptions.StartIfOnBatteries;
_stopIfGoingOnBatteries = copyOptions.StopIfGoingOnBatteries;
_wakeToRun = copyOptions.WakeToRun;
_startIfNotIdle = copyOptions.StartIfNotIdle;
_stopIfGoingOffIdle = copyOptions.StopIfGoingOffIdle;
_restartOnIdleResume = copyOptions.RestartOnIdleResume;
_idleDuration = copyOptions.IdleDuration;
_idleTimeout = copyOptions.IdleTimeout;
_showInTaskScheduler = copyOptions.ShowInTaskScheduler;
_runElevated = copyOptions.RunElevated;
_runWithoutNetwork = copyOptions.RunWithoutNetwork;
_donotAllowDemandStart = copyOptions.DoNotAllowDemandStart;
_multipleInstancePolicy = copyOptions.MultipleInstancePolicy;
_jobDefAssociation = copyOptions.JobDefinition;
}
#endregion
#region ISerializable Implementation
/// <summary>
/// Serialization constructor.
/// </summary>
/// <param name="info">SerializationInfo</param>
/// <param name="context">StreamingContext</param>
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
private ScheduledJobOptions(
SerializationInfo info,
StreamingContext context)
{
if (info == null)
{
throw new PSArgumentNullException("info");
}
_startIfOnBatteries = info.GetBoolean("StartIfOnBatteries_Value");
_stopIfGoingOnBatteries = info.GetBoolean("StopIfGoingOnBatteries_Value");
_wakeToRun = info.GetBoolean("WakeToRun_Value");
_startIfNotIdle = info.GetBoolean("StartIfNotIdle_Value");
_stopIfGoingOffIdle = info.GetBoolean("StopIfGoingOffIdle_Value");
_restartOnIdleResume = info.GetBoolean("RestartOnIdleResume_Value");
_idleDuration = (TimeSpan)info.GetValue("IdleDuration_Value", typeof(TimeSpan));
_idleTimeout = (TimeSpan)info.GetValue("IdleTimeout_Value", typeof(TimeSpan));
_showInTaskScheduler = info.GetBoolean("ShowInTaskScheduler_Value");
_runElevated = info.GetBoolean("RunElevated_Value");
_runWithoutNetwork = info.GetBoolean("RunWithoutNetwork_Value");
_donotAllowDemandStart = info.GetBoolean("DoNotAllowDemandStart_Value");
_multipleInstancePolicy = (TaskMultipleInstancePolicy)info.GetValue("TaskMultipleInstancePolicy_Value", typeof(TaskMultipleInstancePolicy));
// Runtime reference and not saved to store.
_jobDefAssociation = null;
}
/// <summary>
/// GetObjectData for ISerializable implementation.
/// </summary>
/// <param name="info">SerializationInfo</param>
/// <param name="context">StreamingContext</param>
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new PSArgumentNullException("info");
}
info.AddValue("StartIfOnBatteries_Value", _startIfOnBatteries);
info.AddValue("StopIfGoingOnBatteries_Value", _stopIfGoingOnBatteries);
info.AddValue("WakeToRun_Value", _wakeToRun);
info.AddValue("StartIfNotIdle_Value", _startIfNotIdle);
info.AddValue("StopIfGoingOffIdle_Value", _stopIfGoingOffIdle);
info.AddValue("RestartOnIdleResume_Value", _restartOnIdleResume);
info.AddValue("IdleDuration_Value", _idleDuration);
info.AddValue("IdleTimeout_Value", _idleTimeout);
info.AddValue("ShowInTaskScheduler_Value", _showInTaskScheduler);
info.AddValue("RunElevated_Value", _runElevated);
info.AddValue("RunWithoutNetwork_Value", _runWithoutNetwork);
info.AddValue("DoNotAllowDemandStart_Value", _donotAllowDemandStart);
info.AddValue("TaskMultipleInstancePolicy_Value", _multipleInstancePolicy);
}
#endregion
#region Public Methods
/// <summary>
/// Update the associated ScheduledJobDefinition object with the
/// current properties of this object.
/// </summary>
public void UpdateJobDefinition()
{
if (_jobDefAssociation == null)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.NoAssociatedJobDefinitionForOption);
throw new RuntimeException(msg);
}
_jobDefAssociation.UpdateOptions(this, true);
}
#endregion
}
#region Public Enums
/// <summary>
/// Enumerates Task Scheduler options for multiple instance polices of
/// scheduled tasks (jobs).
/// </summary>
public enum TaskMultipleInstancePolicy
{
/// <summary>
/// None
/// </summary>
None = 0,
/// <summary>
/// Ignore a new instance of the task (job)
/// </summary>
IgnoreNew = 1,
/// <summary>
/// Allow parallel running of a task (job)
/// </summary>
Parallel = 2,
/// <summary>
/// Queue up multiple instances of a task (job)
/// </summary>
Queue = 3,
/// <summary>
/// Stop currently running task (job) and start a new one
/// </summary>
StopExisting = 4
}
#endregion
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,673 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.IO;
using System.Globalization;
using System.Management.Automation;
using System.Security.AccessControl;
using System.Security.Principal;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This class encapsulates the work of determining the file location where
/// a job definition will be stored and retreived and where job runs will
/// be stored and retreived. Scheduled job definitions are stored in a
/// location based on the current user. Job runs are stored in the
/// corresponding scheduled job definition location under an "Output"
/// directory, where each run will have a subdirectory with a name derived
/// from the job run date/time.
///
/// File Structure for "JobDefinitionFoo":
/// $env:User\AppData\Local\Windows\PowerShell\ScheduledJobs\JobDefinitionFoo\
/// ScheduledJobDefinition.xml
/// Output\
/// 110321-130942\
/// Status.xml
/// Results.xml
/// 110319-173502\
/// Status.xml
/// Results.xml
/// ...
///
/// </summary>
internal class ScheduledJobStore
{
#region Public Enums
public enum JobRunItem
{
None = 0,
Status = 1,
Results = 2
}
#endregion
#region Public Strings
public const string ScheduledJobsPath = @"Microsoft\Windows\PowerShell\ScheduledJobs";
public const string DefinitionFileName = "ScheduledJobDefinition";
public const string JobRunOutput = "Output";
public const string ScheduledJobDefExistsFQEID = "ScheduledJobDefExists";
#endregion
#region Public Methods
/// <summary>
/// Returns FileStream object for existing scheduled job definition.
/// Definition file is looked for in the default user local appdata path.
/// </summary>
/// <param name="definitionName">Scheduled job definition name.</param>
/// <param name="fileMode">File mode.</param>
/// <param name="fileAccess">File access.</param>
/// <param name="fileShare">File share.</param>
/// <returns>FileStream object.</returns>
public static FileStream GetFileForJobDefinition(
string definitionName,
FileMode fileMode,
FileAccess fileAccess,
FileShare fileShare)
{
if (string.IsNullOrEmpty(definitionName))
{
throw new PSArgumentException("definitionName");
}
string filePathName = GetFilePathName(definitionName, DefinitionFileName);
return File.Open(filePathName, fileMode, fileAccess, fileShare);
}
/// <summary>
/// Returns FileStream object for existing scheduled job definition.
/// Definition file is looked for in the path provided.
/// </summary>
/// <param name="definitionName">Scheduled job definition name.</param>
/// <param name="definitionPath">Scheduled job definition file path.</param>
/// <param name="fileMode">File mode.</param>
/// <param name="fileAccess">File share.</param>
/// <param name="fileShare">File share.</param>
/// <returns></returns>
public static FileStream GetFileForJobDefinition(
string definitionName,
string definitionPath,
FileMode fileMode,
FileAccess fileAccess,
FileShare fileShare)
{
if (string.IsNullOrEmpty(definitionName))
{
throw new PSArgumentException("definitionName");
}
if (string.IsNullOrEmpty(definitionPath))
{
throw new PSArgumentException("definitionPath");
}
string filePathName = string.Format(CultureInfo.InvariantCulture, @"{0}\{1}\{2}.xml",
definitionPath, definitionName, DefinitionFileName);
return File.Open(filePathName, fileMode, fileAccess, fileShare);
}
/// <summary>
/// Checks the provided path against the the default path of scheduled jobs
/// for the current user.
/// </summary>
/// <param name="definitionPath">Path for scheduled job definitions</param>
/// <returns>True if paths are equal</returns>
public static bool IsDefaultUserPath(string definitionPath)
{
return definitionPath.Equals(GetJobDefinitionLocation(), StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Returns a FileStream object for a new scheduled job definition name.
/// </summary>
/// <param name="definitionName">Scheduled job definition name.</param>
/// <returns>FileStream object.</returns>
public static FileStream CreateFileForJobDefinition(
string definitionName)
{
if (string.IsNullOrEmpty(definitionName))
{
throw new PSArgumentException("definitionName");
}
string filePathName = CreateFilePathName(definitionName, DefinitionFileName);
return File.Create(filePathName);
}
/// <summary>
/// Returns an IEnumerable object of scheduled job definition names in
/// the job store.
/// </summary>
/// <returns>IEnumerable of job definition names.</returns>
public static IEnumerable<string> GetJobDefinitions()
{
// Directory names are identical to the corresponding scheduled job definition names.
string directoryPath = GetDirectoryPath();
IEnumerable<string> definitions = Directory.EnumerateDirectories(directoryPath);
return (definitions != null) ? definitions : new Collection<string>() as IEnumerable<string>;
}
/// <summary>
/// Returns a FileStream object for an existing scheduled job definition
/// run.
/// </summary>
/// <param name="definitionName">Scheduled job definition name.</param>
/// <param name="runStart">DateTime of job run start time.</param>
/// <param name="runItem">Job run item.</param>
/// <param name="fileAccess">File access</param>
/// <param name="fileMode">File mode</param>
/// <param name="fileShare">File share</param>
/// <returns>FileStream object.</returns>
public static FileStream GetFileForJobRunItem(
string definitionName,
DateTime runStart,
JobRunItem runItem,
FileMode fileMode,
FileAccess fileAccess,
FileShare fileShare)
{
if (string.IsNullOrEmpty(definitionName))
{
throw new PSArgumentException("definitionName");
}
string filePathName = GetRunFilePathName(definitionName, runItem, runStart);
return File.Open(filePathName, fileMode, fileAccess, fileShare);
}
/// <summary>
/// Returns a FileStream object for a new scheduled job definition run.
/// </summary>
/// <param name="definitionOutputPath">Scheudled job definition path.</param>
/// <param name="runStart">DateTime of job run start time.</param>
/// <param name="runItem">Job run item.</param>
/// <returns>FileStream object.</returns>
public static FileStream CreateFileForJobRunItem(
string definitionOutputPath,
DateTime runStart,
JobRunItem runItem)
{
if (string.IsNullOrEmpty(definitionOutputPath))
{
throw new PSArgumentException("definitionOutputPath");
}
string filePathName = GetRunFilePathNameFromPath(definitionOutputPath, runItem, runStart);
// If the file already exists, we overwrite it because the job run
// can be updated multiple times while the job is running.
return File.Create(filePathName);
}
/// <summary>
/// Returns a collection of DateTime objects which specify job run directories
/// that are currently in the store.
/// </summary>
/// <param name="definitionName">Scheduled job definition name.</param>
/// <returns>Collection of DateTime objects.</returns>
public static Collection<DateTime> GetJobRunsForDefinition(
string definitionName)
{
if (string.IsNullOrEmpty(definitionName))
{
throw new PSArgumentException("definitionName");
}
string definitionOutputPath = GetJobRunOutputDirectory(definitionName);
return GetJobRunsForDefinitionPath(definitionOutputPath);
}
/// <summary>
/// Returns a collection of DateTime objects which specify job run directories
/// that are currently in the store.
/// </summary>
/// <param name="definitionOutputPath">Scheduled job definition job run Output path.</param>
/// <returns>Collection of DateTime objects.</returns>
public static Collection<DateTime> GetJobRunsForDefinitionPath(
string definitionOutputPath)
{
if (string.IsNullOrEmpty(definitionOutputPath))
{
throw new PSArgumentException("definitionOutputPath");
}
Collection<DateTime> jobRunInfos = new Collection<DateTime>();
IEnumerable<string> jobRuns = Directory.EnumerateDirectories(definitionOutputPath);
if (jobRuns != null)
{
// Job run directory names are the date/times that the job was started.
foreach (string jobRun in jobRuns)
{
DateTime jobRunDateTime;
int indx = jobRun.LastIndexOf('\\');
string jobRunName = (indx != -1) ? jobRun.Substring(indx + 1) : jobRun;
if (ConvertJobRunNameToDateTime(jobRunName, out jobRunDateTime))
{
jobRunInfos.Add(jobRunDateTime);
}
}
}
return jobRunInfos;
}
/// <summary>
/// Remove the job definition and all job runs from job store.
/// </summary>
/// <param name="definitionName">Scheduled Job Definition name</param>
public static void RemoveJobDefinition(
string definitionName)
{
if (string.IsNullOrEmpty(definitionName))
{
throw new PSArgumentException("definitionName");
}
// Remove job runs, job definition file, and job definition directory.
string jobDefDirectory = GetJobDefinitionPath(definitionName);
Directory.Delete(jobDefDirectory, true);
}
/// <summary>
/// Renames the directory containing the old job definition name
/// to the new name provided.
/// </summary>
/// <param name="oldDefName">Existing job defintion directory</param>
/// <param name="newDefName">Renamed job defintion directory</param>
public static void RenameScheduledJobDefDir(
string oldDefName,
string newDefName)
{
if (string.IsNullOrEmpty(oldDefName))
{
throw new PSArgumentException("oldDefName");
}
if (string.IsNullOrEmpty(newDefName))
{
throw new PSArgumentException("newDefName");
}
string oldDirPath = GetJobDefinitionPath(oldDefName);
string newDirPath = GetJobDefinitionPath(newDefName);
Directory.Move(oldDirPath, newDirPath);
}
/// <summary>
/// Remove a single job definition job run from the job store.
/// </summary>
/// <param name="definitionName">Scheduled Job Definition name</param>
/// <param name="runStart">DateTime of job run</param>
public static void RemoveJobRun(
string definitionName,
DateTime runStart)
{
if (string.IsNullOrEmpty(definitionName))
{
throw new PSArgumentException("definitionName");
}
// Remove the job run files and directory.
string runDirectory = GetRunDirectory(definitionName, runStart);
Directory.Delete(runDirectory, true);
}
/// <summary>
/// Remove a single job definition job run from the job store.
/// </summary>
/// <param name="definitionOutputPath">Scheduled Job Definition Output path</param>
/// <param name="runStart">DateTime of job run</param>
public static void RemoveJobRunFromOutputPath(
string definitionOutputPath,
DateTime runStart)
{
if (string.IsNullOrEmpty(definitionOutputPath))
{
throw new PSArgumentException("definitionOutputPath");
}
// Remove the job run files and directory.
string runDirectory = GetRunDirectoryFromPath(definitionOutputPath, runStart);
Directory.Delete(runDirectory, true);
}
/// <summary>
/// Remove all job runs for this job definition.
/// </summary>
/// <param name="definitionName">Scheduled Job Definition name</param>
public static void RemoveAllJobRuns(
string definitionName)
{
if (string.IsNullOrEmpty(definitionName))
{
throw new PSArgumentException("definitionName");
}
Collection<DateTime> jobRuns = GetJobRunsForDefinition(definitionName);
foreach (DateTime jobRun in jobRuns)
{
string jobRunPath = GetRunDirectory(definitionName, jobRun);
Directory.Delete(jobRunPath, true);
}
}
/// <summary>
/// Set read access on provided definition file for specified user.
/// </summary>
/// <param name="definitionName">Definition name</param>
/// <param name="user">Account user name</param>
public static void SetReadAccessOnDefinitionFile(
string definitionName,
string user)
{
string filePath = GetFilePathName(definitionName, DefinitionFileName);
// Get file security for existing file.
FileSecurity fileSecurity = new FileSecurity(
filePath,
AccessControlSections.Access);
// Create rule.
FileSystemAccessRule fileAccessRule = new FileSystemAccessRule(
user,
FileSystemRights.Read,
AccessControlType.Allow);
fileSecurity.AddAccessRule(fileAccessRule);
// Apply rule.
File.SetAccessControl(filePath, fileSecurity);
}
/// <summary>
/// Set write access on Output directory for provided definition for
/// specified user.
/// </summary>
/// <param name="definitionName">Definition name</param>
/// <param name="user">Account user name</param>
public static void SetWriteAccessOnJobRunOutput(
string definitionName,
string user)
{
string outputDirectoryPath = GetJobRunOutputDirectory(definitionName);
AddFullAccessToDirectory(user, outputDirectoryPath);
}
/// <summary>
/// Returns the directory path for job run output for the specified
/// scheduled job definition.
/// </summary>
/// <param name="definitionName">Definition name</param>
/// <returns>Directory Path</returns>
public static string GetJobRunOutputDirectory(
string definitionName)
{
if (string.IsNullOrEmpty(definitionName))
{
throw new PSArgumentException("definitionName");
}
return Path.Combine(GetJobDefinitionPath(definitionName), JobRunOutput);
}
/// <summary>
/// Gets the directory path for a Scheduled Job Definition.
/// </summary>
/// <returns>Directory Path</returns>
public static string GetJobDefinitionLocation()
{
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
ScheduledJobsPath);
}
public static void CreateDirectoryIfNotExists()
{
GetDirectoryPath();
}
#endregion
#region Private Methods
/// <summary>
/// Gets the directory path for Scheduled Jobs. Will create the directory if
/// it does not exist.
/// </summary>
/// <returns>Directory Path</returns>
private static string GetDirectoryPath()
{
string pathName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
ScheduledJobsPath);
if (!Directory.Exists(pathName))
{
Directory.CreateDirectory(pathName);
}
return pathName;
}
/// <summary>
/// Creates a ScheduledJob definition directory with provided definition name
/// along with a job run Output directory, and returns a file path/name.
/// ...\ScheduledJobs\definitionName\fileName.xml
/// ...\ScheduledJobs\definitionName\Output\
/// </summary>
/// <param name="definitionName">Definition name</param>
/// <param name="fileName">File name</param>
/// <returns>File path/name</returns>
private static string CreateFilePathName(string definitionName, string fileName)
{
string filePath = GetJobDefinitionPath(definitionName);
string outputPath = GetJobRunOutputDirectory(definitionName);
if (Directory.Exists(filePath))
{
ScheduledJobException ex = new ScheduledJobException(StringUtil.Format(ScheduledJobErrorStrings.JobDefFileAlreadyExists, definitionName));
ex.FQEID = ScheduledJobDefExistsFQEID;
throw ex;
}
Directory.CreateDirectory(filePath);
Directory.CreateDirectory(outputPath);
return string.Format(CultureInfo.InstalledUICulture, @"{0}\{1}.xml", filePath, fileName);
}
/// <summary>
/// Returns a file path/name for an existing Scheduled job definition directory.
/// </summary>
/// <param name="definitionName">Definition name</param>
/// <param name="fileName">File name</param>
/// <returns>File path/name</returns>
private static string GetFilePathName(string definitionName, string fileName)
{
string filePath = GetJobDefinitionPath(definitionName);
return string.Format(CultureInfo.InvariantCulture, @"{0}\{1}.xml", filePath, fileName);
}
/// <summary>
/// Gets the directory path for a Scheduled Job Definition.
/// </summary>
/// <param name="definitionName">Scheduled job definition name</param>
/// <returns>Directory Path</returns>
private static string GetJobDefinitionPath(string definitionName)
{
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
ScheduledJobsPath,
definitionName);
}
/// <summary>
/// Returns a directory path for an existing ScheduledJob run result directroy.
/// </summary>
/// <param name="definitionName">Definition name</param>
/// <param name="runStart">File name</param>
/// <returns>Directory Path</returns>
private static string GetRunDirectory(
string definitionName,
DateTime runStart)
{
string directoryPath = GetJobRunOutputDirectory(definitionName);
return string.Format(CultureInfo.InvariantCulture, @"{0}\{1}", directoryPath,
ConvertDateTimeToJobRunName(runStart));
}
/// <summary>
/// Returns a directory path for an existing ScheduledJob run based on
/// provided definition Output directory path.
/// </summary>
/// <param name="definitionOutputPath">Output directory path</param>
/// <param name="runStart">File name</param>
/// <returns>Directory Path</returns>
private static string GetRunDirectoryFromPath(
string definitionOutputPath,
DateTime runStart)
{
return string.Format(CultureInfo.InvariantCulture, @"{0}\{1}",
definitionOutputPath, ConvertDateTimeToJobRunName(runStart));
}
/// <summary>
/// Returns a file path/name for a run result file. Will create the
/// job run directory if it does not exist.
/// </summary>
/// <param name="definitionName">Definition name</param>
/// <param name="runItem">Result type</param>
/// <param name="runStart">Run date</param>
/// <returns>File path/name</returns>
private static string GetRunFilePathName(
string definitionName,
JobRunItem runItem,
DateTime runStart)
{
string directoryPath = GetJobRunOutputDirectory(definitionName);
string jobRunPath = string.Format(CultureInfo.InvariantCulture, @"{0}\{1}",
directoryPath, ConvertDateTimeToJobRunName(runStart));
return string.Format(CultureInfo.InvariantCulture, @"{0}\{1}.xml", jobRunPath,
runItem.ToString());
}
/// <summary>
/// Returns a file path/name for a job run result, based on the passed in
/// job run output path. Will create the job run directory if it does not
/// exist.
/// </summary>
/// <param name="outputPath">Definition job run output path</param>
/// <param name="runItem">Result type</param>
/// <param name="runStart">Run date</param>
/// <returns></returns>
private static string GetRunFilePathNameFromPath(
string outputPath,
JobRunItem runItem,
DateTime runStart)
{
string jobRunPath = string.Format(CultureInfo.InvariantCulture, @"{0}\{1}",
outputPath, ConvertDateTimeToJobRunName(runStart));
if (!Directory.Exists(jobRunPath))
{
// Create directory for this job run date.
Directory.CreateDirectory(jobRunPath);
}
return string.Format(CultureInfo.InvariantCulture, @"{0}\{1}.xml", jobRunPath,
runItem.ToString());
}
private static void AddFullAccessToDirectory(
string user,
string directoryPath)
{
// Create rule.
DirectoryInfo info = new DirectoryInfo(directoryPath);
DirectorySecurity dSecurity = info.GetAccessControl();
FileSystemAccessRule fileAccessRule = new FileSystemAccessRule(
user,
FileSystemRights.FullControl,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.None,
AccessControlType.Allow);
// Apply rule.
dSecurity.AddAccessRule(fileAccessRule);
info.SetAccessControl(dSecurity);
}
//
// String format: 'YYYYMMDD-HHMMSS-SSS'
// ,where SSS is milliseconds.
//
private static string ConvertDateTimeToJobRunName(DateTime dt)
{
return string.Format(CultureInfo.InvariantCulture,
@"{0:d4}{1:d2}{2:d2}-{3:d2}{4:d2}{5:d2}-{6:d3}",
dt.Year, dt.Month, dt.Day,
dt.Hour, dt.Minute, dt.Second, dt.Millisecond);
}
/// <summary>
/// Converts a jobRun name string to an equivalent DateTime
/// </summary>
/// <param name="jobRunName"></param>
/// <param name="jobRun"></param>
/// <returns></returns>
internal static bool ConvertJobRunNameToDateTime(string jobRunName, out DateTime jobRun)
{
if (jobRunName == null || jobRunName.Length != 19)
{
jobRun = new DateTime();
return false;
}
int year = 0;
int month = 0;
int day = 0;
int hour = 0;
int minute = 0;
int second = 0;
int msecs = 0;
bool success = true;
try
{
year = Convert.ToInt32(jobRunName.Substring(0, 4));
month = Convert.ToInt32(jobRunName.Substring(4, 2));
day = Convert.ToInt32(jobRunName.Substring(6, 2));
hour = Convert.ToInt32(jobRunName.Substring(9, 2));
minute = Convert.ToInt32(jobRunName.Substring(11, 2));
second = Convert.ToInt32(jobRunName.Substring(13, 2));
msecs = Convert.ToInt32(jobRunName.Substring(16, 3));
}
catch (FormatException)
{
success = false;
}
catch (OverflowException)
{
success = false;
}
if (success)
{
jobRun = new DateTime(year, month, day, hour, minute, second, msecs);
}
else
{
jobRun = new DateTime();
}
return success;
}
#endregion
}
}

View File

@ -0,0 +1,880 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Runtime.Serialization;
using System.Management.Automation;
using System.Globalization;
using System.Threading;
using Microsoft.Management.Infrastructure;
using System.Security.Permissions;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This class contains parameters used to define how/when a PowerShell job is
/// run via the Windows Task Scheduler (WTS).
/// </summary>
[Serializable]
public sealed class ScheduledJobTrigger : ISerializable
{
#region Private Members
private DateTime? _time;
private List<DayOfWeek> _daysOfWeek;
private TimeSpan _randomDelay;
private Int32 _interval = 1;
private string _user;
private TriggerFrequency _frequency = TriggerFrequency.None;
private TimeSpan? _repInterval;
private TimeSpan? _repDuration;
private Int32 _id;
private bool _enabled = true;
private ScheduledJobDefinition _jobDefAssociation;
private static string _allUsers = "*";
#endregion
#region Public Properties
/// <summary>
/// Trigger time.
/// </summary>
public DateTime? At
{
get { return _time; }
set { _time = value; }
}
/// <summary>
/// Trigger days of week.
/// </summary>
public List<DayOfWeek> DaysOfWeek
{
get { return _daysOfWeek; }
set { _daysOfWeek = value; }
}
/// <summary>
/// Trigger days or weeks interval.
/// </summary>
public Int32 Interval
{
get { return _interval; }
set { _interval = value; }
}
/// <summary>
/// Trigger frequency.
/// </summary>
public TriggerFrequency Frequency
{
get { return _frequency; }
set { _frequency = value; }
}
/// <summary>
/// Trigger random delay.
/// </summary>
public TimeSpan RandomDelay
{
get { return _randomDelay; }
set { _randomDelay = value; }
}
/// <summary>
/// Trigger Once frequency repetition interval.
/// </summary>
public TimeSpan? RepetitionInterval
{
get { return _repInterval; }
set
{
// A TimeSpan value of zero is equivalent to a null value.
_repInterval = (value != null && value.Value == TimeSpan.Zero) ?
null : value;
}
}
/// <summary>
/// Trigger Once frequency repetition duration.
/// </summary>
public TimeSpan? RepetitionDuration
{
get { return _repDuration; }
set
{
// A TimeSpan value of zero is equivalent to a null value.
_repDuration = (value != null && value.Value == TimeSpan.Zero) ?
null : value;
}
}
/// <summary>
/// Trigger user name.
/// </summary>
public string User
{
get { return _user; }
set { _user = value; }
}
/// <summary>
/// Returns the trigger local Id.
/// </summary>
public Int32 Id
{
get { return _id; }
internal set { _id = value; }
}
/// <summary>
/// Defines enabled state of trigger.
/// </summary>
public bool Enabled
{
get { return _enabled; }
set { _enabled = value; }
}
/// <summary>
/// ScheduledJobDefinition object this trigger is associated with.
/// </summary>
public ScheduledJobDefinition JobDefinition
{
get { return _jobDefAssociation; }
internal set { _jobDefAssociation = value; }
}
#endregion
#region Constructors
/// <summary>
/// Default constructor.
/// </summary>
public ScheduledJobTrigger()
{ }
/// <summary>
/// Constructor.
/// </summary>
/// <param name="enabled">Enabled</param>
/// <param name="frequency">Trigger frequency</param>
/// <param name="time">Trigger time</param>
/// <param name="daysOfWeek">Weekly days of week</param>
/// <param name="interval">Daily or Weekly interval</param>
/// <param name="randomDelay">Random delay</param>
/// <param name="repetitionInterval">Repetition interval</param>
/// <param name="repetitionDuration">Repetition duration</param>
/// <param name="user">Logon user</param>
/// <param name="id">Trigger id</param>
private ScheduledJobTrigger(
bool enabled,
TriggerFrequency frequency,
DateTime? time,
List<DayOfWeek> daysOfWeek,
Int32 interval,
TimeSpan randomDelay,
TimeSpan? repetitionInterval,
TimeSpan? repetitionDuration,
string user,
Int32 id)
{
_enabled = enabled;
_frequency = frequency;
_time = time;
_daysOfWeek = daysOfWeek;
_interval = interval;
_randomDelay = randomDelay;
RepetitionInterval = repetitionInterval;
RepetitionDuration = repetitionDuration;
_user = user;
_id = id;
}
/// <summary>
/// Copy constructor.
/// </summary>
/// <param name="copyTrigger">ScheduledJobTrigger</param>
internal ScheduledJobTrigger(ScheduledJobTrigger copyTrigger)
{
if (copyTrigger == null)
{
throw new PSArgumentNullException("copyTrigger");
}
_enabled = copyTrigger.Enabled;
_frequency = copyTrigger.Frequency;
_id = copyTrigger.Id;
_time = copyTrigger.At;
_daysOfWeek = copyTrigger.DaysOfWeek;
_interval = copyTrigger.Interval;
_randomDelay = copyTrigger.RandomDelay;
_repInterval = copyTrigger.RepetitionInterval;
_repDuration = copyTrigger.RepetitionDuration;
_user = copyTrigger.User;
_jobDefAssociation = copyTrigger.JobDefinition;
}
/// <summary>
/// Serialization constructor
/// </summary>
/// <param name="info">SerializationInfo</param>
/// <param name="context">StreamingContext</param>
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
private ScheduledJobTrigger(
SerializationInfo info,
StreamingContext context)
{
if (info == null)
{
throw new PSArgumentNullException("info");
}
DateTime time = info.GetDateTime("Time_Value");
if (time != DateTime.MinValue)
{
_time = time;
}
else
{
_time = null;
}
RepetitionInterval = (TimeSpan?)info.GetValue("RepetitionInterval_Value", typeof(TimeSpan));
RepetitionDuration = (TimeSpan?)info.GetValue("RepetitionDuration_Value", typeof(TimeSpan));
_daysOfWeek = (List<DayOfWeek>)info.GetValue("DaysOfWeek_Value", typeof(List<DayOfWeek>));
_randomDelay = (TimeSpan)info.GetValue("RandomDelay_Value", typeof(TimeSpan));
_interval = info.GetInt32("Interval_Value");
_user = info.GetString("User_Value");
_frequency = (TriggerFrequency)info.GetValue("TriggerFrequency_Value", typeof(TriggerFrequency));
_id = info.GetInt32("ID_Value");
_enabled = info.GetBoolean("Enabled_Value");
// Runtime reference and not saved to store.
_jobDefAssociation = null;
}
#endregion
#region ISerializable Implementation
/// <summary>
/// GetObjectData for ISerializable implementation.
/// </summary>
/// <param name="info"></param>
/// <param name="context"></param>
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new PSArgumentNullException("info");
}
if (_time == null)
{
info.AddValue("Time_Value", DateTime.MinValue);
}
else
{
info.AddValue("Time_Value", _time);
}
if (_repInterval == null)
{
info.AddValue("RepetitionInterval_Value", TimeSpan.Zero);
}
else
{
info.AddValue("RepetitionInterval_Value", _repInterval);
}
if (_repDuration == null)
{
info.AddValue("RepetitionDuration_Value", TimeSpan.Zero);
}
else
{
info.AddValue("RepetitionDuration_Value", _repDuration);
}
info.AddValue("DaysOfWeek_Value", _daysOfWeek);
info.AddValue("RandomDelay_Value", _randomDelay);
info.AddValue("Interval_Value", _interval);
info.AddValue("User_Value", _user);
info.AddValue("TriggerFrequency_Value", _frequency);
info.AddValue("ID_Value", _id);
info.AddValue("Enabled_Value", _enabled);
}
#endregion
#region Internal Methods
internal void ClearProperties()
{
_time = null;
_daysOfWeek = null;
_interval = 1;
_randomDelay = TimeSpan.Zero;
_repInterval = null;
_repDuration = null;
_user = null;
_frequency = TriggerFrequency.None;
_enabled = false;
_id = 0;
}
internal void Validate()
{
switch (_frequency)
{
case TriggerFrequency.None:
throw new ScheduledJobException(ScheduledJobErrorStrings.MissingJobTriggerType);
case TriggerFrequency.AtStartup:
// AtStartup has no required parameters.
break;
case TriggerFrequency.AtLogon:
// AtLogon has no required parameters.
break;
case TriggerFrequency.Once:
if (_time == null)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.MissingJobTriggerTime, ScheduledJobErrorStrings.TriggerOnceType);
throw new ScheduledJobException(msg);
}
if (_repInterval != null || _repDuration != null)
{
ValidateOnceRepetitionParams(_repInterval, _repDuration);
}
break;
case TriggerFrequency.Daily:
if (_time == null)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.MissingJobTriggerTime, ScheduledJobErrorStrings.TriggerDailyType);
throw new ScheduledJobException(msg);
}
if (_interval < 1)
{
throw new ScheduledJobException(ScheduledJobErrorStrings.InvalidDaysIntervalParam);
}
break;
case TriggerFrequency.Weekly:
if (_time == null)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.MissingJobTriggerTime, ScheduledJobErrorStrings.TriggerWeeklyType);
throw new ScheduledJobException(msg);
}
if (_interval < 1)
{
throw new ScheduledJobException(ScheduledJobErrorStrings.InvalidWeeksIntervalParam);
}
if (_daysOfWeek == null || _daysOfWeek.Count == 0)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.MissingJobTriggerDaysOfWeek, ScheduledJobErrorStrings.TriggerWeeklyType);
throw new ScheduledJobException(msg);
}
break;
}
}
internal static void ValidateOnceRepetitionParams(
TimeSpan? repInterval,
TimeSpan? repDuration)
{
// Both Interval and Duration parameters must be specified together.
if (repInterval == null || repDuration == null)
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidRepetitionParams);
}
// Interval and Duration parameters must not have negative value.
if (repInterval < TimeSpan.Zero || repDuration < TimeSpan.Zero)
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidRepetitionParamValues);
}
// Zero values are allowed but only if both parameters are set to zero.
// This removes repetition from the Once trigger.
if (repInterval == TimeSpan.Zero && repDuration != TimeSpan.Zero)
{
throw new PSArgumentException(ScheduledJobErrorStrings.MismatchedRepetitionParamValues);
}
// Parameter values must be GE to one minute unless both are zero to remove repetition.
if (repInterval < TimeSpan.FromMinutes(1) &&
!(repInterval == TimeSpan.Zero && repDuration == TimeSpan.Zero))
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidRepetitionIntervalValue);
}
// Interval parameter must be LE to Duration parameter.
if (repInterval > repDuration)
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidRepetitionInterval);
}
}
internal void CopyTo(ScheduledJobTrigger targetTrigger)
{
if (targetTrigger == null)
{
throw new PSArgumentNullException("targetTrigger");
}
targetTrigger.Enabled = _enabled;
targetTrigger.Frequency = _frequency;
targetTrigger.Id = _id;
targetTrigger.At = _time;
targetTrigger.DaysOfWeek = _daysOfWeek;
targetTrigger.Interval = _interval;
targetTrigger.RandomDelay = _randomDelay;
targetTrigger.RepetitionInterval = _repInterval;
targetTrigger.RepetitionDuration = _repDuration;
targetTrigger.User = _user;
targetTrigger.JobDefinition = _jobDefAssociation;
}
#endregion
#region Static methods
/// <summary>
/// Creates a one time ScheduledJobTrigger object.
/// </summary>
/// <param name="time">DateTime when trigger activates</param>
/// <param name="delay">Random delay</param>
/// <param name="repetitionInterval">Repetition interval</param>
/// <param name="repetitionDuration">Repetition duration</param>
/// <param name="id">Trigger Id</param>
/// <param name="enabled">Trigger enabled state</param>
/// <returns>ScheduledJobTrigger</returns>
public static ScheduledJobTrigger CreateOnceTrigger(
DateTime time,
TimeSpan delay,
TimeSpan? repetitionInterval,
TimeSpan? repetitionDuration,
Int32 id,
bool enabled)
{
return new ScheduledJobTrigger(
enabled,
TriggerFrequency.Once,
time,
null,
1,
delay,
repetitionInterval,
repetitionDuration,
null,
id);
}
/// <summary>
/// Creates a daily ScheduledJobTrigger object.
/// </summary>
/// <param name="time">Time of day when trigger activates</param>
/// <param name="interval">Days interval for trigger activation</param>
/// <param name="delay">Random delay</param>
/// <param name="id">Trigger Id</param>
/// <param name="enabled">Trigger enabled state</param>
/// <returns>ScheduledJobTrigger</returns>
public static ScheduledJobTrigger CreateDailyTrigger(
DateTime time,
Int32 interval,
TimeSpan delay,
Int32 id,
bool enabled)
{
return new ScheduledJobTrigger(
enabled,
TriggerFrequency.Daily,
time,
null,
interval,
delay,
null,
null,
null,
id);
}
/// <summary>
/// Creates a weekly ScheduledJobTrigger object.
/// </summary>
/// <param name="time">Time of day when trigger activates</param>
/// <param name="interval">Weeks interval for trigger activation</param>
/// <param name="daysOfWeek">Days of the week for trigger activation</param>
/// <param name="delay">Random delay</param>
/// <param name="id">Trigger Id</param>
/// <param name="enabled">Trigger enabled state</param>
/// <returns>ScheduledJobTrigger</returns>
public static ScheduledJobTrigger CreateWeeklyTrigger(
DateTime time,
Int32 interval,
IEnumerable<DayOfWeek> daysOfWeek,
TimeSpan delay,
Int32 id,
bool enabled)
{
List<DayOfWeek> lDaysOfWeek = (daysOfWeek != null) ? new List<DayOfWeek>(daysOfWeek) : null;
return new ScheduledJobTrigger(
enabled,
TriggerFrequency.Weekly,
time,
lDaysOfWeek,
interval,
delay,
null,
null,
null,
id);
}
/// <summary>
/// Creates a trigger that activates after user log on.
/// </summary>
/// <param name="user">Name of user</param>
/// <param name="delay">Random delay</param>
/// <param name="id">Trigger Id</param>
/// <param name="enabled">Trigger enabled state</param>
/// <returns>ScheduledJobTrigger</returns>
public static ScheduledJobTrigger CreateAtLogOnTrigger(
string user,
TimeSpan delay,
Int32 id,
bool enabled)
{
return new ScheduledJobTrigger(
enabled,
TriggerFrequency.AtLogon,
null,
null,
1,
delay,
null,
null,
string.IsNullOrEmpty(user) ? AllUsers : user,
id);
}
/// <summary>
/// Creates a trigger that activates after OS boot.
/// </summary>
/// <param name="delay">Random delay</param>
/// <param name="id">Trigger Id</param>
/// <param name="enabled">Trigger enabled state</param>
/// <returns>ScheduledJobTrigger</returns>
public static ScheduledJobTrigger CreateAtStartupTrigger(
TimeSpan delay,
Int32 id,
bool enabled)
{
return new ScheduledJobTrigger(
enabled,
TriggerFrequency.AtStartup,
null,
null,
1,
delay,
null,
null,
null,
id);
}
/// <summary>
/// Compares provided user name to All Users string ("*").
/// </summary>
/// <param name="userName">Logon user name.</param>
/// <returns>Boolean, true if All Users.</returns>
internal static bool IsAllUsers(string userName)
{
return (string.Compare(userName, ScheduledJobTrigger.AllUsers,
StringComparison.OrdinalIgnoreCase) == 0);
}
/// <summary>
/// Returns the All Users string.
/// </summary>
internal static string AllUsers
{
get { return _allUsers; }
}
#endregion
#region Public Methods
/// <summary>
/// Update the associated ScheduledJobDefinition object with the
/// current properties of this object.
/// </summary>
public void UpdateJobDefinition()
{
if (_jobDefAssociation == null)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.NoAssociatedJobDefinitionForTrigger, _id);
throw new RuntimeException(msg);
}
_jobDefAssociation.UpdateTriggers(new ScheduledJobTrigger[1] { this }, true);
}
#endregion
}
#region Public Enums
/// <summary>
/// Specifies trigger types in terms of the frequency that
/// the trigger is activated.
/// </summary>
public enum TriggerFrequency
{
/// <summary>
/// None.
/// </summary>
None = 0,
/// <summary>
/// Trigger activates once at a specified time.
/// </summary>
Once = 1,
/// <summary>
/// Trigger activates daily.
/// </summary>
Daily = 2,
/// <summary>
/// Trigger activates on a weekly basis and multiple days
/// during the week.
/// </summary>
Weekly = 3,
/// <summary>
/// Trigger activates at user logon to the operating system.
/// </summary>
AtLogon = 4,
/// <summary>
/// Trigger activates after machine boot up.
/// </summary>
AtStartup = 5
}
#endregion
#region JobTriggerToCimInstanceConverter
/// <summary>
/// Class providing implementation of PowerShell conversions for types in Microsoft.Management.Infrastructure namespace
/// </summary>
public sealed class JobTriggerToCimInstanceConverter : PSTypeConverter
{
private static readonly string CIM_TRIGGER_NAMESPACE = @"Root\Microsoft\Windows\TaskScheduler";
/// <summary>
/// Determines if the converter can convert the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter.
/// </summary>
/// <param name="sourceValue">The value to convert from</param>
/// <param name="destinationType">The type to convert to</param>
/// <returns>True if the converter can convert the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter, otherwise false.</returns>
public override bool CanConvertFrom(object sourceValue, Type destinationType)
{
if (destinationType == null)
{
throw new ArgumentNullException("destinationType");
}
return (sourceValue is ScheduledJobTrigger) && (destinationType.Equals(typeof(CimInstance)));
}
/// <summary>
/// Converts the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter using formatProvider and ignoreCase
/// </summary>
/// <param name="sourceValue">The value to convert from</param>
/// <param name="destinationType">The type to convert to</param>
/// <param name="formatProvider">The format provider to use like in IFormatable's ToString</param>
/// <param name="ignoreCase">true if case should be ignored</param>
/// <returns>the <paramref name="sourceValue"/> parameter converted to the <paramref name="destinationType"/> parameter using formatProvider and ignoreCase</returns>
/// <exception cref="InvalidCastException">if no conversion was possible</exception>
public override object ConvertFrom(object sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase)
{
if (destinationType == null)
{
throw new ArgumentNullException("destinationType");
}
if (sourceValue == null)
{
throw new ArgumentNullException("sourceValue");
}
ScheduledJobTrigger originalTrigger = (ScheduledJobTrigger) sourceValue;
using (CimSession cimSession = CimSession.Create(null))
{
switch (originalTrigger.Frequency)
{
case TriggerFrequency.Weekly:
return ConvertToWeekly(originalTrigger, cimSession);
case TriggerFrequency.Once:
return ConvertToOnce(originalTrigger, cimSession);
case TriggerFrequency.Daily:
return ConvertToDaily(originalTrigger, cimSession);
case TriggerFrequency.AtStartup:
return ConvertToAtStartup(originalTrigger, cimSession);
case TriggerFrequency.AtLogon:
return ConvertToAtLogon(originalTrigger, cimSession);
case TriggerFrequency.None:
return ConvertToDefault(originalTrigger, cimSession);
default:
string errorMsg = StringUtil.Format(ScheduledJobErrorStrings.UnknownTriggerFrequency,
originalTrigger.Frequency.ToString());
throw new PSInvalidOperationException(errorMsg);
}
}
}
/// <summary>
/// Returns true if the converter can convert the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter
/// </summary>
/// <param name="sourceValue">The value to convert from</param>
/// <param name="destinationType">The type to convert to</param>
/// <returns>True if the converter can convert the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter, otherwise false.</returns>
public override bool CanConvertTo(object sourceValue, Type destinationType)
{
return false;
}
/// <summary>
/// Converts the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter using formatProvider and ignoreCase
/// </summary>
/// <param name="sourceValue">The value to convert from</param>
/// <param name="destinationType">The type to convert to</param>
/// <param name="formatProvider">The format provider to use like in IFormatable's ToString</param>
/// <param name="ignoreCase">true if case should be ignored</param>
/// <returns>sourceValue converted to the <paramref name="destinationType"/> parameter using formatProvider and ignoreCase</returns>
/// <exception cref="InvalidCastException">if no conversion was possible</exception>
public override object ConvertTo(object sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase)
{
throw new NotImplementedException();
}
#region Helper Methods
private CimInstance ConvertToWeekly(ScheduledJobTrigger trigger, CimSession cimSession)
{
CimClass cimClass = cimSession.GetClass(CIM_TRIGGER_NAMESPACE, "MSFT_TaskWeeklyTrigger");
CimInstance cimInstance = new CimInstance(cimClass);
cimInstance.CimInstanceProperties["DaysOfWeek"].Value = ScheduledJobWTS.ConvertDaysOfWeekToMask(trigger.DaysOfWeek);
cimInstance.CimInstanceProperties["RandomDelay"].Value = ScheduledJobWTS.ConvertTimeSpanToWTSString(trigger.RandomDelay);
cimInstance.CimInstanceProperties["WeeksInterval"].Value = trigger.Interval;
AddCommonProperties(trigger, cimInstance);
return cimInstance;
}
private CimInstance ConvertToOnce(ScheduledJobTrigger trigger, CimSession cimSession)
{
CimClass cimClass = cimSession.GetClass(CIM_TRIGGER_NAMESPACE, "MSFT_TaskTimeTrigger");
CimInstance cimInstance = new CimInstance(cimClass);
cimInstance.CimInstanceProperties["RandomDelay"].Value = ScheduledJobWTS.ConvertTimeSpanToWTSString(trigger.RandomDelay);
if (trigger.RepetitionInterval != null && trigger.RepetitionDuration != null)
{
CimClass cimRepClass = cimSession.GetClass(CIM_TRIGGER_NAMESPACE, "MSFT_TaskRepetitionPattern");
CimInstance cimRepInstance = new CimInstance(cimRepClass);
cimRepInstance.CimInstanceProperties["Interval"].Value = ScheduledJobWTS.ConvertTimeSpanToWTSString(trigger.RepetitionInterval.Value);
if (trigger.RepetitionDuration == TimeSpan.MaxValue)
{
cimRepInstance.CimInstanceProperties["StopAtDurationEnd"].Value = false;
}
else
{
cimRepInstance.CimInstanceProperties["StopAtDurationEnd"].Value = true;
cimRepInstance.CimInstanceProperties["Duration"].Value = ScheduledJobWTS.ConvertTimeSpanToWTSString(trigger.RepetitionDuration.Value);
}
cimInstance.CimInstanceProperties["Repetition"].Value = cimRepInstance;
}
AddCommonProperties(trigger, cimInstance);
return cimInstance;
}
private CimInstance ConvertToDaily(ScheduledJobTrigger trigger, CimSession cimSession)
{
CimClass cimClass = cimSession.GetClass(CIM_TRIGGER_NAMESPACE, "MSFT_TaskDailyTrigger");
CimInstance cimInstance = new CimInstance(cimClass);
cimInstance.CimInstanceProperties["RandomDelay"].Value = ScheduledJobWTS.ConvertTimeSpanToWTSString(trigger.RandomDelay);
cimInstance.CimInstanceProperties["DaysInterval"].Value = trigger.Interval;
AddCommonProperties(trigger, cimInstance);
return cimInstance;
}
private CimInstance ConvertToAtLogon(ScheduledJobTrigger trigger, CimSession cimSession)
{
CimClass cimClass = cimSession.GetClass(CIM_TRIGGER_NAMESPACE, "MSFT_TaskLogonTrigger");
CimInstance cimInstance = new CimInstance(cimClass);
cimInstance.CimInstanceProperties["Delay"].Value = ScheduledJobWTS.ConvertTimeSpanToWTSString(trigger.RandomDelay);
// Convert the "AllUsers" name ("*" character) to null for Task Scheduler.
string userId = (ScheduledJobTrigger.IsAllUsers(trigger.User)) ? null : trigger.User;
cimInstance.CimInstanceProperties["UserId"].Value = userId;
AddCommonProperties(trigger, cimInstance);
return cimInstance;
}
private CimInstance ConvertToAtStartup(ScheduledJobTrigger trigger, CimSession cimSession)
{
CimClass cimClass = cimSession.GetClass(CIM_TRIGGER_NAMESPACE, "MSFT_TaskBootTrigger");
CimInstance cimInstance = new CimInstance(cimClass);
cimInstance.CimInstanceProperties["Delay"].Value = ScheduledJobWTS.ConvertTimeSpanToWTSString(trigger.RandomDelay);
AddCommonProperties(trigger, cimInstance);
return cimInstance;
}
private CimInstance ConvertToDefault(ScheduledJobTrigger trigger, CimSession cimSession)
{
CimClass cimClass = cimSession.GetClass(CIM_TRIGGER_NAMESPACE, "MSFT_TaskTrigger");
CimInstance result = new CimInstance(cimClass);
AddCommonProperties(trigger, result);
return result;
}
private static void AddCommonProperties(ScheduledJobTrigger trigger, CimInstance cimInstance)
{
cimInstance.CimInstanceProperties["Enabled"].Value = trigger.Enabled;
if (trigger.At != null)
{
cimInstance.CimInstanceProperties["StartBoundary"].Value = ScheduledJobWTS.ConvertDateTimeToString(trigger.At);
}
}
#endregion
}
#endregion
}

View File

@ -0,0 +1,947 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using TaskScheduler;
using System.Diagnostics;
using System.Globalization;
using System.Management.Automation;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// Managed code class to provide Windows Task Scheduler functionality for
/// scheduled jobs.
/// </summary>
internal sealed class ScheduledJobWTS : IDisposable
{
#region Private Members
private ITaskService _taskScheduler;
private ITaskFolder _iRootFolder;
private const short WTSSunday = 0x01;
private const short WTSMonday = 0x02;
private const short WTSTuesday = 0x04;
private const short WTSWednesday = 0x08;
private const short WTSThursday = 0x10;
private const short WTSFriday = 0x20;
private const short WTSSaturday = 0x40;
// Task Scheduler folders for PowerShell scheduled job tasks.
private const string TaskSchedulerWindowsFolder = @"\Microsoft\Windows";
private const string ScheduledJobSubFolder = @"PowerShell\ScheduledJobs";
private const string ScheduledJobTasksRootFolder = @"\Microsoft\Windows\PowerShell\ScheduledJobs";
// Define a single Action Id since PowerShell Scheduled Job tasks will have only one action.
private const string ScheduledJobTaskActionId = "StartPowerShellJob";
#endregion
#region Constructors
public ScheduledJobWTS()
{
// Create the Windows Task Scheduler object.
_taskScheduler = (ITaskService)new TaskScheduler.TaskScheduler();
// Connect the task scheduler object to the local machine
// using the current user security token.
_taskScheduler.Connect(null, null, null, null);
// Get or create the root folder in Task Scheduler for PowerShell scheduled jobs.
_iRootFolder = GetRootFolder();
}
#endregion
#region Public Methods
/// <summary>
/// Retrieves job triggers from WTS with provided task Id.
/// </summary>
/// <param name="taskId">Task Id</param>
/// <exception cref="ScheduledJobException">Task not found.</exception>
/// <returns>ScheduledJobTriggers</returns>
public Collection<ScheduledJobTrigger> GetJobTriggers(
string taskId)
{
if (string.IsNullOrEmpty(taskId))
{
throw new PSArgumentException("taskId");
}
ITaskDefinition iTaskDefinition = FindTask(taskId);
Collection<ScheduledJobTrigger> jobTriggers = new Collection<ScheduledJobTrigger>();
ITriggerCollection iTriggerCollection = iTaskDefinition.Triggers;
if (iTriggerCollection != null)
{
foreach (ITrigger iTrigger in iTriggerCollection)
{
ScheduledJobTrigger jobTrigger = CreateJobTrigger(iTrigger);
if (jobTrigger == null)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.UnknownTriggerType, taskId, iTrigger.Id);
throw new ScheduledJobException(msg);
}
jobTriggers.Add(jobTrigger);
}
}
return jobTriggers;
}
/// <summary>
/// Retrives options for the provided task Id.
/// </summary>
/// <param name="taskId">Task Id</param>
/// <exception cref="ScheduledJobException">Task not found.</exception>
/// <returns>ScheduledJobOptions</returns>
public ScheduledJobOptions GetJobOptions(
string taskId)
{
if (string.IsNullOrEmpty(taskId))
{
throw new PSArgumentException("taskId");
}
ITaskDefinition iTaskDefinition = FindTask(taskId);
return CreateJobOptions(iTaskDefinition);
}
/// <summary>
/// Returns a boolean indicating whether the job/task is enabled
/// in the Task Scheduler.
/// </summary>
/// <param name="taskId"></param>
/// <returns></returns>
public bool GetTaskEnabled(
string taskId)
{
if (string.IsNullOrEmpty(taskId))
{
throw new PSArgumentException("taskId");
}
ITaskDefinition iTaskDefinition = FindTask(taskId);
return iTaskDefinition.Settings.Enabled;
}
/// <summary>
/// Creates a new task in WTS with information from ScheduledJobDefinition.
/// </summary>
/// <param name="definition">ScheduledJobDefinition</param>
public void CreateTask(
ScheduledJobDefinition definition)
{
if (definition == null)
{
throw new PSArgumentNullException("definition");
}
// Create task definition
ITaskDefinition iTaskDefinition = _taskScheduler.NewTask(0);
// Add task options.
AddTaskOptions(iTaskDefinition, definition.Options);
// Add task triggers.
foreach (ScheduledJobTrigger jobTrigger in definition.JobTriggers)
{
AddTaskTrigger(iTaskDefinition, jobTrigger);
}
// Add task action.
AddTaskAction(iTaskDefinition, definition);
// Create a security descriptor for the current user so that only the user
// (and Local System account) can see/access the registered task.
string startSddl = "D:P(A;;GA;;;SY)(A;;GA;;;BA)"; // DACL Allow Generic Access to System and BUILTIN\Administrators.
System.Security.Principal.SecurityIdentifier userSid =
System.Security.Principal.WindowsIdentity.GetCurrent().User;
CommonSecurityDescriptor SDesc = new CommonSecurityDescriptor(false, false, startSddl);
SDesc.DiscretionaryAcl.AddAccess(AccessControlType.Allow, userSid, 0x10000000, InheritanceFlags.None, PropagationFlags.None);
string sddl = SDesc.GetSddlForm(AccessControlSections.All);
// Register this new task with the Task Scheduler.
if (definition.Credential == null)
{
// Register task to run as currently logged on user.
_iRootFolder.RegisterTaskDefinition(
definition.Name,
iTaskDefinition,
(int)_TASK_CREATION.TASK_CREATE,
null, // User name
null, // Password
_TASK_LOGON_TYPE.TASK_LOGON_S4U,
sddl);
}
else
{
// Register task to run under provided user account/credentials.
_iRootFolder.RegisterTaskDefinition(
definition.Name,
iTaskDefinition,
(int)_TASK_CREATION.TASK_CREATE,
definition.Credential.UserName,
GetCredentialPassword(definition.Credential),
_TASK_LOGON_TYPE.TASK_LOGON_PASSWORD,
sddl);
}
}
/// <summary>
/// Removes the WTS task for this ScheduledJobDefinition.
/// Throws error if one or more instances of this task are running.
/// Force parameter will stop all running instances and remove task.
/// </summary>
/// <param name="definition">ScheduledJobDefinition</param>
/// <param name="force">Force running instances to stop and remove task</param>
public void RemoveTask(
ScheduledJobDefinition definition,
bool force = false)
{
if (definition == null)
{
throw new PSArgumentNullException("definition");
}
RemoveTaskByName(definition.Name, force, false);
}
/// <summary>
/// Removes a Task Scheduler task from the PowerShell/ScheduledJobs folder
/// based on a task name.
/// </summary>
/// <param name="taskName">Task Scheduler task name</param>
/// <param name="force">Force running instances to stop and remove task</param>
/// <param name="firstCheckForTask">First check for existence of task</param>
public void RemoveTaskByName(
string taskName,
bool force,
bool firstCheckForTask)
{
// Get registered task.
IRegisteredTask iRegisteredTask = null;
try
{
iRegisteredTask = _iRootFolder.GetTask(taskName);
}
catch (System.IO.DirectoryNotFoundException)
{
if (!firstCheckForTask)
{
throw;
}
}
catch (System.IO.FileNotFoundException)
{
if (!firstCheckForTask)
{
throw;
}
}
if (iRegisteredTask == null)
{
return;
}
// Check to see if any instances of this job/task is running.
IRunningTaskCollection iRunningTasks = iRegisteredTask.GetInstances(0);
if (iRunningTasks.Count > 0)
{
if (!force)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.CannotRemoveTaskRunningInstance, taskName);
throw new ScheduledJobException(msg);
}
// Stop all running tasks.
iRegisteredTask.Stop(0);
}
// Remove task.
_iRootFolder.DeleteTask(taskName, 0);
}
/// <summary>
/// Starts task running from Task Scheduler.
/// </summary>
/// <param name="definition">ScheduledJobDefinition</param>
/// <exception cref="System.IO.DirectoryNotFoundException"></exception>
/// <exception cref="System.IO.FileNotFoundException"></exception>
public void RunTask(
ScheduledJobDefinition definition)
{
// Get registered task.
IRegisteredTask iRegisteredTask = _iRootFolder.GetTask(definition.Name);
// Run task.
iRegisteredTask.Run(null);
}
/// <summary>
/// Updates an existing task in WTS with information from
/// ScheduledJobDefinition.
/// </summary>
/// <param name="definition">ScheduledJobDefinition</param>
public void UpdateTask(
ScheduledJobDefinition definition)
{
if (definition == null)
{
throw new PSArgumentNullException("definition");
}
// Get task to update.
ITaskDefinition iTaskDefinition = FindTask(definition.Name);
// Replace options.
AddTaskOptions(iTaskDefinition, definition.Options);
// Set enabled state.
iTaskDefinition.Settings.Enabled = definition.Enabled;
// Replace triggers.
iTaskDefinition.Triggers.Clear();
foreach (ScheduledJobTrigger jobTrigger in definition.JobTriggers)
{
AddTaskTrigger(iTaskDefinition, jobTrigger);
}
// Replace action.
iTaskDefinition.Actions.Clear();
AddTaskAction(iTaskDefinition, definition);
// Register updated task.
if (definition.Credential == null)
{
// Register task to run as currently logged on user.
_iRootFolder.RegisterTaskDefinition(
definition.Name,
iTaskDefinition,
(int)_TASK_CREATION.TASK_UPDATE,
null, // User name
null, // Password
_TASK_LOGON_TYPE.TASK_LOGON_S4U,
null);
}
else
{
// Register task to run under provided user account/credentials.
_iRootFolder.RegisterTaskDefinition(
definition.Name,
iTaskDefinition,
(int)_TASK_CREATION.TASK_UPDATE,
definition.Credential.UserName,
GetCredentialPassword(definition.Credential),
_TASK_LOGON_TYPE.TASK_LOGON_PASSWORD,
null);
}
}
#endregion
#region Private Methods
/// <summary>
/// Creates a new WTS trigger based on the provided ScheduledJobTrigger object
/// and adds it to the provided ITaskDefinition object.
/// </summary>
/// <param name="iTaskDefinition">ITaskDefinition</param>
/// <param name="jobTrigger">ScheduledJobTrigger</param>
private void AddTaskTrigger(
ITaskDefinition iTaskDefinition,
ScheduledJobTrigger jobTrigger)
{
ITrigger iTrigger = null;
switch (jobTrigger.Frequency)
{
case TriggerFrequency.AtStartup:
{
iTrigger = iTaskDefinition.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_BOOT);
IBootTrigger iBootTrigger = iTrigger as IBootTrigger;
Debug.Assert(iBootTrigger != null);
iBootTrigger.Delay = ConvertTimeSpanToWTSString(jobTrigger.RandomDelay);
iTrigger.Id = jobTrigger.Id.ToString(CultureInfo.InvariantCulture);
iTrigger.Enabled = jobTrigger.Enabled;
}
break;
case TriggerFrequency.AtLogon:
{
iTrigger = iTaskDefinition.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_LOGON);
ILogonTrigger iLogonTrigger = iTrigger as ILogonTrigger;
Debug.Assert(iLogonTrigger != null);
iLogonTrigger.UserId = ScheduledJobTrigger.IsAllUsers(jobTrigger.User) ? null : jobTrigger.User;
iLogonTrigger.Delay = ConvertTimeSpanToWTSString(jobTrigger.RandomDelay);
iTrigger.Id = jobTrigger.Id.ToString(CultureInfo.InvariantCulture);
iTrigger.Enabled = jobTrigger.Enabled;
}
break;
case TriggerFrequency.Once:
{
iTrigger = iTaskDefinition.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_TIME);
ITimeTrigger iTimeTrigger = iTrigger as ITimeTrigger;
Debug.Assert(iTimeTrigger != null);
iTimeTrigger.RandomDelay = ConvertTimeSpanToWTSString(jobTrigger.RandomDelay);
// Time trigger repetition.
if (jobTrigger.RepetitionInterval != null &&
jobTrigger.RepetitionDuration != null)
{
iTimeTrigger.Repetition.Interval = ConvertTimeSpanToWTSString(jobTrigger.RepetitionInterval.Value);
if (jobTrigger.RepetitionDuration.Value == TimeSpan.MaxValue)
{
iTimeTrigger.Repetition.StopAtDurationEnd = false;
}
else
{
iTimeTrigger.Repetition.StopAtDurationEnd = true;
iTimeTrigger.Repetition.Duration = ConvertTimeSpanToWTSString(jobTrigger.RepetitionDuration.Value);
}
}
iTrigger.StartBoundary = ConvertDateTimeToString(jobTrigger.At);
iTrigger.Id = jobTrigger.Id.ToString(CultureInfo.InvariantCulture);
iTrigger.Enabled = jobTrigger.Enabled;
}
break;
case TriggerFrequency.Daily:
{
iTrigger = iTaskDefinition.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_DAILY);
IDailyTrigger iDailyTrigger = iTrigger as IDailyTrigger;
Debug.Assert(iDailyTrigger != null);
iDailyTrigger.RandomDelay = ConvertTimeSpanToWTSString(jobTrigger.RandomDelay);
iDailyTrigger.DaysInterval = (short)jobTrigger.Interval;
iTrigger.StartBoundary = ConvertDateTimeToString(jobTrigger.At);
iTrigger.Id = jobTrigger.Id.ToString(CultureInfo.InvariantCulture);
iTrigger.Enabled = jobTrigger.Enabled;
}
break;
case TriggerFrequency.Weekly:
{
iTrigger = iTaskDefinition.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_WEEKLY);
IWeeklyTrigger iWeeklyTrigger = iTrigger as IWeeklyTrigger;
Debug.Assert(iWeeklyTrigger != null);
iWeeklyTrigger.RandomDelay = ConvertTimeSpanToWTSString(jobTrigger.RandomDelay);
iWeeklyTrigger.WeeksInterval = (short)jobTrigger.Interval;
iWeeklyTrigger.DaysOfWeek = ConvertDaysOfWeekToMask(jobTrigger.DaysOfWeek);
iTrigger.StartBoundary = ConvertDateTimeToString(jobTrigger.At);
iTrigger.Id = jobTrigger.Id.ToString(CultureInfo.InvariantCulture);
iTrigger.Enabled = jobTrigger.Enabled;
}
break;
}
}
/// <summary>
/// Creates a ScheuduledJobTrigger object based on a provided WTS ITrigger.
/// </summary>
/// <param name="iTrigger">ITrigger</param>
/// <returns>ScheduledJobTrigger</returns>
private ScheduledJobTrigger CreateJobTrigger(
ITrigger iTrigger)
{
ScheduledJobTrigger rtnJobTrigger = null;
if (iTrigger is IBootTrigger)
{
IBootTrigger iBootTrigger = (IBootTrigger)iTrigger;
rtnJobTrigger = ScheduledJobTrigger.CreateAtStartupTrigger(
ParseWTSTime(iBootTrigger.Delay),
ConvertStringId(iBootTrigger.Id),
iBootTrigger.Enabled);
}
else if (iTrigger is ILogonTrigger)
{
ILogonTrigger iLogonTrigger = (ILogonTrigger)iTrigger;
rtnJobTrigger = ScheduledJobTrigger.CreateAtLogOnTrigger(
iLogonTrigger.UserId,
ParseWTSTime(iLogonTrigger.Delay),
ConvertStringId(iLogonTrigger.Id),
iLogonTrigger.Enabled);
}
else if (iTrigger is ITimeTrigger)
{
ITimeTrigger iTimeTrigger = (ITimeTrigger)iTrigger;
TimeSpan repInterval = ParseWTSTime(iTimeTrigger.Repetition.Interval);
TimeSpan repDuration = (repInterval != TimeSpan.Zero && iTimeTrigger.Repetition.StopAtDurationEnd == false) ?
TimeSpan.MaxValue : ParseWTSTime(iTimeTrigger.Repetition.Duration);
rtnJobTrigger = ScheduledJobTrigger.CreateOnceTrigger(
DateTime.Parse(iTimeTrigger.StartBoundary, CultureInfo.InvariantCulture),
ParseWTSTime(iTimeTrigger.RandomDelay),
repInterval,
repDuration,
ConvertStringId(iTimeTrigger.Id),
iTimeTrigger.Enabled);
}
else if (iTrigger is IDailyTrigger)
{
IDailyTrigger iDailyTrigger = (IDailyTrigger)iTrigger;
rtnJobTrigger = ScheduledJobTrigger.CreateDailyTrigger(
DateTime.Parse(iDailyTrigger.StartBoundary, CultureInfo.InvariantCulture),
(Int32)iDailyTrigger.DaysInterval,
ParseWTSTime(iDailyTrigger.RandomDelay),
ConvertStringId(iDailyTrigger.Id),
iDailyTrigger.Enabled);
}
else if (iTrigger is IWeeklyTrigger)
{
IWeeklyTrigger iWeeklyTrigger = (IWeeklyTrigger)iTrigger;
rtnJobTrigger = ScheduledJobTrigger.CreateWeeklyTrigger(
DateTime.Parse(iWeeklyTrigger.StartBoundary, CultureInfo.InvariantCulture),
(Int32)iWeeklyTrigger.WeeksInterval,
ConvertMaskToDaysOfWeekArray(iWeeklyTrigger.DaysOfWeek),
ParseWTSTime(iWeeklyTrigger.RandomDelay),
ConvertStringId(iWeeklyTrigger.Id),
iWeeklyTrigger.Enabled);
}
return rtnJobTrigger;
}
private void AddTaskOptions(
ITaskDefinition iTaskDefinition,
ScheduledJobOptions jobOptions)
{
iTaskDefinition.Settings.DisallowStartIfOnBatteries = !jobOptions.StartIfOnBatteries;
iTaskDefinition.Settings.StopIfGoingOnBatteries = jobOptions.StopIfGoingOnBatteries;
iTaskDefinition.Settings.WakeToRun = jobOptions.WakeToRun;
iTaskDefinition.Settings.RunOnlyIfIdle = !jobOptions.StartIfNotIdle;
iTaskDefinition.Settings.IdleSettings.StopOnIdleEnd = jobOptions.StopIfGoingOffIdle;
iTaskDefinition.Settings.IdleSettings.RestartOnIdle = jobOptions.RestartOnIdleResume;
iTaskDefinition.Settings.IdleSettings.IdleDuration = ConvertTimeSpanToWTSString(jobOptions.IdleDuration);
iTaskDefinition.Settings.IdleSettings.WaitTimeout = ConvertTimeSpanToWTSString(jobOptions.IdleTimeout);
iTaskDefinition.Settings.Hidden = !jobOptions.ShowInTaskScheduler;
iTaskDefinition.Settings.RunOnlyIfNetworkAvailable = !jobOptions.RunWithoutNetwork;
iTaskDefinition.Settings.AllowDemandStart = !jobOptions.DoNotAllowDemandStart;
iTaskDefinition.Settings.MultipleInstances = ConvertFromMultiInstances(jobOptions.MultipleInstancePolicy);
iTaskDefinition.Principal.RunLevel = (jobOptions.RunElevated) ?
_TASK_RUNLEVEL.TASK_RUNLEVEL_HIGHEST : _TASK_RUNLEVEL.TASK_RUNLEVEL_LUA;
}
private ScheduledJobOptions CreateJobOptions(
ITaskDefinition iTaskDefinition)
{
ITaskSettings iTaskSettings = iTaskDefinition.Settings;
IPrincipal iPrincipal = iTaskDefinition.Principal;
return new ScheduledJobOptions(
!iTaskSettings.DisallowStartIfOnBatteries,
iTaskSettings.StopIfGoingOnBatteries,
iTaskSettings.WakeToRun,
!iTaskSettings.RunOnlyIfIdle,
iTaskSettings.IdleSettings.StopOnIdleEnd,
iTaskSettings.IdleSettings.RestartOnIdle,
ParseWTSTime(iTaskSettings.IdleSettings.IdleDuration),
ParseWTSTime(iTaskSettings.IdleSettings.WaitTimeout),
!iTaskSettings.Hidden,
iPrincipal.RunLevel == _TASK_RUNLEVEL.TASK_RUNLEVEL_HIGHEST,
!iTaskSettings.RunOnlyIfNetworkAvailable,
!iTaskSettings.AllowDemandStart,
ConvertToMultiInstances(iTaskSettings));
}
private void AddTaskAction(
ITaskDefinition iTaskDefinition,
ScheduledJobDefinition definition)
{
IExecAction iExecAction = iTaskDefinition.Actions.Create(_TASK_ACTION_TYPE.TASK_ACTION_EXEC) as IExecAction;
Debug.Assert(iExecAction != null);
iExecAction.Id = ScheduledJobTaskActionId;
iExecAction.Path = definition.PSExecutionPath;
iExecAction.Arguments = definition.PSExecutionArgs;
}
/// <summary>
/// Gets and returns the unsecured password for the provided
/// PSCredential object.
/// </summary>
/// <param name="credential">PSCredential</param>
/// <returns>Unsecured password string</returns>
private string GetCredentialPassword(PSCredential credential)
{
if (credential == null)
{
return null;
}
IntPtr unmanagedString = IntPtr.Zero;
try
{
unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(credential.Password);
return Marshal.PtrToStringUni(unmanagedString);
}
finally
{
Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
}
}
#endregion
#region Private Utility Methods
/// <summary>
/// Gets the Task Scheduler root folder for Scheduled Jobs or
/// creates it if it does not exist.
/// </summary>
/// <returns>Scheduled Jobs root folder.</returns>
private ITaskFolder GetRootFolder()
{
ITaskFolder iTaskRootFolder = null;
try
{
iTaskRootFolder = _taskScheduler.GetFolder(ScheduledJobTasksRootFolder);
}
catch (System.IO.DirectoryNotFoundException)
{
}
catch (System.IO.FileNotFoundException)
{
// This can be thrown if COM interop tries to load the Microsoft.PowerShell.ScheduledJob
// assembly again.
}
if (iTaskRootFolder == null)
{
// Create the PowerShell Scheduled Job root folder.
ITaskFolder iTSWindowsFolder = _taskScheduler.GetFolder(TaskSchedulerWindowsFolder);
iTaskRootFolder = iTSWindowsFolder.CreateFolder(ScheduledJobSubFolder);
}
return iTaskRootFolder;
}
/// <summary>
/// Finds a task with the provided Task Id and returns it as
/// a ITaskDefinition object.
/// </summary>
/// <param name="taskId">Task Id</param>
/// <returns>ITaskDefinition</returns>
private ITaskDefinition FindTask(string taskId)
{
try
{
ITaskFolder iTaskFolder = _taskScheduler.GetFolder(ScheduledJobTasksRootFolder);
IRegisteredTask iRegisteredTask = iTaskFolder.GetTask(taskId);
return iRegisteredTask.Definition;
}
catch (System.IO.DirectoryNotFoundException e)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.CannotFindTaskId, taskId);
throw new ScheduledJobException(msg, e);
}
}
private Int32 ConvertStringId(string triggerId)
{
Int32 triggerIdVal = 0;
try
{
triggerIdVal = Convert.ToInt32(triggerId);
}
catch (FormatException)
{ }
catch (OverflowException)
{ }
return triggerIdVal;
}
/// <summary>
/// Helper method to parse a WTS time string and return
/// a corresponding TimeSpan object. Note that the
/// year and month values are ignored.
/// Format:
/// "PnYnMnDTnHnMnS"
/// "P" - Date separator
/// "nY" - year value.
/// "nM" - month value.
/// "nD" - day value.
/// "T" - Time separator
/// "nH" - hour value.
/// "nM" - minute value.
/// "nS" - second value.
/// </summary>
/// <param name="wtsTime">Formatted time string</param>
/// <returns>TimeSpan</returns>
private TimeSpan ParseWTSTime(string wtsTime)
{
if (string.IsNullOrEmpty(wtsTime))
{
return new TimeSpan(0);
}
int days = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
int indx = 0;
int length = wtsTime.Length;
StringBuilder str = new StringBuilder();
try
{
while (indx != length)
{
char c = wtsTime[indx++];
switch (c)
{
case 'P':
str.Clear();
while (indx != length &&
wtsTime[indx] != 'T')
{
char c2 = wtsTime[indx++];
if (c2 == 'Y')
{
// Ignore year value.
str.Clear();
}
else if (c2 == 'M')
{
// Ignore month value.
str.Clear();
}
else if (c2 == 'D')
{
days = Convert.ToInt32(str.ToString(), CultureInfo.InvariantCulture);
str.Clear();
}
else if (c2 >= '0' && c2 <= '9')
{
str.Append(c2);
}
}
break;
case 'T':
str.Clear();
while (indx != length &&
wtsTime[indx] != 'P')
{
char c2 = wtsTime[indx++];
if (c2 == 'H')
{
hours = Convert.ToInt32(str.ToString(), CultureInfo.InvariantCulture);
str.Clear();
}
else if (c2 == 'M')
{
minutes = Convert.ToInt32(str.ToString(), CultureInfo.InvariantCulture);
str.Clear();
}
else if (c2 == 'S')
{
seconds = Convert.ToInt32(str.ToString(), CultureInfo.InvariantCulture);
str.Clear();
}
else if (c2 >= '0' && c2 <= '9')
{
str.Append(c2);
}
}
break;
}
}
}
catch (FormatException)
{ }
catch (OverflowException)
{ }
return new TimeSpan(days, hours, minutes, seconds);
}
/// <summary>
/// Creates WTS formatted time string based on TimeSpan parameter.
/// </summary>
/// <param name="time">TimeSpan</param>
/// <returns>WTS time string</returns>
internal static string ConvertTimeSpanToWTSString(TimeSpan time)
{
return string.Format(
CultureInfo.InvariantCulture,
"P{0}DT{1}H{2}M{3}S",
time.Days,
time.Hours,
time.Minutes,
time.Seconds);
}
/// <summary>
/// Converts DateTime to string for WTS.
/// </summary>
/// <param name="dt">DateTime</param>
/// <returns>DateTime string</returns>
internal static string ConvertDateTimeToString(DateTime? dt)
{
if (dt == null)
{
return string.Empty;
}
else
{
return dt.Value.ToString("s", CultureInfo.InvariantCulture);
}
}
/// <summary>
/// Returns a bitmask representing days of week as
/// required by Windows Task Scheduler API.
/// </summary>
/// <param name="daysOfWeek">Array of DayOfWeek</param>
/// <returns>WTS days of week mask</returns>
internal static short ConvertDaysOfWeekToMask(IEnumerable<DayOfWeek> daysOfWeek)
{
short rtnValue = 0;
foreach (DayOfWeek day in daysOfWeek)
{
switch (day)
{
case DayOfWeek.Sunday:
rtnValue |= WTSSunday;
break;
case DayOfWeek.Monday:
rtnValue |= WTSMonday;
break;
case DayOfWeek.Tuesday:
rtnValue |= WTSTuesday;
break;
case DayOfWeek.Wednesday:
rtnValue |= WTSWednesday;
break;
case DayOfWeek.Thursday:
rtnValue |= WTSThursday;
break;
case DayOfWeek.Friday:
rtnValue |= WTSFriday;
break;
case DayOfWeek.Saturday:
rtnValue |= WTSSaturday;
break;
}
}
return rtnValue;
}
/// <summary>
/// Converts WTS days of week mask to an array of DayOfWeek type.
/// </summary>
/// <param name="mask">WTS days of week mask</param>
/// <returns>Days of week as List</returns>
private List<DayOfWeek> ConvertMaskToDaysOfWeekArray(short mask)
{
List<DayOfWeek> daysOfWeek = new List<DayOfWeek>();
if ((mask & WTSSunday) != 0) { daysOfWeek.Add(DayOfWeek.Sunday); }
if ((mask & WTSMonday) != 0) { daysOfWeek.Add(DayOfWeek.Monday); }
if ((mask & WTSTuesday) != 0) { daysOfWeek.Add(DayOfWeek.Tuesday); }
if ((mask & WTSWednesday) != 0) { daysOfWeek.Add(DayOfWeek.Wednesday); }
if ((mask & WTSThursday) != 0) { daysOfWeek.Add(DayOfWeek.Thursday); }
if ((mask & WTSFriday) != 0) { daysOfWeek.Add(DayOfWeek.Friday); }
if ((mask & WTSSaturday) != 0) { daysOfWeek.Add(DayOfWeek.Saturday); }
return daysOfWeek;
}
private TaskMultipleInstancePolicy ConvertToMultiInstances(
ITaskSettings iTaskSettings)
{
switch (iTaskSettings.MultipleInstances)
{
case _TASK_INSTANCES_POLICY.TASK_INSTANCES_IGNORE_NEW:
return TaskMultipleInstancePolicy.IgnoreNew;
case _TASK_INSTANCES_POLICY.TASK_INSTANCES_PARALLEL:
return TaskMultipleInstancePolicy.Parallel;
case _TASK_INSTANCES_POLICY.TASK_INSTANCES_QUEUE:
return TaskMultipleInstancePolicy.Queue;
case _TASK_INSTANCES_POLICY.TASK_INSTANCES_STOP_EXISTING:
return TaskMultipleInstancePolicy.StopExisting;
}
Debug.Assert(false);
return TaskMultipleInstancePolicy.None;
}
private _TASK_INSTANCES_POLICY ConvertFromMultiInstances(
TaskMultipleInstancePolicy jobPolicies)
{
switch (jobPolicies)
{
case TaskMultipleInstancePolicy.IgnoreNew:
return _TASK_INSTANCES_POLICY.TASK_INSTANCES_IGNORE_NEW;
case TaskMultipleInstancePolicy.Parallel:
return _TASK_INSTANCES_POLICY.TASK_INSTANCES_PARALLEL;
case TaskMultipleInstancePolicy.Queue:
return _TASK_INSTANCES_POLICY.TASK_INSTANCES_QUEUE;
case TaskMultipleInstancePolicy.StopExisting:
return _TASK_INSTANCES_POLICY.TASK_INSTANCES_STOP_EXISTING;
default:
return _TASK_INSTANCES_POLICY.TASK_INSTANCES_IGNORE_NEW;
}
}
#endregion
#region IDisposable
/// <summary>
/// Dispose.
/// </summary>
public void Dispose()
{
// Release reference to Task Scheduler object so that the COM
// object can be released.
_iRootFolder = null;
_taskScheduler = null;
GC.SuppressFinalize(this);
}
#endregion
}
}

View File

@ -0,0 +1,139 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Management.Automation;
using System.Management.Automation.Internal;
using System.Management.Automation.Host;
using System.Threading;
using System.Diagnostics;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This cmdlet adds ScheduledJobTriggers to ScheduledJobDefinition objects.
/// </summary>
[Cmdlet(VerbsCommon.Add, "JobTrigger", DefaultParameterSetName = AddJobTriggerCommand.JobDefinitionParameterSet,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=223913")]
public sealed class AddJobTriggerCommand : ScheduleJobCmdletBase
{
#region Parameters
private const string JobDefinitionParameterSet = "JobDefinition";
private const string JobDefinitionIdParameterSet = "JobDefinitionId";
private const string JobDefinitionNameParameterSet = "JobDefinitionName";
/// <summary>
/// ScheduledJobTrigger.
/// </summary>
[Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true,
ParameterSetName = AddJobTriggerCommand.JobDefinitionParameterSet)]
[Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true,
ParameterSetName = AddJobTriggerCommand.JobDefinitionIdParameterSet)]
[Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true,
ParameterSetName = AddJobTriggerCommand.JobDefinitionNameParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public ScheduledJobTrigger[] Trigger
{
get { return _triggers; }
set { _triggers = value; }
}
private ScheduledJobTrigger[] _triggers;
/// <summary>
/// ScheduledJobDefition Id.
/// </summary>
[Parameter(Position = 0, Mandatory = true,
ParameterSetName = AddJobTriggerCommand.JobDefinitionIdParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public Int32[] Id
{
get { return _ids; }
set { _ids = value; }
}
private Int32[] _ids;
/// <summary>
/// ScheduledJobDefinition Name.
/// </summary>
[Parameter(Position = 0, Mandatory = true,
ParameterSetName = AddJobTriggerCommand.JobDefinitionNameParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] Name
{
get { return _names; }
set { _names = value; }
}
private string[] _names;
/// <summary>
/// ScheduledJobDefinition.
/// </summary>
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,
ParameterSetName = AddJobTriggerCommand.JobDefinitionParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public ScheduledJobDefinition[] InputObject
{
get { return _definitions; }
set { _definitions = value; }
}
private ScheduledJobDefinition[] _definitions;
#endregion
#region Cmdlet Overrides
/// <summary>
/// Process input.
/// </summary>
protected override void ProcessRecord()
{
switch (ParameterSetName)
{
case JobDefinitionParameterSet:
AddToJobDefinition(_definitions);
break;
case JobDefinitionIdParameterSet:
AddToJobDefinition(GetJobDefinitionsById(_ids));
break;
case JobDefinitionNameParameterSet:
AddToJobDefinition(GetJobDefinitionsByName(_names));
break;
}
}
#endregion
#region Private Methods
private void AddToJobDefinition(IEnumerable<ScheduledJobDefinition> jobDefinitions)
{
foreach (ScheduledJobDefinition definition in jobDefinitions)
{
try
{
definition.AddTriggers(_triggers, true);
}
catch (ScheduledJobException e)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.CantAddJobTriggersToDefinition, definition.Name);
Exception reason = new RuntimeException(msg, e);
ErrorRecord errorRecord = new ErrorRecord(reason, "CantAddJobTriggersToScheduledJobDefinition", ErrorCategory.InvalidOperation, definition);
WriteError(errorRecord);
}
}
}
#endregion
}
}

View File

@ -0,0 +1,32 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Management.Automation;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This cmdlet disables the specified ScheduledJobDefinition.
/// </summary>
[Cmdlet(VerbsLifecycle.Disable, "ScheduledJob", SupportsShouldProcess = true, DefaultParameterSetName = DisableScheduledJobDefinitionBase.DefinitionParameterSet,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=223927")]
[OutputType(typeof(ScheduledJobDefinition))]
public sealed class DisableScheduledJobCommand : DisableScheduledJobDefinitionBase
{
#region Properties
/// <summary>
/// Returns true if scheduled job defintion should be enabled,
/// false otherwise.
/// </summary>
protected override bool Enabled
{
get { return false; }
}
#endregion
}
}

View File

@ -0,0 +1,149 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Management.Automation;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// Base class for the DisableScheduledJobCommand, EnableScheduledJobCommand cmdlets.
/// </summary>
public abstract class DisableScheduledJobDefinitionBase : ScheduleJobCmdletBase
{
#region Parameters
/// <summary>
/// DefinitionIdParameterSet
/// </summary>
protected const string DefinitionIdParameterSet = "DefinitionId";
/// <summary>
/// DefinitionNameParameterSet
/// </summary>
protected const string DefinitionNameParameterSet = "DefinitionName";
/// <summary>
/// DefinitionParameterSet
/// </summary>
protected const string DefinitionParameterSet = "Definition";
/// <summary>
/// ScheduledJobDefinition.
/// </summary>
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,
ParameterSetName = DisableScheduledJobDefinitionBase.DefinitionParameterSet)]
[ValidateNotNull]
public ScheduledJobDefinition InputObject
{
get { return _definition; }
set { _definition = value; }
}
private ScheduledJobDefinition _definition;
/// <summary>
/// ScheduledJobDefinition Id.
/// </summary>
[Parameter(Position = 0, Mandatory = true,
ParameterSetName = DisableScheduledJobDefinitionBase.DefinitionIdParameterSet)]
public Int32 Id
{
get { return _definitionId; }
set { _definitionId = value; }
}
private Int32 _definitionId;
/// <summary>
/// ScheduledJobDefinition Name.
/// </summary>
[Parameter(Position = 0, Mandatory = true,
ParameterSetName = DisableScheduledJobDefinitionBase.DefinitionNameParameterSet)]
[ValidateNotNullOrEmpty]
public string Name
{
get { return _definitionName; }
set { _definitionName = value; }
}
private string _definitionName;
/// <summary>
/// Pass through ScheduledJobDefinition object.
/// </summary>
[Parameter(ParameterSetName = DisableScheduledJobDefinitionBase.DefinitionParameterSet)]
[Parameter(ParameterSetName = DisableScheduledJobDefinitionBase.DefinitionIdParameterSet)]
[Parameter(ParameterSetName = DisableScheduledJobDefinitionBase.DefinitionNameParameterSet)]
public SwitchParameter PassThru
{
get { return _passThru; }
set { _passThru = value; }
}
private SwitchParameter _passThru;
#endregion
#region Cmdlet Overrides
/// <summary>
/// Process input.
/// </summary>
protected override void ProcessRecord()
{
ScheduledJobDefinition definition = null;
switch (ParameterSetName)
{
case DefinitionParameterSet:
definition = _definition;
break;
case DefinitionIdParameterSet:
definition = GetJobDefinitionById(_definitionId);
break;
case DefinitionNameParameterSet:
definition = GetJobDefinitionByName(_definitionName);
break;
}
string verbName = Enabled ? VerbsLifecycle.Enable : VerbsLifecycle.Disable;
if (definition != null &&
ShouldProcess(definition.Name, verbName))
{
try
{
definition.SetEnabled(Enabled, true);
}
catch (ScheduledJobException e)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.CantSetEnableOnJobDefinition, definition.Name);
Exception reason = new RuntimeException(msg, e);
ErrorRecord errorRecord = new ErrorRecord(reason, "CantSetEnableOnScheduledJobDefinition", ErrorCategory.InvalidOperation, definition);
WriteError(errorRecord);
}
if (_passThru)
{
WriteObject(definition);
}
}
}
#endregion
#region Properties
/// <summary>
/// Returns true if scheduled job defintion should be enabled,
/// false otherwise.
/// </summary>
protected abstract bool Enabled
{
get;
}
#endregion
}
}

View File

@ -0,0 +1,36 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Management.Automation;
using System.Management.Automation.Internal;
using System.Management.Automation.Host;
using System.Threading;
using System.Diagnostics;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This cmdlet enables triggers on a ScheduledJobDefinition object.
/// </summary>
[Cmdlet(VerbsLifecycle.Disable, "JobTrigger", SupportsShouldProcess = true, DefaultParameterSetName = DisableJobTriggerCommand.EnabledParameterSet,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=223918")]
public sealed class DisableJobTriggerCommand : EnableDisableScheduledJobCmdletBase
{
#region Enabled Implementation
/// <summary>
/// Property to determine if trigger should be enabled or disabled.
/// </summary>
internal override bool Enabled
{
get { return false; }
}
#endregion
}
}

View File

@ -0,0 +1,94 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Internal;
using System.Management.Automation.Host;
using System.Threading;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// Base class for DisableJobTrigger, EnableJobTrigger cmdlets.
/// </summary>
public abstract class EnableDisableScheduledJobCmdletBase : ScheduleJobCmdletBase
{
#region Parameters
/// <summary>
/// JobDefinition parameter set.
/// </summary>
protected const string EnabledParameterSet = "JobEnabled";
/// <summary>
/// ScheduledJobTrigger objects to set properties on.
/// </summary>
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,
ParameterSetName = EnableDisableScheduledJobCmdletBase.EnabledParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public ScheduledJobTrigger[] InputObject
{
get { return _triggers; }
set { _triggers = value; }
}
/// <summary>
/// Pass through for scheduledjobtrigger object.
/// </summary>
[Parameter(ParameterSetName = EnableDisableScheduledJobCmdletBase.EnabledParameterSet)]
public SwitchParameter PassThru
{
get { return _passThru; }
set { _passThru = value; }
}
private SwitchParameter _passThru;
private ScheduledJobTrigger[] _triggers;
#endregion
#region Cmdlet Overrides
/// <summary>
/// Process input.
/// </summary>
protected override void ProcessRecord()
{
// Update each trigger with the current enabled state.
foreach (ScheduledJobTrigger trigger in _triggers)
{
trigger.Enabled = Enabled;
if (trigger.JobDefinition != null)
{
trigger.UpdateJobDefinition();
}
if (_passThru)
{
WriteObject(trigger);
}
}
}
#endregion
#region Internal Properties
/// <summary>
/// Property to determine if trigger should be enabled or disabled.
/// </summary>
internal abstract bool Enabled
{
get;
}
#endregion
}
}

View File

@ -0,0 +1,32 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Management.Automation;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This cmdlet enables the specified ScheduledJobDefinition.
/// </summary>
[Cmdlet(VerbsLifecycle.Enable, "ScheduledJob", SupportsShouldProcess = true, DefaultParameterSetName = DisableScheduledJobDefinitionBase.DefinitionParameterSet,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=223926")]
[OutputType(typeof(ScheduledJobDefinition))]
public sealed class EnableScheduledJobCommand : DisableScheduledJobDefinitionBase
{
#region Properties
/// <summary>
/// Returns true if scheduled job defintion should be enabled,
/// false otherwise.
/// </summary>
protected override bool Enabled
{
get { return true; }
}
#endregion
}
}

View File

@ -0,0 +1,36 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Management.Automation;
using System.Management.Automation.Internal;
using System.Management.Automation.Host;
using System.Threading;
using System.Diagnostics;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This cmdlet disables triggers on a ScheduledJobDefinition object.
/// </summary>
[Cmdlet(VerbsLifecycle.Enable, "JobTrigger", SupportsShouldProcess = true, DefaultParameterSetName = EnableJobTriggerCommand.EnabledParameterSet,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=223917")]
public sealed class EnableJobTriggerCommand : EnableDisableScheduledJobCmdletBase
{
#region Enabled Implementation
/// <summary>
/// Property to determine if trigger should be enabled or disabled.
/// </summary>
internal override bool Enabled
{
get { return true; }
}
#endregion
}
}

View File

@ -0,0 +1,96 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This cmdlet gets scheduled job definition objects from the local repository.
/// </summary>
[Cmdlet(VerbsCommon.Get, "ScheduledJob", DefaultParameterSetName = GetScheduledJobCommand.DefinitionIdParameterSet,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=223923")]
[OutputType(typeof(ScheduledJobDefinition))]
public sealed class GetScheduledJobCommand : ScheduleJobCmdletBase
{
#region Parameters
private const string DefinitionIdParameterSet = "DefinitionId";
private const string DefinitionNameParameterSet = "DefinitionName";
/// <summary>
/// ScheduledJobDefintion Id.
/// </summary>
[Parameter(Position = 0,
ParameterSetName = GetScheduledJobCommand.DefinitionIdParameterSet)]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public Int32[] Id
{
get { return _definitionIds; }
set { _definitionIds = value; }
}
private Int32[] _definitionIds;
/// <summary>
/// ScheduledJobDefinition Name.
/// </summary>
[Parameter(Position = 0, Mandatory = true,
ParameterSetName = GetScheduledJobCommand.DefinitionNameParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] Name
{
get { return _definitionNames; }
set { _definitionNames = value; }
}
private string[] _definitionNames;
#endregion
#region Cmdlet Overrides
/// <summary>
/// Process input.
/// </summary>
protected override void ProcessRecord()
{
switch (ParameterSetName)
{
case DefinitionIdParameterSet:
if (_definitionIds == null)
{
FindAllJobDefinitions(
(definition) =>
{
WriteObject(definition);
});
}
else
{
FindJobDefinitionsById(
_definitionIds,
(definition) =>
{
WriteObject(definition);
});
}
break;
case DefinitionNameParameterSet:
FindJobDefinitionsByName(
_definitionNames,
(definition) =>
{
WriteObject(definition);
});
break;
}
}
#endregion
}
}

View File

@ -0,0 +1,140 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Management.Automation;
using System.Management.Automation.Internal;
using System.Management.Automation.Host;
using System.Threading;
using System.Diagnostics;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This cmdlet gets ScheduledJobTriggers for the specified ScheduledJobDefintion object.
/// </summary>
[Cmdlet(VerbsCommon.Get, "JobTrigger", DefaultParameterSetName = GetJobTriggerCommand.JobDefinitionParameterSet,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=223915")]
[OutputType(typeof(ScheduledJobTrigger))]
public sealed class GetJobTriggerCommand : ScheduleJobCmdletBase
{
#region Parameters
private const string JobDefinitionParameterSet = "JobDefinition";
private const string JobDefinitionIdParameterSet = "JobDefinitionId";
private const string JobDefinitionNameParameterSet = "JobDefinitionName";
/// <summary>
/// Trigger number to get.
/// </summary>
[Parameter(Position = 1,
ParameterSetName = GetJobTriggerCommand.JobDefinitionParameterSet)]
[Parameter(Position = 1,
ParameterSetName = GetJobTriggerCommand.JobDefinitionIdParameterSet)]
[Parameter(Position = 1,
ParameterSetName = GetJobTriggerCommand.JobDefinitionNameParameterSet)]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public Int32[] TriggerId
{
get { return _triggerIds; }
set { _triggerIds = value; }
}
private Int32[] _triggerIds;
/// <summary>
/// ScheduledJobDefinition.
/// </summary>
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,
ParameterSetName = GetJobTriggerCommand.JobDefinitionParameterSet)]
[ValidateNotNull]
public ScheduledJobDefinition InputObject
{
get { return _definition; }
set { _definition = value; }
}
private ScheduledJobDefinition _definition;
/// <summary>
/// ScheduledJobDefintion Id.
/// </summary>
[Parameter(Position = 0, Mandatory = true,
ParameterSetName = GetJobTriggerCommand.JobDefinitionIdParameterSet)]
public Int32 Id
{
get { return _definitionId; }
set { _definitionId = value; }
}
private Int32 _definitionId;
/// <summary>
/// ScheduledJobDefinition Name.
/// </summary>
[Parameter(Position = 0, Mandatory = true,
ParameterSetName = GetJobTriggerCommand.JobDefinitionNameParameterSet)]
[ValidateNotNullOrEmpty]
public string Name
{
get { return _name; }
set { _name = value; }
}
private string _name;
#endregion
#region Cmdlet Overrides
/// <summary>
/// Process input.
/// </summary>
protected override void ProcessRecord()
{
switch (ParameterSetName)
{
case JobDefinitionParameterSet:
WriteTriggers(_definition);
break;
case JobDefinitionIdParameterSet:
WriteTriggers(GetJobDefinitionById(_definitionId));
break;
case JobDefinitionNameParameterSet:
WriteTriggers(GetJobDefinitionByName(_name));
break;
}
}
#endregion
#region Private Methods
private void WriteTriggers(ScheduledJobDefinition definition)
{
if (definition == null)
{
return;
}
List<Int32> notFoundIds;
List<ScheduledJobTrigger> triggers = definition.GetTriggers(_triggerIds, out notFoundIds);
// Write found trigger objects.
foreach (ScheduledJobTrigger trigger in triggers)
{
WriteObject(trigger);
}
// Report any triggers that were not found.
foreach (Int32 notFoundId in notFoundIds)
{
WriteTriggerNotFoundError(notFoundId, definition.Name, definition);
}
}
#endregion
}
}

View File

@ -0,0 +1,98 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Management.Automation;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This cmdlet gets scheduled job option object from a provided ScheduledJobDefinition object.
/// </summary>
[Cmdlet(VerbsCommon.Get, "ScheduledJobOption", DefaultParameterSetName = GetScheduledJobOptionCommand.JobDefinitionParameterSet,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=223920")]
[OutputType(typeof(ScheduledJobOptions))]
public sealed class GetScheduledJobOptionCommand : ScheduleJobCmdletBase
{
#region Parameters
private const string JobDefinitionParameterSet = "JobDefinition";
private const string JobDefinitionIdParameterSet = "JobDefinitionId";
private const string JobDefinitionNameParameterSet = "JobDefinitionName";
/// <summary>
/// ScheduledJobDefition Id.
/// </summary>
[Parameter(Position = 0, Mandatory = true,
ParameterSetName = GetScheduledJobOptionCommand.JobDefinitionIdParameterSet)]
public Int32 Id
{
get { return _id; }
set { _id = value; }
}
private Int32 _id;
/// <summary>
/// ScheduledJobDefinition Name.
/// </summary>
[Parameter(Position = 0, Mandatory = true, ValueFromPipelineByPropertyName = true,
ParameterSetName = GetScheduledJobOptionCommand.JobDefinitionNameParameterSet)]
[ValidateNotNullOrEmpty]
public string Name
{
get { return _name; }
set { _name = value; }
}
private string _name;
/// <summary>
/// ScheduledJobDefinition.
/// </summary>
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,
ParameterSetName = GetScheduledJobOptionCommand.JobDefinitionParameterSet)]
[ValidateNotNull]
public ScheduledJobDefinition InputObject
{
get { return _definition; }
set { _definition = value; }
}
private ScheduledJobDefinition _definition;
#endregion
#region Cmdlet Overrides
/// <summary>
/// Process input.
/// </summary>
protected override void ProcessRecord()
{
// Get ScheduledJobDefinition object.
ScheduledJobDefinition definition = null;
switch (ParameterSetName)
{
case JobDefinitionParameterSet:
definition = _definition;
break;
case JobDefinitionIdParameterSet:
definition = GetJobDefinitionById(_id);
break;
case JobDefinitionNameParameterSet:
definition = GetJobDefinitionByName(_name);
break;
}
// Return options from the definition object.
if (definition != null)
{
WriteObject(definition.Options);
}
}
#endregion
}
}

View File

@ -0,0 +1,327 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Management.Automation;
using System.Management.Automation.Internal;
using System.Management.Automation.Host;
using System.Threading;
using System.Diagnostics;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This cmdlet creates a new scheduled job trigger based on the provided
/// parameter values.
/// </summary>
[Cmdlet(VerbsCommon.New, "JobTrigger", DefaultParameterSetName = NewJobTriggerCommand.OnceParameterSet,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=223912")]
[OutputType(typeof(ScheduledJobTrigger))]
public sealed class NewJobTriggerCommand : ScheduleJobCmdletBase
{
#region Parameters
private const string AtLogonParameterSet = "AtLogon";
private const string AtStartupParameterSet = "AtStartup";
private const string OnceParameterSet = "Once";
private const string DailyParameterSet = "Daily";
private const string WeeklyParameterSet = "Weekly";
/// <summary>
/// Daily interval for trigger.
/// </summary>
[Parameter(ParameterSetName = NewJobTriggerCommand.DailyParameterSet)]
public Int32 DaysInterval
{
get { return _daysInterval; }
set { _daysInterval = value; }
}
private Int32 _daysInterval = 1;
/// <summary>
/// Weekly interval for trigger.
/// </summary>
[Parameter(ParameterSetName = NewJobTriggerCommand.WeeklyParameterSet)]
public Int32 WeeksInterval
{
get { return _weeksInterval; }
set { _weeksInterval = value; }
}
private Int32 _weeksInterval = 1;
/// <summary>
/// Random delay for trigger.
/// </summary>
[Parameter(ParameterSetName = NewJobTriggerCommand.AtLogonParameterSet)]
[Parameter(ParameterSetName = NewJobTriggerCommand.AtStartupParameterSet)]
[Parameter(ParameterSetName = NewJobTriggerCommand.OnceParameterSet)]
[Parameter(ParameterSetName = NewJobTriggerCommand.DailyParameterSet)]
[Parameter(ParameterSetName = NewJobTriggerCommand.WeeklyParameterSet)]
public TimeSpan RandomDelay
{
get { return _randomDelay; }
set { _randomDelay = value; }
}
private TimeSpan _randomDelay;
/// <summary>
/// Job start date/time for trigger.
/// </summary>
[Parameter(Mandatory = true,
ParameterSetName = NewJobTriggerCommand.OnceParameterSet)]
[Parameter(Mandatory = true,
ParameterSetName = NewJobTriggerCommand.DailyParameterSet)]
[Parameter(Mandatory = true,
ParameterSetName = NewJobTriggerCommand.WeeklyParameterSet)]
public DateTime At
{
get { return _atTime; }
set { _atTime = value; }
}
private DateTime _atTime;
/// <summary>
/// User name for AtLogon trigger. User name is used to determine which user
/// log on causes the trigger to activate.
/// </summary>
[Parameter(ParameterSetName = NewJobTriggerCommand.AtLogonParameterSet)]
[ValidateNotNullOrEmpty]
public string User
{
get { return _user; }
set { _user = value; }
}
private string _user;
/// <summary>
/// Days of week for trigger applies only to the Weekly parameter set.
/// Specifies which day(s) of the week the weekly trigger is activated.
/// </summary>
[Parameter(Mandatory = true, ParameterSetName = NewJobTriggerCommand.WeeklyParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public DayOfWeek[] DaysOfWeek
{
get { return _daysOfWeek; }
set { _daysOfWeek = value; }
}
private DayOfWeek[] _daysOfWeek;
/// <summary>
/// Switch to specify an AtStartup trigger.
/// </summary>
[Parameter(Mandatory = true, Position = 0,
ParameterSetName = NewJobTriggerCommand.AtStartupParameterSet)]
public SwitchParameter AtStartup
{
get { return _atStartup; }
set { _atStartup = value; }
}
private SwitchParameter _atStartup;
/// <summary>
/// Switch to specify an AtLogon trigger.
/// </summary>
[Parameter(Mandatory = true, Position = 0,
ParameterSetName = NewJobTriggerCommand.AtLogonParameterSet)]
public SwitchParameter AtLogOn
{
get { return _atLogon; }
set { _atLogon = value; }
}
private SwitchParameter _atLogon;
/// <summary>
/// Switch to specify a Once (one time) trigger.
/// </summary>
[Parameter(Mandatory = true, Position = 0,
ParameterSetName = NewJobTriggerCommand.OnceParameterSet)]
public SwitchParameter Once
{
get { return _once; }
set { _once = value; }
}
private SwitchParameter _once;
/// <summary>
/// Repetition interval of a one time trigger.
/// </summary>
[Parameter(ParameterSetName = NewJobTriggerCommand.OnceParameterSet)]
public TimeSpan RepetitionInterval
{
get { return _repInterval; }
set { _repInterval = value; }
}
private TimeSpan _repInterval;
/// <summary>
/// Repetition duration of a one time trigger.
/// </summary>
[Parameter(ParameterSetName = NewJobTriggerCommand.OnceParameterSet)]
public TimeSpan RepetitionDuration
{
get { return _repDuration; }
set { _repDuration = value; }
}
private TimeSpan _repDuration;
/// <summary>
/// Repetition interval repeats indefinitely.
/// </summary>
[Parameter(ParameterSetName = NewJobTriggerCommand.OnceParameterSet)]
public SwitchParameter RepeatIndefinitely
{
get { return _repRepeatIndefinitely; }
set { _repRepeatIndefinitely = value; }
}
private SwitchParameter _repRepeatIndefinitely;
/// <summary>
/// Switch to specify a Daily trigger.
/// </summary>
[Parameter(Mandatory = true, Position = 0,
ParameterSetName = NewJobTriggerCommand.DailyParameterSet)]
public SwitchParameter Daily
{
get { return _daily; }
set { _daily = value; }
}
private SwitchParameter _daily;
/// <summary>
/// Switch to specify a Weekly trigger.
/// </summary>
[Parameter(Mandatory = true, Position = 0,
ParameterSetName = NewJobTriggerCommand.WeeklyParameterSet)]
public SwitchParameter Weekly
{
get { return _weekly; }
set { _weekly = value; }
}
private SwitchParameter _weekly;
#endregion
#region Cmdlet Overrides
/// <summary>
/// Do begin processing.
/// </summary>
protected override void BeginProcessing()
{
base.BeginProcessing();
// Validate parameters.
if (_daysInterval < 1)
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidDaysIntervalParam);
}
if (_weeksInterval < 1)
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidWeeksIntervalParam);
}
}
/// <summary>
/// Process input.
/// </summary>
protected override void ProcessRecord()
{
switch (ParameterSetName)
{
case AtLogonParameterSet:
CreateAtLogonTrigger();
break;
case AtStartupParameterSet:
CreateAtStartupTrigger();
break;
case OnceParameterSet:
CreateOnceTrigger();
break;
case DailyParameterSet:
CreateDailyTrigger();
break;
case WeeklyParameterSet:
CreateWeeklyTrigger();
break;
}
}
#endregion
#region Private Methods
private void CreateAtLogonTrigger()
{
WriteObject(ScheduledJobTrigger.CreateAtLogOnTrigger(_user, _randomDelay, 0, true));
}
private void CreateAtStartupTrigger()
{
WriteObject(ScheduledJobTrigger.CreateAtStartupTrigger(_randomDelay, 0, true));
}
private void CreateOnceTrigger()
{
TimeSpan? repInterval = null;
TimeSpan? repDuration = null;
if (MyInvocation.BoundParameters.ContainsKey("RepetitionInterval") || MyInvocation.BoundParameters.ContainsKey("RepetitionDuration") ||
MyInvocation.BoundParameters.ContainsKey("RepeatIndefinitely"))
{
if (MyInvocation.BoundParameters.ContainsKey("RepeatIndefinitely"))
{
if (MyInvocation.BoundParameters.ContainsKey("RepetitionDuration"))
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidRepeatIndefinitelyParams);
}
if (!MyInvocation.BoundParameters.ContainsKey("RepetitionInterval"))
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidRepetitionRepeatParams);
}
_repDuration = TimeSpan.MaxValue;
}
else if (!MyInvocation.BoundParameters.ContainsKey("RepetitionInterval") || !MyInvocation.BoundParameters.ContainsKey("RepetitionDuration"))
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidRepetitionParams);
}
if (_repInterval < TimeSpan.Zero || _repDuration < TimeSpan.Zero)
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidRepetitionParamValues);
}
if (_repInterval < TimeSpan.FromMinutes(1))
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidRepetitionIntervalValue);
}
if (_repInterval > _repDuration)
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidRepetitionInterval);
}
repInterval = _repInterval;
repDuration = _repDuration;
}
WriteObject(ScheduledJobTrigger.CreateOnceTrigger(_atTime, _randomDelay, repInterval, repDuration, 0, true));
}
private void CreateDailyTrigger()
{
WriteObject(ScheduledJobTrigger.CreateDailyTrigger(_atTime, _daysInterval, _randomDelay, 0, true));
}
private void CreateWeeklyTrigger()
{
WriteObject(ScheduledJobTrigger.CreateWeeklyTrigger(_atTime, _weeksInterval, _daysOfWeek, _randomDelay, 0, true));
}
#endregion
}
}

View File

@ -0,0 +1,45 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Management.Automation;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This cmdlet creates a new scheduled job option object based on the provided
/// parameter values.
/// </summary>
[Cmdlet(VerbsCommon.New, "ScheduledJobOption", DefaultParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=223919")]
[OutputType(typeof(ScheduledJobOptions))]
public sealed class NewScheduledJobOptionCommand : ScheduledJobOptionCmdletBase
{
#region Cmdlet Overrides
/// <summary>
/// Process input.
/// </summary>
protected override void ProcessRecord()
{
WriteObject(new ScheduledJobOptions(
StartIfOnBattery,
!ContinueIfGoingOnBattery,
WakeToRun,
!StartIfIdle,
StopIfGoingOffIdle,
RestartOnIdleResume,
IdleDuration,
IdleTimeout,
!HideInTaskScheduler,
RunElevated,
!RequireNetwork,
DoNotAllowDemandStart,
MultipleInstancePolicy));
}
#endregion
}
}

View File

@ -0,0 +1,379 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using Microsoft.PowerShell.Commands;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This cmdlet creates a new scheduled job definition object based on the provided
/// parameter values and registers it with the Task Scheduler.
/// </summary>
[SuppressMessage("Microsoft.PowerShell", "PS1012:CallShouldProcessOnlyIfDeclaringSupport")]
[Cmdlet(VerbsLifecycle.Register, "ScheduledJob", SupportsShouldProcess = true, DefaultParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=223922")]
[OutputType(typeof(ScheduledJobDefinition))]
public sealed class RegisterScheduledJobCommand : ScheduleJobCmdletBase
{
#region Parameters
private const string FilePathParameterSet = "FilePath";
private const string ScriptBlockParameterSet = "ScriptBlock";
/// <summary>
/// File path for script to be run in job.
/// </summary>
[Parameter(Position = 1, Mandatory = true,
ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)]
[ValidateNotNullOrEmpty]
public string FilePath
{
get { return _filePath; }
set { _filePath = value; }
}
private string _filePath;
/// <summary>
/// ScriptBlock containing script to run in job.
/// </summary>
[Parameter(Position = 1, Mandatory = true,
ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)]
[ValidateNotNull]
public ScriptBlock ScriptBlock
{
get { return _scriptBlock; }
set { _scriptBlock = value; }
}
private ScriptBlock _scriptBlock;
/// <summary>
/// Name of scheduled job definition.
/// </summary>
[Parameter(Position = 0, Mandatory = true,
ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)]
[Parameter(Position = 0, Mandatory = true,
ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)]
[ValidateNotNullOrEmpty]
public string Name
{
get { return _name; }
set { _name = value; }
}
private string _name;
/// <summary>
/// Triggers to define when job will run.
/// </summary>
[Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)]
[Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public ScheduledJobTrigger[] Trigger
{
get { return _triggers; }
set { _triggers = value; }
}
private ScheduledJobTrigger[] _triggers;
/// <summary>
/// Initialization script to run before the job starts.
/// </summary>
[Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)]
[Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)]
[ValidateNotNull]
public ScriptBlock InitializationScript
{
get { return _initializationScript; }
set { _initializationScript = value; }
}
private ScriptBlock _initializationScript;
/// <summary>
/// Runs the job in a 32-bit PowerShell process.
/// </summary>
[Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)]
[Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)]
public SwitchParameter RunAs32
{
get { return _runAs32; }
set { _runAs32 = value; }
}
private SwitchParameter _runAs32;
/// <summary>
/// Credentials for job.
/// </summary>
[Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)]
[Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)]
[Credential()]
public PSCredential Credential
{
get { return _credential; }
set { _credential = value; }
}
private PSCredential _credential;
/// <summary>
/// Authentication mechanism to use for job.
/// </summary>
[Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)]
[Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)]
public AuthenticationMechanism Authentication
{
get { return _authenticationMechanism; }
set { _authenticationMechanism = value; }
}
private AuthenticationMechanism _authenticationMechanism;
/// <summary>
/// Scheduling options for job.
/// </summary>
[Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)]
[Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)]
[ValidateNotNull]
public ScheduledJobOptions ScheduledJobOption
{
get { return _options; }
set { _options = value; }
}
private ScheduledJobOptions _options;
/// <summary>
/// Argument list for FilePath parameter.
/// </summary>
[Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)]
[Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public object[] ArgumentList
{
get { return _arguments; }
set { _arguments = value; }
}
private object[] _arguments;
/// <summary>
/// Maximum number of job results allowed in job store.
/// </summary>
[Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)]
[Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)]
public int MaxResultCount
{
get { return _executionHistoryLength; }
set { _executionHistoryLength = value; }
}
private int _executionHistoryLength;
/// <summary>
/// Runs scheduled job immediately after successful registration.
/// </summary>
[Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)]
[Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)]
public SwitchParameter RunNow
{
get { return _runNow; }
set { _runNow = value; }
}
private SwitchParameter _runNow;
/// <summary>
/// Runs scheduled job at the repetition interval indicated by the
/// TimeSpan value for an unending duration.
/// </summary>
[Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)]
[Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)]
public TimeSpan RunEvery
{
get { return _runEvery; }
set { _runEvery = value; }
}
private TimeSpan _runEvery;
#endregion
#region Cmdlet Overrides
/// <summary>
/// Process input.
/// </summary>
protected override void ProcessRecord()
{
string targetString = StringUtil.Format(ScheduledJobErrorStrings.DefinitionWhatIf, Name);
if (!ShouldProcess(targetString, VerbsLifecycle.Register))
{
return;
}
ScheduledJobDefinition definition = null;
switch (ParameterSetName)
{
case ScriptBlockParameterSet:
definition = CreateScriptBlockDefinition();
break;
case FilePathParameterSet:
definition = CreateFilePathDefinition();
break;
}
if (definition != null)
{
// Set the MaxCount value if available.
if (MyInvocation.BoundParameters.ContainsKey("MaxResultCount"))
{
if (MaxResultCount < 1)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidMaxResultCount);
Exception reason = new RuntimeException(msg);
ErrorRecord errorRecord = new ErrorRecord(reason, "InvalidMaxResultCountParameterForRegisterScheduledJobDefinition", ErrorCategory.InvalidArgument, null);
WriteError(errorRecord);
return;
}
definition.SetExecutionHistoryLength(MaxResultCount, false);
}
try
{
// If RunEvery parameter is specified then create a job trigger for the definition that
// runs the job at the requested interval.
if (MyInvocation.BoundParameters.ContainsKey("RunEvery"))
{
AddRepetitionJobTriggerToDefinition(
definition,
RunEvery,
false);
}
definition.Register();
WriteObject(definition);
if (_runNow)
{
definition.RunAsTask();
}
}
catch (ScheduledJobException e)
{
// Check for access denied error.
if (e.InnerException != null && e.InnerException is System.UnauthorizedAccessException)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.UnauthorizedAccessError, definition.Name);
Exception reason = new RuntimeException(msg, e);
ErrorRecord errorRecord = new ErrorRecord(reason, "UnauthorizedAccessToRegisterScheduledJobDefinition", ErrorCategory.PermissionDenied, definition);
WriteError(errorRecord);
}
else if (e.InnerException != null && e.InnerException is System.IO.DirectoryNotFoundException)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.DirectoryNotFoundError, definition.Name);
Exception reason = new RuntimeException(msg, e);
ErrorRecord errorRecord = new ErrorRecord(reason, "DirectoryNotFoundWhenRegisteringScheduledJobDefinition", ErrorCategory.ObjectNotFound, definition);
WriteError(errorRecord);
}
else if (e.InnerException != null && e.InnerException is System.Runtime.Serialization.InvalidDataContractException)
{
string innerMsg = (!string.IsNullOrEmpty(e.InnerException.Message)) ? e.InnerException.Message : string.Empty;
string msg = StringUtil.Format(ScheduledJobErrorStrings.CannotSerializeData, definition.Name, innerMsg);
Exception reason = new RuntimeException(msg, e);
ErrorRecord errorRecord = new ErrorRecord(reason, "CannotSerializeDataWhenRegisteringScheduledJobDefinition", ErrorCategory.InvalidData, definition);
WriteError(errorRecord);
}
else
{
// Create record around known exception type.
ErrorRecord errorRecord = new ErrorRecord(e, "CantRegisterScheduledJobDefinition", ErrorCategory.InvalidOperation, definition);
WriteError(errorRecord);
}
}
}
}
#endregion
#region Private Methods
private ScheduledJobDefinition CreateScriptBlockDefinition()
{
JobDefinition jobDefinition = new JobDefinition(typeof(ScheduledJobSourceAdapter), ScriptBlock.ToString(), _name);
jobDefinition.ModuleName = ModuleName;
Dictionary<string, object> parameterCollection = CreateCommonParameters();
// ScriptBlock, mandatory
parameterCollection.Add(ScheduledJobInvocationInfo.ScriptBlockParameter, ScriptBlock);
JobInvocationInfo jobInvocationInfo = new ScheduledJobInvocationInfo(jobDefinition, parameterCollection);
ScheduledJobDefinition definition = new ScheduledJobDefinition(jobInvocationInfo, Trigger,
ScheduledJobOption, _credential);
return definition;
}
private ScheduledJobDefinition CreateFilePathDefinition()
{
JobDefinition jobDefinition = new JobDefinition(typeof(ScheduledJobSourceAdapter), FilePath, _name);
jobDefinition.ModuleName = ModuleName;
Dictionary<string, object> parameterCollection = CreateCommonParameters();
// FilePath, mandatory
if (!FilePath.EndsWith(".ps1", StringComparison.OrdinalIgnoreCase))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidFilePathFile);
Exception reason = new RuntimeException(msg);
ErrorRecord errorRecord = new ErrorRecord(reason, "InvalidFilePathParameterForRegisterScheduledJobDefinition", ErrorCategory.InvalidArgument, this);
WriteError(errorRecord);
return null;
}
Collection<PathInfo> pathInfos = SessionState.Path.GetResolvedPSPathFromPSPath(FilePath);
if (pathInfos.Count != 1)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidFilePath);
Exception reason = new RuntimeException(msg);
ErrorRecord errorRecord = new ErrorRecord(reason, "InvalidFilePathParameterForRegisterScheduledJobDefinition", ErrorCategory.InvalidArgument, this);
WriteError(errorRecord);
return null;
}
parameterCollection.Add(ScheduledJobInvocationInfo.FilePathParameter, pathInfos[0].Path);
JobInvocationInfo jobInvocationInfo = new ScheduledJobInvocationInfo(jobDefinition, parameterCollection);
ScheduledJobDefinition definition = new ScheduledJobDefinition(jobInvocationInfo, Trigger,
ScheduledJobOption, _credential);
return definition;
}
private Dictionary<string, object> CreateCommonParameters()
{
Dictionary<string, object> parameterCollection = new Dictionary<string, object>();
parameterCollection.Add(ScheduledJobInvocationInfo.RunAs32Parameter, RunAs32.ToBool());
parameterCollection.Add(ScheduledJobInvocationInfo.AuthenticationParameter, Authentication);
if (InitializationScript != null)
{
parameterCollection.Add(ScheduledJobInvocationInfo.InitializationScriptParameter, InitializationScript);
}
if (ArgumentList != null)
{
parameterCollection.Add(ScheduledJobInvocationInfo.ArgumentListParameter, ArgumentList);
}
return parameterCollection;
}
#endregion
}
}

View File

@ -0,0 +1,143 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Management.Automation;
using System.Management.Automation.Internal;
using System.Management.Automation.Host;
using System.Threading;
using System.Diagnostics;
using System.Globalization;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This cmdlet removes ScheduledJobTriggers from ScheduledJobDefinition objects.
/// </summary>
[Cmdlet(VerbsCommon.Remove, "JobTrigger", DefaultParameterSetName = RemoveJobTriggerCommand.JobDefinitionParameterSet,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=223914")]
public sealed class RemoveJobTriggerCommand : ScheduleJobCmdletBase
{
#region Parameters
private const string JobDefinitionParameterSet = "JobDefinition";
private const string JobDefinitionIdParameterSet = "JobDefinitionId";
private const string JobDefinitionNameParameterSet = "JobDefinitionName";
/// <summary>
/// Trigger number to remove.
/// </summary>
[Parameter(ParameterSetName = RemoveJobTriggerCommand.JobDefinitionParameterSet)]
[Parameter(ParameterSetName = RemoveJobTriggerCommand.JobDefinitionIdParameterSet)]
[Parameter(ParameterSetName = RemoveJobTriggerCommand.JobDefinitionNameParameterSet)]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public Int32[] TriggerId
{
get { return _triggerIds; }
set { _triggerIds = value; }
}
private Int32[] _triggerIds;
/// <summary>
/// ScheduledJobDefinition Id.
/// </summary>
[Parameter(Position = 0, Mandatory = true,
ParameterSetName = RemoveJobTriggerCommand.JobDefinitionIdParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public Int32[] Id
{
get { return _definitionIds; }
set { _definitionIds = value; }
}
private Int32[] _definitionIds;
/// <summary>
/// ScheduledJobDefintion Name.
/// </summary>
[Parameter(Position = 0, Mandatory = true,
ParameterSetName = RemoveJobTriggerCommand.JobDefinitionNameParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] Name
{
get { return _names; }
set { _names = value; }
}
private string[] _names;
/// <summary>
/// ScheduledJobDefinition.
/// </summary>
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,
ParameterSetName = RemoveJobTriggerCommand.JobDefinitionParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public ScheduledJobDefinition[] InputObject
{
get { return _definitions; }
set { _definitions = value; }
}
private ScheduledJobDefinition[] _definitions;
#endregion
#region Cmdlet Overrides
/// <summary>
/// Process input.
/// </summary>
protected override void ProcessRecord()
{
switch (ParameterSetName)
{
case JobDefinitionParameterSet:
RemoveFromJobDefinition(_definitions);
break;
case JobDefinitionIdParameterSet:
RemoveFromJobDefinition(GetJobDefinitionsById(_definitionIds));
break;
case JobDefinitionNameParameterSet:
RemoveFromJobDefinition(GetJobDefinitionsByName(_names));
break;
}
}
#endregion
#region Private Methods
private void RemoveFromJobDefinition(IEnumerable<ScheduledJobDefinition> definitions)
{
foreach (ScheduledJobDefinition definition in definitions)
{
List<Int32> notFoundIds = new List<int>();
try
{
notFoundIds = definition.RemoveTriggers(_triggerIds, true);
}
catch (ScheduledJobException e)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.CantRemoveTriggersFromDefinition, definition.Name);
Exception reason = new RuntimeException(msg, e);
ErrorRecord errorRecord = new ErrorRecord(reason, "CantRemoveTriggersFromScheduledJobDefinition", ErrorCategory.InvalidOperation, definition);
WriteError(errorRecord);
}
// Report not found errors.
foreach (Int32 idNotFound in notFoundIds)
{
WriteTriggerNotFoundError(idNotFound, definition.Name, definition);
}
}
}
#endregion
}
}

View File

@ -0,0 +1,467 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Management.Automation;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// Base class for ScheduledJob cmdlets.
/// </summary>
public abstract class ScheduleJobCmdletBase : PSCmdlet
{
#region Cmdlet Strings
/// <summary>
/// Scheduled job module name.
/// </summary>
protected const string ModuleName = "PSScheduledJob";
#endregion
#region Utility Methods
/// <summary>
/// Makes delegate callback call for each scheduledjob definition object found.
/// </summary>
/// <param name="itemFound">Callback delegate for each discovered item.</param>
internal void FindAllJobDefinitions(
Action<ScheduledJobDefinition> itemFound)
{
Dictionary<string, Exception> errors = ScheduledJobDefinition.RefreshRepositoryFromStore((definition) =>
{
if (ValidateJobDefinition(definition))
{
itemFound(definition);
}
});
HandleAllLoadErrors(errors);
}
/// <summary>
/// Returns a single ScheduledJobDefinition object from the local
/// scheduled job definition repository corresponding to the provided id.
/// </summary>
/// <param name="id">Local repository scheduled job definition id</param>
/// <param name="writeErrorsAndWarnings">Errors/warnings are written to host</param>
/// <returns>ScheduledJobDefinition object</returns>
internal ScheduledJobDefinition GetJobDefinitionById(
Int32 id,
bool writeErrorsAndWarnings = true)
{
Dictionary<string, Exception> errors = ScheduledJobDefinition.RefreshRepositoryFromStore(null);
HandleAllLoadErrors(errors);
foreach (var definition in ScheduledJobDefinition.Repository.Definitions)
{
if (definition.Id == id &&
ValidateJobDefinition(definition))
{
return definition;
}
}
if (writeErrorsAndWarnings)
{
WriteDefinitionNotFoundByIdError(id);
}
return null;
}
/// <summary>
/// Returns an array of ScheduledJobDefinition objects from the local
/// scheduled job definition repository corresponding to the provided Ids.
/// </summary>
/// <param name="ids">Local repository scheduled job definition ids</param>
/// <param name="writeErrorsAndWarnings">Errors/warnings are written to host</param>
/// <returns>List of ScheduledJobDefinition objects</returns>
internal List<ScheduledJobDefinition> GetJobDefinitionsById(
Int32[] ids,
bool writeErrorsAndWarnings = true)
{
Dictionary<string, Exception> errors = ScheduledJobDefinition.RefreshRepositoryFromStore(null);
HandleAllLoadErrors(errors);
List<ScheduledJobDefinition> definitions = new List<ScheduledJobDefinition>();
HashSet<Int32> findIds = new HashSet<Int32>(ids);
foreach (var definition in ScheduledJobDefinition.Repository.Definitions)
{
if (findIds.Contains(definition.Id) &&
ValidateJobDefinition(definition))
{
definitions.Add(definition);
findIds.Remove(definition.Id);
}
}
if (writeErrorsAndWarnings)
{
foreach (int id in findIds)
{
WriteDefinitionNotFoundByIdError(id);
}
}
return definitions;
}
/// <summary>
/// Makes delegate callback call for each scheduledjob definition object found.
/// </summary>
/// <param name="ids">Local repository scheduled job definition ids</param>
/// <param name="itemFound">Callback delegate for each discovered item.</param>
/// <param name="writeErrorsAndWarnings">Errors/warnings are written to host</param>
internal void FindJobDefinitionsById(
Int32[] ids,
Action<ScheduledJobDefinition> itemFound,
bool writeErrorsAndWarnings = true)
{
HashSet<Int32> findIds = new HashSet<Int32>(ids);
Dictionary<string, Exception> errors = ScheduledJobDefinition.RefreshRepositoryFromStore((definition) =>
{
if (findIds.Contains(definition.Id) &&
ValidateJobDefinition(definition))
{
itemFound(definition);
findIds.Remove(definition.Id);
}
});
HandleAllLoadErrors(errors);
if (writeErrorsAndWarnings)
{
foreach (Int32 id in findIds)
{
WriteDefinitionNotFoundByIdError(id);
}
}
}
/// <summary>
/// Returns an array of ScheduledJobDefinition objects from the local
/// scheduled job definition repository corresponding to the given name.
/// </summary>
/// <param name="name">Scheduled job definition name</param>
/// <param name="writeErrorsAndWarnings">Errors/warnings are written to host</param>
/// <returns>ScheduledJobDefinition object</returns>
internal ScheduledJobDefinition GetJobDefinitionByName(
string name,
bool writeErrorsAndWarnings = true)
{
Dictionary<string, Exception> errors = ScheduledJobDefinition.RefreshRepositoryFromStore(null);
// Look for match.
WildcardPattern namePattern = new WildcardPattern(name, WildcardOptions.IgnoreCase);
foreach (var definition in ScheduledJobDefinition.Repository.Definitions)
{
if (namePattern.IsMatch(definition.Name) &&
ValidateJobDefinition(definition))
{
return definition;
}
}
// Look for load error.
foreach (var error in errors)
{
if (namePattern.IsMatch(error.Key))
{
HandleLoadError(error.Key, error.Value);
}
}
if (writeErrorsAndWarnings)
{
WriteDefinitionNotFoundByNameError(name);
}
return null;
}
/// <summary>
/// Returns an array of ScheduledJobDefinition objects from the local
/// scheduled job definition repository corresponding to the given names.
/// </summary>
/// <param name="names">Scheduled job definition names</param>
/// <param name="writeErrorsAndWarnings">Errors/warnings are written to host</param>
/// <returns>List of ScheduledJobDefinition objects</returns>
internal List<ScheduledJobDefinition> GetJobDefinitionsByName(
string[] names,
bool writeErrorsAndWarnings = true)
{
Dictionary<string, Exception> errors = ScheduledJobDefinition.RefreshRepositoryFromStore(null);
List<ScheduledJobDefinition> definitions = new List<ScheduledJobDefinition>();
foreach (string name in names)
{
WildcardPattern namePattern = new WildcardPattern(name, WildcardOptions.IgnoreCase);
// Look for match.
bool nameFound = false;
foreach (var definition in ScheduledJobDefinition.Repository.Definitions)
{
if (namePattern.IsMatch(definition.Name) &&
ValidateJobDefinition(definition))
{
nameFound = true;
definitions.Add(definition);
}
}
// Look for load error.
foreach (var error in errors)
{
if (namePattern.IsMatch(error.Key))
{
HandleLoadError(error.Key, error.Value);
}
}
if (!nameFound && writeErrorsAndWarnings)
{
WriteDefinitionNotFoundByNameError(name);
}
}
return definitions;
}
/// <summary>
/// Makes delegate callback call for each scheduledjob definition object found.
/// </summary>
/// <param name="names">Scheduled job definition names</param>
/// <param name="itemFound">Callback delegate for each discovered item.</param>
/// <param name="writeErrorsAndWarnings">Errors/warnings are written to host</param>
internal void FindJobDefinitionsByName(
string[] names,
Action<ScheduledJobDefinition> itemFound,
bool writeErrorsAndWarnings = true)
{
HashSet<string> notFoundNames = new HashSet<string>(names);
Dictionary<string, WildcardPattern> patterns = new Dictionary<string, WildcardPattern>();
foreach (string name in names)
{
if (!patterns.ContainsKey(name))
{
patterns.Add(name, new WildcardPattern(name, WildcardOptions.IgnoreCase));
}
}
Dictionary<string, Exception> errors = ScheduledJobDefinition.RefreshRepositoryFromStore((definition) =>
{
foreach (var item in patterns)
{
if (item.Value.IsMatch(definition.Name) &&
ValidateJobDefinition(definition))
{
itemFound(definition);
if (notFoundNames.Contains(item.Key))
{
notFoundNames.Remove(item.Key);
}
}
}
});
// Look for load error.
foreach (var error in errors)
{
foreach (var item in patterns)
{
if (item.Value.IsMatch(error.Key))
{
HandleLoadError(error.Key, error.Value);
}
}
}
if (writeErrorsAndWarnings)
{
foreach (var name in notFoundNames)
{
WriteDefinitionNotFoundByNameError(name);
}
}
}
/// <summary>
/// Writes a "Trigger not found" error to host.
/// </summary>
/// <param name="notFoundId">Trigger Id not found</param>
/// <param name="definitionName">ScheduledJobDefinition name</param>
/// <param name="errorObject">Error object</param>
internal void WriteTriggerNotFoundError(
Int32 notFoundId,
string definitionName,
object errorObject)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.TriggerNotFound, notFoundId, definitionName);
Exception reason = new RuntimeException(msg);
ErrorRecord errorRecord = new ErrorRecord(reason, "ScheduledJobTriggerNotFound", ErrorCategory.ObjectNotFound, errorObject);
WriteError(errorRecord);
}
/// <summary>
/// Writes a "Definition not found for Id" error to host.
/// </summary>
/// <param name="defId">Definition Id</param>
internal void WriteDefinitionNotFoundByIdError(
Int32 defId)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.DefinitionNotFoundById, defId);
Exception reason = new RuntimeException(msg);
ErrorRecord errorRecord = new ErrorRecord(reason, "ScheduledJobDefinitionNotFoundById", ErrorCategory.ObjectNotFound, null);
WriteError(errorRecord);
}
/// <summary>
/// Writes a "Definition not found for Name" error to host.
/// </summary>
/// <param name="name">Definition Name</param>
internal void WriteDefinitionNotFoundByNameError(
string name)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.DefinitionNotFoundByName, name);
Exception reason = new RuntimeException(msg);
ErrorRecord errorRecord = new ErrorRecord(reason, "ScheduledJobDefinitionNotFoundByName", ErrorCategory.ObjectNotFound, null);
WriteError(errorRecord);
}
/// <summary>
/// Writes a "Load from job store" error to host.
/// </summary>
/// <param name="name">Scheduled job definition name</param>
/// <param name="error">Exception thrown during loading</param>
internal void WriteErrorLoadingDefinition(string name, Exception error)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.CantLoadDefinitionFromStore, name);
Exception reason = new RuntimeException(msg, error);
ErrorRecord errorRecord = new ErrorRecord(reason, "CantLoadScheduledJobDefinitionFromStore", ErrorCategory.InvalidOperation, null);
WriteError(errorRecord);
}
/// <summary>
/// Creates a Once job trigger with provided repetition interval and an
/// infinite duration, and adds the trigger to the provided scheduled job
/// definition object.
/// </summary>
/// <param name="definition">ScheduledJobDefinition</param>
/// <param name="repInterval">rep interval</param>
/// <param name="save">save definition change</param>
internal static void AddRepetitionJobTriggerToDefinition(
ScheduledJobDefinition definition,
TimeSpan repInterval,
bool save)
{
if (definition == null)
{
throw new PSArgumentNullException("definition");
}
TimeSpan repDuration = TimeSpan.MaxValue;
// Validate every interval value.
if (repInterval < TimeSpan.Zero || repDuration < TimeSpan.Zero)
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidRepetitionParamValues);
}
if (repInterval < TimeSpan.FromMinutes(1))
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidRepetitionIntervalValue);
}
if (repInterval > repDuration)
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidRepetitionInterval);
}
// Create job trigger.
var trigger = ScheduledJobTrigger.CreateOnceTrigger(
DateTime.Now,
TimeSpan.Zero,
repInterval,
repDuration,
0,
true);
definition.AddTriggers(new ScheduledJobTrigger[] { trigger }, save);
}
#endregion
#region Private Methods
private void HandleAllLoadErrors(Dictionary<string, Exception> errors)
{
foreach (var error in errors)
{
HandleLoadError(error.Key, error.Value);
}
}
private void HandleLoadError(string name, Exception e)
{
if (e is System.IO.IOException ||
e is System.Xml.XmlException ||
e is System.TypeInitializationException ||
e is System.Runtime.Serialization.SerializationException ||
e is System.ArgumentNullException)
{
// Remove the corrupted scheduled job definition and
// notify user with error message.
ScheduledJobDefinition.RemoveDefinition(name);
WriteErrorLoadingDefinition(name, e);
}
}
private void ValidateJobDefinitions()
{
foreach (var definition in ScheduledJobDefinition.Repository.Definitions)
{
ValidateJobDefinition(definition);
}
}
/// <summary>
/// Validates the job definition object retrieved from store by syncing
/// its data with the corresponding Task Scheduler task. If no task
/// is found then validation fails.
/// </summary>
/// <param name="definition"></param>
/// <returns></returns>
private bool ValidateJobDefinition(ScheduledJobDefinition definition)
{
Exception ex = null;
try
{
definition.SyncWithWTS();
}
catch (System.IO.DirectoryNotFoundException e)
{
ex = e;
}
catch (System.IO.FileNotFoundException e)
{
ex = e;
}
catch (System.ArgumentNullException e)
{
ex = e;
}
if (ex != null)
{
WriteErrorLoadingDefinition(definition.Name, ex);
}
return (ex == null);
}
#endregion
}
}

View File

@ -0,0 +1,194 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Management.Automation;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// Base class for NewScheduledJobOption, SetScheduledJobOption cmdlets.
/// </summary>
public abstract class ScheduledJobOptionCmdletBase : ScheduleJobCmdletBase
{
#region Parameters
/// <summary>
/// Options parameter set name.
/// </summary>
protected const string OptionsParameterSet = "Options";
/// <summary>
/// Scheduled job task is run with elevated privileges when this switch is selected.
/// </summary>
[Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)]
public SwitchParameter RunElevated
{
get { return _runElevated; }
set { _runElevated = value; }
}
private SwitchParameter _runElevated = false;
/// <summary>
/// Scheduled job task is hidden in Windows Task Scheduler when true.
/// </summary>
[Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)]
public SwitchParameter HideInTaskScheduler
{
get { return _hideInTaskScheduler; }
set { _hideInTaskScheduler = value; }
}
private SwitchParameter _hideInTaskScheduler = false;
/// <summary>
/// Scheduled job task will be restarted when machine becomes idle. This is applicable
/// only if the job was configured to stop when no longer idle.
/// </summary>
[Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)]
public SwitchParameter RestartOnIdleResume
{
get { return _restartOnIdleResume; }
set { _restartOnIdleResume = value; }
}
private SwitchParameter _restartOnIdleResume = false;
/// <summary>
/// Provides task scheduler options for multiple running instances of the job.
/// </summary>
[Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)]
public TaskMultipleInstancePolicy MultipleInstancePolicy
{
get { return _multipleInstancePolicy; }
set { _multipleInstancePolicy = value; }
}
private TaskMultipleInstancePolicy _multipleInstancePolicy = TaskMultipleInstancePolicy.IgnoreNew;
/// <summary>
/// Prevents the job task from being started manually via Task Scheduler UI.
/// </summary>
[Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)]
public SwitchParameter DoNotAllowDemandStart
{
get { return _doNotAllowDemandStart; }
set { _doNotAllowDemandStart = value; }
}
private SwitchParameter _doNotAllowDemandStart = false;
/// <summary>
/// Allows the job task to be run only when network connection available.
/// </summary>
[Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)]
public SwitchParameter RequireNetwork
{
get { return _requireNetwork; }
set { _requireNetwork = value; }
}
private SwitchParameter _requireNetwork = false;
/// <summary>
/// Stops running job started by Task Scheduler if computer is no longer idle.
/// </summary>
[Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)]
public SwitchParameter StopIfGoingOffIdle
{
get { return _stopIfGoingOffIdle; }
set { _stopIfGoingOffIdle = value; }
}
private SwitchParameter _stopIfGoingOffIdle = false;
/// <summary>
/// Will wake the computer to run the job if computer is in sleep mode when
/// trigger activates.
/// </summary>
[Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)]
public SwitchParameter WakeToRun
{
get { return _wakeToRun; }
set { _wakeToRun = value; }
}
private SwitchParameter _wakeToRun = false;
/// <summary>
/// Continue running task job if computer going on battery.
/// </summary>
[Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)]
public SwitchParameter ContinueIfGoingOnBattery
{
get { return _continueIfGoingOnBattery; }
set { _continueIfGoingOnBattery = value; }
}
private SwitchParameter _continueIfGoingOnBattery = false;
/// <summary>
/// Will start job task even if computer is running on battery power.
/// </summary>
[Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)]
public SwitchParameter StartIfOnBattery
{
get { return _startIfOnBattery; }
set { _startIfOnBattery = value; }
}
private SwitchParameter _startIfOnBattery = false;
/// <summary>
/// Specifies how long Task Scheduler will wait for idle time after a trigger has
/// activated before giving up trying to run job during computer idle.
/// </summary>
[Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)]
public TimeSpan IdleTimeout
{
get { return _idleTimeout; }
set { _idleTimeout = value; }
}
private TimeSpan _idleTimeout = new TimeSpan(1, 0, 0);
/// <summary>
/// How long the computer needs to be idle before a triggered job task is started.
/// </summary>
[Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)]
public TimeSpan IdleDuration
{
get { return _idleDuration; }
set { _idleDuration = value; }
}
private TimeSpan _idleDuration = new TimeSpan(0, 10, 0);
/// <summary>
/// Will start job task if machine is idle.
/// </summary>
[Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)]
public SwitchParameter StartIfIdle
{
get { return _startIfIdle; }
set { _startIfIdle = value; }
}
private SwitchParameter _startIfIdle = false;
#endregion
#region Cmdlet Overrides
/// <summary>
/// Begin processing.
/// </summary>
protected override void BeginProcessing()
{
// Validate parameters.
if (MyInvocation.BoundParameters.ContainsKey("IdleTimeout") &&
_idleTimeout < TimeSpan.Zero)
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidIdleTimeout);
}
if (MyInvocation.BoundParameters.ContainsKey("IdleDuration") &&
_idleDuration < TimeSpan.Zero)
{
throw new PSArgumentException(ScheduledJobErrorStrings.InvalidIdleDuration);
}
}
#endregion
}
}

View File

@ -0,0 +1,521 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This cmdlet updates a scheduled job definition object based on the provided
/// parameter values and saves changes to job store and Task Scheduler.
/// </summary>
[Cmdlet(VerbsCommon.Set, "ScheduledJob", DefaultParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=223924")]
[OutputType(typeof(ScheduledJobDefinition))]
public sealed class SetScheduledJobCommand : ScheduleJobCmdletBase
{
#region Parameters
private const string ExecutionParameterSet = "Execution";
private const string ScriptBlockParameterSet = "ScriptBlock";
private const string FilePathParameterSet = "FilePath";
/// <summary>
/// Name of scheduled job definition.
/// </summary>
[Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)]
[Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)]
[ValidateNotNullOrEmpty]
public string Name
{
get { return _name; }
set { _name = value; }
}
private string _name;
/// <summary>
/// File path for script to be run in job.
/// </summary>
[Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)]
[ValidateNotNullOrEmpty]
public string FilePath
{
get { return _filePath; }
set { _filePath = value; }
}
private string _filePath;
/// <summary>
/// ScriptBlock containing script to run in job.
/// </summary>
[Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)]
[ValidateNotNull]
public ScriptBlock ScriptBlock
{
get { return _scriptBlock; }
set { _scriptBlock = value; }
}
private ScriptBlock _scriptBlock;
/// <summary>
/// Triggers to define when job will run.
/// </summary>
[Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)]
[Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public ScheduledJobTrigger[] Trigger
{
get { return _triggers; }
set { _triggers = value; }
}
private ScheduledJobTrigger[] _triggers;
/// <summary>
/// Initialization script to run before the job starts.
/// </summary>
[Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)]
[Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)]
[ValidateNotNull]
public ScriptBlock InitializationScript
{
get { return _initializationScript; }
set { _initializationScript = value; }
}
private ScriptBlock _initializationScript;
/// <summary>
/// Runs the job in a 32-bit PowerShell process.
/// </summary>
[Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)]
[Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)]
public SwitchParameter RunAs32
{
get { return _runAs32; }
set { _runAs32 = value; }
}
private SwitchParameter _runAs32;
/// <summary>
/// Credentials for job.
/// </summary>
[Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)]
[Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)]
[Credential()]
public PSCredential Credential
{
get { return _credential; }
set { _credential = value; }
}
private PSCredential _credential;
/// <summary>
/// Authentication mechanism to use for job.
/// </summary>
[Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)]
[Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)]
public AuthenticationMechanism Authentication
{
get { return _authenticationMechanism; }
set { _authenticationMechanism = value; }
}
private AuthenticationMechanism _authenticationMechanism;
/// <summary>
/// Scheduling options for job.
/// </summary>
[Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)]
[Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)]
[ValidateNotNull]
public ScheduledJobOptions ScheduledJobOption
{
get { return _options; }
set { _options = value; }
}
private ScheduledJobOptions _options;
/// <summary>
/// Input for the job.
/// </summary>
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,
ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)]
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,
ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)]
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,
ParameterSetName = SetScheduledJobCommand.ExecutionParameterSet)]
[ValidateNotNull]
public ScheduledJobDefinition InputObject
{
get { return _definition; }
set { _definition = value; }
}
private ScheduledJobDefinition _definition;
/// <summary>
/// ClearExecutionHistory
/// </summary>
[Parameter(ParameterSetName = SetScheduledJobCommand.ExecutionParameterSet)]
public SwitchParameter ClearExecutionHistory
{
get { return _clearExecutionHistory; }
set { _clearExecutionHistory = value; }
}
private SwitchParameter _clearExecutionHistory;
/// <summary>
/// Maximum number of job results allowed in job store.
/// </summary>
[Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)]
[Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)]
public int MaxResultCount
{
get { return _executionHistoryLength; }
set { _executionHistoryLength = value; }
}
private int _executionHistoryLength;
/// <summary>
/// Pass the ScheduledJobDefinition object through to output.
/// </summary>
[Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)]
[Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)]
[Parameter(ParameterSetName = SetScheduledJobCommand.ExecutionParameterSet)]
public SwitchParameter PassThru
{
get { return _passThru; }
set { _passThru = value; }
}
private SwitchParameter _passThru;
/// <summary>
/// Argument list.
/// </summary>
[Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)]
[Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public object[] ArgumentList
{
get { return _arguments; }
set { _arguments = value; }
}
private object[] _arguments;
/// <summary>
/// Runs scheduled job immediately after successfully setting job definition.
/// </summary>
[Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)]
[Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)]
public SwitchParameter RunNow
{
get { return _runNow; }
set { _runNow = value; }
}
private SwitchParameter _runNow;
/// <summary>
/// Runs scheduled job at the repetition interval indicated by the
/// TimeSpan value for an unending duration.
/// </summary>
[Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)]
[Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)]
public TimeSpan RunEvery
{
get { return _runEvery; }
set { _runEvery = value; }
}
private TimeSpan _runEvery;
#endregion
#region Cmdlet Overrides
/// <summary>
/// Process input.
/// </summary>
protected override void ProcessRecord()
{
switch (ParameterSetName)
{
case ExecutionParameterSet:
UpdateExecutionDefinition();
break;
case ScriptBlockParameterSet:
case FilePathParameterSet:
UpdateDefinition();
break;
}
try
{
// If RunEvery parameter is specified then create a job trigger for the definition that
// runs the job at the requested interval.
bool addedTrigger = false;
if (MyInvocation.BoundParameters.ContainsKey("RunEvery"))
{
AddRepetitionJobTriggerToDefinition(
_definition,
RunEvery,
false);
addedTrigger = true;
}
if (Trigger != null || ScheduledJobOption != null || Credential != null || addedTrigger)
{
// Save definition to file and update WTS.
_definition.Save();
}
else
{
// No WTS changes. Save definition to store only.
_definition.SaveToStore();
}
if (_runNow)
{
_definition.RunAsTask();
}
}
catch (ScheduledJobException e)
{
ErrorRecord errorRecord;
if (e.InnerException != null &&
e.InnerException is System.UnauthorizedAccessException)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.NoAccessOnSetJobDefinition, _definition.Name);
errorRecord = new ErrorRecord(new RuntimeException(msg, e),
"NoAccessFailureOnSetJobDefinition", ErrorCategory.InvalidOperation, _definition);
}
else if (e.InnerException != null &&
e.InnerException is System.IO.IOException)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.IOFailureOnSetJobDefinition, _definition.Name);
errorRecord = new ErrorRecord(new RuntimeException(msg, e),
"IOFailureOnSetJobDefinition", ErrorCategory.InvalidOperation, _definition);
}
else
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.CantSetJobDefinition, _definition.Name);
errorRecord = new ErrorRecord(new RuntimeException(msg, e),
"CantSetPropertiesToScheduledJobDefinition", ErrorCategory.InvalidOperation, _definition);
}
WriteError(errorRecord);
}
if (_passThru)
{
WriteObject(_definition);
}
}
#endregion
#region Private Methods
private void UpdateExecutionDefinition()
{
if (_clearExecutionHistory)
{
_definition.ClearExecutionHistory();
}
}
private void UpdateDefinition()
{
if (_name != null &&
string.Compare(_name, _definition.Name, StringComparison.OrdinalIgnoreCase) != 0)
{
_definition.RenameAndSave(_name);
}
UpdateJobInvocationInfo();
if (MyInvocation.BoundParameters.ContainsKey("MaxResultCount"))
{
_definition.SetExecutionHistoryLength(MaxResultCount, false);
}
if (Credential != null)
{
_definition.Credential = Credential;
}
if (Trigger != null)
{
_definition.SetTriggers(Trigger, false);
}
if (ScheduledJobOption != null)
{
_definition.UpdateOptions(ScheduledJobOption, false);
}
}
/// <summary>
/// Create new ScheduledJobInvocationInfo object with update information and
/// update the job defintion object.
/// </summary>
private void UpdateJobInvocationInfo()
{
Dictionary<string, object> parameters = UpdateParameters();
string name = _definition.Name;
string command;
if (ScriptBlock != null)
{
command = ScriptBlock.ToString();
}
else if (FilePath != null)
{
command = FilePath;
}
else
{
command = _definition.InvocationInfo.Command;
}
JobDefinition jobDefinition = new JobDefinition(typeof(ScheduledJobSourceAdapter), command, name);
jobDefinition.ModuleName = ModuleName;
JobInvocationInfo jobInvocationInfo = new ScheduledJobInvocationInfo(jobDefinition, parameters);
_definition.UpdateJobInvocationInfo(jobInvocationInfo, false);
}
/// <summary>
/// Creates a new parameter dictionary with update parameters.
/// </summary>
/// <returns>Updated parameters.</returns>
private Dictionary<string, object> UpdateParameters()
{
Debug.Assert(_definition.InvocationInfo.Parameters.Count != 0,
"ScheduledJobDefinition must always have some job invocation parameters");
Dictionary<string, object> newParameters = new Dictionary<string, object>();
foreach (CommandParameter parameter in _definition.InvocationInfo.Parameters[0])
{
newParameters.Add(parameter.Name, parameter.Value);
}
// RunAs32
if (MyInvocation.BoundParameters.ContainsKey("RunAs32"))
{
if (newParameters.ContainsKey(ScheduledJobInvocationInfo.RunAs32Parameter))
{
newParameters[ScheduledJobInvocationInfo.RunAs32Parameter] = RunAs32.ToBool();
}
else
{
newParameters.Add(ScheduledJobInvocationInfo.RunAs32Parameter, RunAs32.ToBool());
}
}
// Authentication
if (MyInvocation.BoundParameters.ContainsKey("Authentication"))
{
if (newParameters.ContainsKey(ScheduledJobInvocationInfo.AuthenticationParameter))
{
newParameters[ScheduledJobInvocationInfo.AuthenticationParameter] = Authentication;
}
else
{
newParameters.Add(ScheduledJobInvocationInfo.AuthenticationParameter, Authentication);
}
}
// InitializationScript
if (InitializationScript == null)
{
if (newParameters.ContainsKey(ScheduledJobInvocationInfo.InitializationScriptParameter))
{
newParameters.Remove(ScheduledJobInvocationInfo.InitializationScriptParameter);
}
}
else
{
if (newParameters.ContainsKey(ScheduledJobInvocationInfo.InitializationScriptParameter))
{
newParameters[ScheduledJobInvocationInfo.InitializationScriptParameter] = InitializationScript;
}
else
{
newParameters.Add(ScheduledJobInvocationInfo.InitializationScriptParameter, InitializationScript);
}
}
// ScriptBlock
if (ScriptBlock != null)
{
// FilePath cannot also be specified.
if (newParameters.ContainsKey(ScheduledJobInvocationInfo.FilePathParameter))
{
newParameters.Remove(ScheduledJobInvocationInfo.FilePathParameter);
}
if (newParameters.ContainsKey(ScheduledJobInvocationInfo.ScriptBlockParameter))
{
newParameters[ScheduledJobInvocationInfo.ScriptBlockParameter] = ScriptBlock;
}
else
{
newParameters.Add(ScheduledJobInvocationInfo.ScriptBlockParameter, ScriptBlock);
}
}
// FilePath
if (FilePath != null)
{
// ScriptBlock cannot also be specified.
if (newParameters.ContainsKey(ScheduledJobInvocationInfo.ScriptBlockParameter))
{
newParameters.Remove(ScheduledJobInvocationInfo.ScriptBlockParameter);
}
if (newParameters.ContainsKey(ScheduledJobInvocationInfo.FilePathParameter))
{
newParameters[ScheduledJobInvocationInfo.FilePathParameter] = FilePath;
}
else
{
newParameters.Add(ScheduledJobInvocationInfo.FilePathParameter, FilePath);
}
}
// ArgumentList
if (ArgumentList == null)
{
// Clear existing argument list only if new scriptblock or script file path was specified
// (in this case old argument list is invalid).
if (newParameters.ContainsKey(ScheduledJobInvocationInfo.ArgumentListParameter) &&
(ScriptBlock != null || FilePath != null))
{
newParameters.Remove(ScheduledJobInvocationInfo.ArgumentListParameter);
}
}
else
{
if (newParameters.ContainsKey(ScheduledJobInvocationInfo.ArgumentListParameter))
{
newParameters[ScheduledJobInvocationInfo.ArgumentListParameter] = ArgumentList;
}
else
{
newParameters.Add(ScheduledJobInvocationInfo.ArgumentListParameter, ArgumentList);
}
}
return newParameters;
}
#endregion
}
}

View File

@ -0,0 +1,900 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Management.Automation;
using System.Diagnostics;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This cmdlet sets properties on a trigger for a ScheduledJobDefinition.
/// </summary>
[Cmdlet(VerbsCommon.Set, "JobTrigger", DefaultParameterSetName = SetJobTriggerCommand.DefaultParameterSet,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=223916")]
[OutputType(typeof(ScheduledJobTrigger))]
public sealed class SetJobTriggerCommand : ScheduleJobCmdletBase
{
#region Parameters
private const string DefaultParameterSet = "DefaultParams";
/// <summary>
/// ScheduledJobTrigger objects to set properties on.
/// </summary>
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,
ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public ScheduledJobTrigger[] InputObject
{
get { return _triggers; }
set { _triggers = value; }
}
private ScheduledJobTrigger[] _triggers;
/// <summary>
/// Daily interval for trigger.
/// </summary>
[Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)]
public Int32 DaysInterval
{
get { return _daysInterval; }
set { _daysInterval = value; }
}
private Int32 _daysInterval = 1;
/// <summary>
/// Weekly interval for trigger.
/// </summary>
[Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)]
public Int32 WeeksInterval
{
get { return _weeksInterval; }
set { _weeksInterval = value; }
}
private Int32 _weeksInterval = 1;
/// <summary>
/// Random delay for trigger.
/// </summary>
[Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)]
public TimeSpan RandomDelay
{
get { return _randomDelay; }
set { _randomDelay = value; }
}
private TimeSpan _randomDelay;
/// <summary>
/// Job start date/time for trigger.
/// </summary>
[Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)]
public DateTime At
{
get { return _atTime; }
set { _atTime = value; }
}
private DateTime _atTime;
/// <summary>
/// User name for AtLogon trigger. The AtLogon parameter set will create a trigger
/// that activates after log on for the provided user name.
/// </summary>
[Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)]
[ValidateNotNullOrEmpty]
public string User
{
get { return _user; }
set { _user = value; }
}
private string _user;
/// <summary>
/// Days of week for trigger.
/// </summary>
[Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public DayOfWeek[] DaysOfWeek
{
get { return _daysOfWeek; }
set { _daysOfWeek = value; }
}
private DayOfWeek[] _daysOfWeek;
/// <summary>
/// Switch to specify an AtStartup trigger.
/// </summary>
[Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)]
public SwitchParameter AtStartup
{
get { return _atStartup; }
set { _atStartup = value; }
}
private SwitchParameter _atStartup;
/// <summary>
/// Switch to specify an AtLogon trigger.
/// </summary>
[Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)]
public SwitchParameter AtLogOn
{
get { return _atLogon; }
set { _atLogon = value; }
}
private SwitchParameter _atLogon;
/// <summary>
/// Switch to specify an Once trigger.
/// </summary>
[Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)]
public SwitchParameter Once
{
get { return _once; }
set { _once = value; }
}
private SwitchParameter _once;
/// <summary>
/// Repetition interval of a one time trigger.
/// </summary>
[Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)]
public TimeSpan RepetitionInterval
{
get { return _repInterval; }
set { _repInterval = value; }
}
private TimeSpan _repInterval;
/// <summary>
/// Repetition duration of a one time trigger.
/// </summary>
[Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)]
public TimeSpan RepetitionDuration
{
get { return _repDuration; }
set { _repDuration = value; }
}
private TimeSpan _repDuration;
/// <summary>
/// Repetition interval repeats indefinitely.
/// </summary>
[Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)]
public SwitchParameter RepeatIndefinitely
{
get { return _repRepeatIndefinitely; }
set { _repRepeatIndefinitely = value; }
}
private SwitchParameter _repRepeatIndefinitely;
/// <summary>
/// Switch to specify an Daily trigger.
/// </summary>
[Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)]
public SwitchParameter Daily
{
get { return _daily; }
set { _daily = value; }
}
private SwitchParameter _daily;
/// <summary>
/// Switch to specify an Weekly trigger.
/// </summary>
[Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)]
public SwitchParameter Weekly
{
get { return _weekly; }
set { _weekly = value; }
}
private SwitchParameter _weekly;
/// <summary>
/// Pass through job trigger object.
/// </summary>
[Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)]
public SwitchParameter PassThru
{
get { return _passThru; }
set { _passThru = value; }
}
private SwitchParameter _passThru;
#endregion
#region Cmdlet Overrides
/// <summary>
/// Process input.
/// </summary>
protected override void ProcessRecord()
{
// Validate the parameter set and write any errors.
TriggerFrequency newTriggerFrequency = TriggerFrequency.None;
if (!ValidateParameterSet(ref newTriggerFrequency))
{
return;
}
// Update each trigger object with the current parameter set.
// The associated scheduled job definition will also be updated.
foreach (ScheduledJobTrigger trigger in _triggers)
{
ScheduledJobTrigger originalTrigger = new ScheduledJobTrigger(trigger);
if (!UpdateTrigger(trigger, newTriggerFrequency))
{
continue;
}
ScheduledJobDefinition definition = trigger.JobDefinition;
if (definition != null)
{
bool jobUpdateFailed = false;
try
{
trigger.UpdateJobDefinition();
}
catch (ScheduledJobException e)
{
jobUpdateFailed = true;
string msg = StringUtil.Format(ScheduledJobErrorStrings.CantUpdateTriggerOnJobDef, definition.Name, trigger.Id);
Exception reason = new RuntimeException(msg, e);
ErrorRecord errorRecord = new ErrorRecord(reason, "CantSetPropertiesOnJobTrigger", ErrorCategory.InvalidOperation, trigger);
WriteError(errorRecord);
}
if (jobUpdateFailed)
{
// Restore trigger to original configuration.
originalTrigger.CopyTo(trigger);
}
}
if (_passThru)
{
WriteObject(trigger);
}
}
}
#endregion
#region Private Methods
private bool ValidateParameterSet(ref TriggerFrequency newTriggerFrequency)
{
// First see if a switch parameter was set.
List<TriggerFrequency> switchParamList = new List<TriggerFrequency>();
if (MyInvocation.BoundParameters.ContainsKey(_paramAtStartup))
{
switchParamList.Add(TriggerFrequency.AtStartup);
}
if (MyInvocation.BoundParameters.ContainsKey(_paramAtLogon))
{
switchParamList.Add(TriggerFrequency.AtLogon);
}
if (MyInvocation.BoundParameters.ContainsKey(_paramOnce))
{
switchParamList.Add(TriggerFrequency.Once);
}
if (MyInvocation.BoundParameters.ContainsKey(_paramDaily))
{
switchParamList.Add(TriggerFrequency.Daily);
}
if (MyInvocation.BoundParameters.ContainsKey(_paramWeekly))
{
switchParamList.Add(TriggerFrequency.Weekly);
}
if (switchParamList.Count > 1)
{
WriteValidationError(ScheduledJobErrorStrings.ConflictingTypeParams);
return false;
}
newTriggerFrequency = (switchParamList.Count == 1) ? switchParamList[0] : TriggerFrequency.None;
// Validate parameters against the new trigger frequency value.
bool rtnValue = false;
switch (newTriggerFrequency)
{
case TriggerFrequency.None:
rtnValue = true;
break;
case TriggerFrequency.AtStartup:
rtnValue = ValidateStartupParams();
break;
case TriggerFrequency.AtLogon:
rtnValue = ValidateLogonParams();
break;
case TriggerFrequency.Once:
rtnValue = ValidateOnceParams();
break;
case TriggerFrequency.Daily:
rtnValue = ValidateDailyParams();
break;
case TriggerFrequency.Weekly:
rtnValue = ValidateWeeklyParams();
break;
default:
Debug.Assert(false, "Invalid trigger frequency value.");
rtnValue = false;
break;
}
return rtnValue;
}
private bool ValidateStartupParams()
{
if (MyInvocation.BoundParameters.ContainsKey(_paramDaysInterval))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidDaysInterval, ScheduledJobErrorStrings.TriggerStartUpType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramWeeksInterval))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidWeeksInterval, ScheduledJobErrorStrings.TriggerStartUpType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramAt))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidAtTime, ScheduledJobErrorStrings.TriggerStartUpType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramUser))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidUser, ScheduledJobErrorStrings.TriggerStartUpType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramDaysOfWeek))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidDaysOfWeek, ScheduledJobErrorStrings.TriggerStartUpType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramRepetitionInterval) || MyInvocation.BoundParameters.ContainsKey(_paramRepetitionDuration) ||
MyInvocation.BoundParameters.ContainsKey(_paramRepetitionInfiniteDuration))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidSetTriggerRepetition, ScheduledJobErrorStrings.TriggerStartUpType);
WriteValidationError(msg);
return false;
}
return true;
}
private bool ValidateLogonParams()
{
if (MyInvocation.BoundParameters.ContainsKey(_paramDaysInterval))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidDaysInterval, ScheduledJobErrorStrings.TriggerLogonType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramWeeksInterval))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidWeeksInterval, ScheduledJobErrorStrings.TriggerLogonType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramAt))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidAtTime, ScheduledJobErrorStrings.TriggerLogonType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramDaysOfWeek))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidDaysOfWeek, ScheduledJobErrorStrings.TriggerLogonType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramRepetitionInterval) || MyInvocation.BoundParameters.ContainsKey(_paramRepetitionDuration) ||
MyInvocation.BoundParameters.ContainsKey(_paramRepetitionInfiniteDuration))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidSetTriggerRepetition, ScheduledJobErrorStrings.TriggerLogonType);
WriteValidationError(msg);
return false;
}
return true;
}
private bool ValidateOnceParams(ScheduledJobTrigger trigger = null)
{
if (MyInvocation.BoundParameters.ContainsKey(_paramDaysInterval))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidDaysInterval, ScheduledJobErrorStrings.TriggerOnceType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramWeeksInterval))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidWeeksInterval, ScheduledJobErrorStrings.TriggerOnceType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramUser))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidUser, ScheduledJobErrorStrings.TriggerOnceType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramDaysOfWeek))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidDaysOfWeek, ScheduledJobErrorStrings.TriggerOnceType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramRepetitionInfiniteDuration))
{
_repDuration = TimeSpan.MaxValue;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramRepetitionInterval) || MyInvocation.BoundParameters.ContainsKey(_paramRepetitionDuration) ||
MyInvocation.BoundParameters.ContainsKey(_paramRepetitionInfiniteDuration))
{
// Validate Once trigger repetition parameters.
try
{
ScheduledJobTrigger.ValidateOnceRepetitionParams(_repInterval, _repDuration);
}
catch (PSArgumentException e)
{
WriteValidationError(e.Message);
return false;
}
}
if (trigger != null)
{
if (trigger.At == null && !MyInvocation.BoundParameters.ContainsKey(_paramAt))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.MissingAtTime, ScheduledJobErrorStrings.TriggerOnceType);
WriteValidationError(msg);
return false;
}
}
return true;
}
private bool ValidateDailyParams(ScheduledJobTrigger trigger = null)
{
if (MyInvocation.BoundParameters.ContainsKey(_paramDaysInterval) &&
_daysInterval < 1)
{
WriteValidationError(ScheduledJobErrorStrings.InvalidDaysIntervalParam);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramWeeksInterval))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidWeeksInterval, ScheduledJobErrorStrings.TriggerDailyType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramUser))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidUser, ScheduledJobErrorStrings.TriggerDailyType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramDaysOfWeek))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidDaysOfWeek, ScheduledJobErrorStrings.TriggerDailyType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramRepetitionInterval) || MyInvocation.BoundParameters.ContainsKey(_paramRepetitionDuration) ||
MyInvocation.BoundParameters.ContainsKey(_paramRepetitionInfiniteDuration))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidSetTriggerRepetition, ScheduledJobErrorStrings.TriggerDailyType);
WriteValidationError(msg);
return false;
}
if (trigger != null)
{
if (trigger.At == null && !MyInvocation.BoundParameters.ContainsKey(_paramAt))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.MissingAtTime, ScheduledJobErrorStrings.TriggerDailyType);
WriteValidationError(msg);
return false;
}
}
return true;
}
private bool ValidateWeeklyParams(ScheduledJobTrigger trigger = null)
{
if (MyInvocation.BoundParameters.ContainsKey(_paramDaysInterval))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidDaysInterval, ScheduledJobErrorStrings.TriggerWeeklyType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramWeeksInterval) &&
_weeksInterval < 1)
{
WriteValidationError(ScheduledJobErrorStrings.InvalidWeeksIntervalParam);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramUser))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidUser, ScheduledJobErrorStrings.TriggerWeeklyType);
WriteValidationError(msg);
return false;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramRepetitionInterval) || MyInvocation.BoundParameters.ContainsKey(_paramRepetitionDuration) ||
MyInvocation.BoundParameters.ContainsKey(_paramRepetitionInfiniteDuration))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidSetTriggerRepetition, ScheduledJobErrorStrings.TriggerWeeklyType);
WriteValidationError(msg);
return false;
}
if (trigger != null)
{
if (trigger.At == null && !MyInvocation.BoundParameters.ContainsKey(_paramAt))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.MissingAtTime, ScheduledJobErrorStrings.TriggerDailyType);
WriteValidationError(msg);
return false;
}
if ((trigger.DaysOfWeek == null || trigger.DaysOfWeek.Count == 0) &&
!MyInvocation.BoundParameters.ContainsKey(_paramDaysOfWeek))
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.MissingDaysOfWeek, ScheduledJobErrorStrings.TriggerDailyType);
WriteValidationError(msg);
return false;
}
}
return true;
}
private bool UpdateTrigger(ScheduledJobTrigger trigger, TriggerFrequency triggerFrequency)
{
if (triggerFrequency != TriggerFrequency.None)
{
//
// User has specified a specific trigger type.
// Parameters have been validated for this trigger type.
//
if (triggerFrequency != trigger.Frequency)
{
// Changing to a new trigger type.
return CreateTrigger(trigger, triggerFrequency);
}
else
{
// Modifying existing trigger type.
return ModifyTrigger(trigger, triggerFrequency);
}
}
else
{
// We are updating an existing trigger. Need to validate params
// against each trigger type we are updating.
return ModifyTrigger(trigger, trigger.Frequency, true);
}
}
private bool CreateTrigger(ScheduledJobTrigger trigger, TriggerFrequency triggerFrequency)
{
switch (triggerFrequency)
{
case TriggerFrequency.AtStartup:
CreateAtStartupTrigger(trigger);
break;
case TriggerFrequency.AtLogon:
CreateAtLogonTrigger(trigger);
break;
case TriggerFrequency.Once:
if (trigger.Frequency != triggerFrequency &&
!ValidateOnceParams(trigger))
{
return false;
}
CreateOnceTrigger(trigger);
break;
case TriggerFrequency.Daily:
if (trigger.Frequency != triggerFrequency &&
!ValidateDailyParams(trigger))
{
return false;
}
CreateDailyTrigger(trigger);
break;
case TriggerFrequency.Weekly:
if (trigger.Frequency != triggerFrequency &&
!ValidateWeeklyParams(trigger))
{
return false;
}
CreateWeeklyTrigger(trigger);
break;
}
return true;
}
private bool ModifyTrigger(ScheduledJobTrigger trigger, TriggerFrequency triggerFrequency, bool validate = false)
{
switch (triggerFrequency)
{
case TriggerFrequency.AtStartup:
if (validate &&
!ValidateStartupParams())
{
return false;
}
ModifyStartupTrigger(trigger);
break;
case TriggerFrequency.AtLogon:
if (validate &&
!ValidateLogonParams())
{
return false;
}
ModifyLogonTrigger(trigger);
break;
case TriggerFrequency.Once:
if (validate &&
!ValidateOnceParams())
{
return false;
}
ModifyOnceTrigger(trigger);
break;
case TriggerFrequency.Daily:
if (validate &&
!ValidateDailyParams())
{
return false;
}
ModifyDailyTrigger(trigger);
break;
case TriggerFrequency.Weekly:
if (validate &&
!ValidateWeeklyParams())
{
return false;
}
ModifyWeeklyTrigger(trigger);
break;
}
return true;
}
private void ModifyStartupTrigger(ScheduledJobTrigger trigger)
{
if (MyInvocation.BoundParameters.ContainsKey(_paramRandomDelay))
{
trigger.RandomDelay = _randomDelay;
}
}
private void ModifyLogonTrigger(ScheduledJobTrigger trigger)
{
if (MyInvocation.BoundParameters.ContainsKey(_paramRandomDelay))
{
trigger.RandomDelay = _randomDelay;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramUser))
{
trigger.User = string.IsNullOrEmpty(_user) ? ScheduledJobTrigger.AllUsers : _user;
}
}
private void ModifyOnceTrigger(ScheduledJobTrigger trigger)
{
if (MyInvocation.BoundParameters.ContainsKey(_paramRandomDelay))
{
trigger.RandomDelay = _randomDelay;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramRepetitionInterval))
{
trigger.RepetitionInterval = _repInterval;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramRepetitionDuration))
{
trigger.RepetitionDuration = _repDuration;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramAt))
{
trigger.At = _atTime;
}
}
private void ModifyDailyTrigger(ScheduledJobTrigger trigger)
{
if (MyInvocation.BoundParameters.ContainsKey(_paramRandomDelay))
{
trigger.RandomDelay = _randomDelay;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramAt))
{
trigger.At = _atTime;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramDaysInterval))
{
trigger.Interval = _daysInterval;
}
}
private void ModifyWeeklyTrigger(ScheduledJobTrigger trigger)
{
if (MyInvocation.BoundParameters.ContainsKey(_paramRandomDelay))
{
trigger.RandomDelay = _randomDelay;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramAt))
{
trigger.At = _atTime;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramWeeksInterval))
{
trigger.Interval = _weeksInterval;
}
if (MyInvocation.BoundParameters.ContainsKey(_paramDaysOfWeek))
{
trigger.DaysOfWeek = new List<DayOfWeek>(_daysOfWeek);
}
}
private void CreateAtLogonTrigger(ScheduledJobTrigger trigger)
{
bool enabled = trigger.Enabled;
int id = trigger.Id;
TimeSpan randomDelay = trigger.RandomDelay;
string user = string.IsNullOrEmpty(trigger.User) ? ScheduledJobTrigger.AllUsers : trigger.User;
trigger.ClearProperties();
trigger.Frequency = TriggerFrequency.AtLogon;
trigger.Enabled = enabled;
trigger.Id = id;
trigger.RandomDelay = MyInvocation.BoundParameters.ContainsKey(_paramRandomDelay) ? _randomDelay : randomDelay;
trigger.User = MyInvocation.BoundParameters.ContainsKey(_paramUser) ? _user : user;
}
private void CreateAtStartupTrigger(ScheduledJobTrigger trigger)
{
bool enabled = trigger.Enabled;
int id = trigger.Id;
TimeSpan randomDelay = trigger.RandomDelay;
trigger.ClearProperties();
trigger.Frequency = TriggerFrequency.AtStartup;
trigger.Enabled = enabled;
trigger.Id = id;
trigger.RandomDelay = MyInvocation.BoundParameters.ContainsKey(_paramRandomDelay) ? _randomDelay : randomDelay;
}
private void CreateOnceTrigger(ScheduledJobTrigger trigger)
{
bool enabled = trigger.Enabled;
int id = trigger.Id;
TimeSpan randomDelay = trigger.RandomDelay;
DateTime? atTime = trigger.At;
TimeSpan? repInterval = trigger.RepetitionInterval;
TimeSpan? repDuration = trigger.RepetitionDuration;
trigger.ClearProperties();
trigger.Frequency = TriggerFrequency.Once;
trigger.Enabled = enabled;
trigger.Id = id;
trigger.RandomDelay = MyInvocation.BoundParameters.ContainsKey(_paramRandomDelay) ? _randomDelay : randomDelay;
trigger.At = MyInvocation.BoundParameters.ContainsKey(_paramAt) ? _atTime : atTime;
trigger.RepetitionInterval = MyInvocation.BoundParameters.ContainsKey(_paramRepetitionInterval) ? _repInterval : repInterval;
trigger.RepetitionDuration = MyInvocation.BoundParameters.ContainsKey(_paramRepetitionDuration) ? _repDuration : repDuration;
}
private void CreateDailyTrigger(ScheduledJobTrigger trigger)
{
bool enabled = trigger.Enabled;
int id = trigger.Id;
TimeSpan randomDelay = trigger.RandomDelay;
DateTime? atTime = trigger.At;
int interval = trigger.Interval;
trigger.ClearProperties();
trigger.Frequency = TriggerFrequency.Daily;
trigger.Enabled = enabled;
trigger.Id = id;
trigger.RandomDelay = MyInvocation.BoundParameters.ContainsKey(_paramRandomDelay) ? _randomDelay : randomDelay;
trigger.At = MyInvocation.BoundParameters.ContainsKey(_paramAt) ? _atTime : atTime;
trigger.Interval = MyInvocation.BoundParameters.ContainsKey(_paramDaysInterval) ? _daysInterval : interval;
}
private void CreateWeeklyTrigger(ScheduledJobTrigger trigger)
{
bool enabled = trigger.Enabled;
int id = trigger.Id;
TimeSpan randomDelay = trigger.RandomDelay;
DateTime? atTime = trigger.At;
int interval = trigger.Interval;
List<DayOfWeek> daysOfWeek = trigger.DaysOfWeek;
trigger.ClearProperties();
trigger.Frequency = TriggerFrequency.Weekly;
trigger.Enabled = enabled;
trigger.Id = id;
trigger.RandomDelay = MyInvocation.BoundParameters.ContainsKey(_paramRandomDelay) ? _randomDelay : randomDelay;
trigger.At = MyInvocation.BoundParameters.ContainsKey(_paramAt) ? _atTime : atTime;
trigger.Interval = MyInvocation.BoundParameters.ContainsKey(_paramWeeksInterval) ? _weeksInterval : interval;
trigger.DaysOfWeek = MyInvocation.BoundParameters.ContainsKey(_paramDaysOfWeek) ? new List<DayOfWeek>(_daysOfWeek) : daysOfWeek;
}
private void WriteValidationError(string msg)
{
Exception reason = new RuntimeException(msg);
ErrorRecord errorRecord = new ErrorRecord(reason, "SetJobTriggerParameterValidationError", ErrorCategory.InvalidArgument, null);
WriteError(errorRecord);
}
#endregion
#region Private Members
private string _paramAtStartup = "AtStartup";
private string _paramAtLogon = "AtLogon";
private string _paramOnce = "Once";
private string _paramDaily = "Daily";
private string _paramWeekly = "Weekly";
//
private string _paramDaysInterval = "DaysInterval";
private string _paramWeeksInterval = "WeeksInterval";
private string _paramRandomDelay = "RandomDelay";
private string _paramRepetitionInterval = "RepetitionInterval";
private string _paramRepetitionDuration = "RepetitionDuration";
private string _paramRepetitionInfiniteDuration = "RepeatIndefinitely";
private string _paramAt = "At";
private string _paramUser = "User";
private string _paramDaysOfWeek = "DaysOfWeek";
#endregion
}
}

View File

@ -0,0 +1,136 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Management.Automation;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This cmdlet sets the provided scheduled job options to the provided ScheduledJobOptions objects.
/// </summary>
[Cmdlet(VerbsCommon.Set, "ScheduledJobOption", DefaultParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=223921")]
[OutputType(typeof(ScheduledJobOptions))]
public class SetScheduledJobOptionCommand : ScheduledJobOptionCmdletBase
{
#region Parameters
/// <summary>
/// ScheduledJobOptions object.
/// </summary>
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,
ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)]
[ValidateNotNull]
public ScheduledJobOptions InputObject
{
get { return _jobOptions; }
set { _jobOptions = value; }
}
private ScheduledJobOptions _jobOptions;
/// <summary>
/// Pas the ScheduledJobOptions object through to output.
/// </summary>
[Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)]
public SwitchParameter PassThru
{
get { return _passThru; }
set { _passThru = value; }
}
private SwitchParameter _passThru;
#endregion
#region Cmdlet Overrides
/// <summary>
/// Process input.
/// </summary>
protected override void ProcessRecord()
{
// Update ScheduledJobOptions object with current parameters.
// Update switch parameters only if they were selected.
// Also update the ScheduledJobDefintion object associated with this options object.
if (MyInvocation.BoundParameters.ContainsKey("StartIfOnBattery"))
{
_jobOptions.StartIfOnBatteries = StartIfOnBattery;
}
if (MyInvocation.BoundParameters.ContainsKey("ContinueIfGoingOnBattery"))
{
_jobOptions.StopIfGoingOnBatteries = !ContinueIfGoingOnBattery;
}
if (MyInvocation.BoundParameters.ContainsKey("WakeToRun"))
{
_jobOptions.WakeToRun = WakeToRun;
}
if (MyInvocation.BoundParameters.ContainsKey("StartIfIdle"))
{
_jobOptions.StartIfNotIdle = !StartIfIdle;
}
if (MyInvocation.BoundParameters.ContainsKey("StopIfGoingOffIdle"))
{
_jobOptions.StopIfGoingOffIdle = StopIfGoingOffIdle;
}
if (MyInvocation.BoundParameters.ContainsKey("RestartOnIdleResume"))
{
_jobOptions.RestartOnIdleResume = RestartOnIdleResume;
}
if (MyInvocation.BoundParameters.ContainsKey("HideInTaskScheduler"))
{
_jobOptions.ShowInTaskScheduler = !HideInTaskScheduler;
}
if (MyInvocation.BoundParameters.ContainsKey("RunElevated"))
{
_jobOptions.RunElevated = RunElevated;
}
if (MyInvocation.BoundParameters.ContainsKey("RequireNetwork"))
{
_jobOptions.RunWithoutNetwork = !RequireNetwork;
}
if (MyInvocation.BoundParameters.ContainsKey("DoNotAllowDemandStart"))
{
_jobOptions.DoNotAllowDemandStart = DoNotAllowDemandStart;
}
if (MyInvocation.BoundParameters.ContainsKey("IdleDuration"))
{
_jobOptions.IdleDuration = IdleDuration;
}
if (MyInvocation.BoundParameters.ContainsKey("IdleTimeout"))
{
_jobOptions.IdleTimeout = IdleTimeout;
}
if (MyInvocation.BoundParameters.ContainsKey("MultipleInstancePolicy"))
{
_jobOptions.MultipleInstancePolicy = MultipleInstancePolicy;
}
// Update ScheduledJobDefinition with changes.
if (_jobOptions.JobDefinition != null)
{
_jobOptions.UpdateJobDefinition();
}
if (_passThru)
{
WriteObject(_jobOptions);
}
}
#endregion
}
}

View File

@ -0,0 +1,150 @@
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.PowerShell.ScheduledJob
{
/// <summary>
/// This cmdlet removes the specified ScheduledJobDefinition objects from the
/// Task Scheduler, job store, and local repository.
/// </summary>
[Cmdlet(VerbsLifecycle.Unregister, "ScheduledJob", SupportsShouldProcess = true, DefaultParameterSetName = UnregisterScheduledJobCommand.DefinitionParameterSet,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=223925")]
public sealed class UnregisterScheduledJobCommand : ScheduleJobCmdletBase
{
#region Parameters
private const string DefinitionIdParameterSet = "DefinitionId";
private const string DefinitionNameParameterSet = "DefinitionName";
private const string DefinitionParameterSet = "Definition";
/// <summary>
/// ScheduledJobDefintion Id.
/// </summary>
[Parameter(Position = 0, Mandatory = true,
ParameterSetName = UnregisterScheduledJobCommand.DefinitionIdParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public Int32[] Id
{
get { return _definitionIds; }
set { _definitionIds = value; }
}
private Int32[] _definitionIds;
/// <summary>
/// ScheduledJobDefinition Name.
/// </summary>
[Parameter(Position = 0, Mandatory = true,
ParameterSetName = UnregisterScheduledJobCommand.DefinitionNameParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] Name
{
get { return _names; }
set { _names = value; }
}
private string[] _names;
/// <summary>
/// ScheduledJobDefinition.
/// </summary>
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,
ParameterSetName = UnregisterScheduledJobCommand.DefinitionParameterSet)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public ScheduledJobDefinition[] InputObject
{
get { return _definitions; }
set { _definitions = value; }
}
private ScheduledJobDefinition[] _definitions;
/// <summary>
/// When true this will stop any running instances of this job definition before
/// removing the definition.
/// </summary>
[Parameter(ParameterSetName = UnregisterScheduledJobCommand.DefinitionIdParameterSet)]
[Parameter(ParameterSetName = UnregisterScheduledJobCommand.DefinitionNameParameterSet)]
[Parameter(ParameterSetName = UnregisterScheduledJobCommand.DefinitionParameterSet)]
public SwitchParameter Force
{
get { return _force; }
set { _force = value; }
}
private SwitchParameter _force;
#endregion
#region Cmdlet Overrides
/// <summary>
/// Process input.
/// </summary>
protected override void ProcessRecord()
{
List<ScheduledJobDefinition> definitions = null;
switch (ParameterSetName)
{
case DefinitionParameterSet:
definitions = new List<ScheduledJobDefinition>(_definitions);
break;
case DefinitionNameParameterSet:
definitions = GetJobDefinitionsByName(_names);
break;
case DefinitionIdParameterSet:
definitions = GetJobDefinitionsById(_definitionIds);
break;
}
if (definitions != null)
{
foreach (ScheduledJobDefinition definition in definitions)
{
string targetString = StringUtil.Format(ScheduledJobErrorStrings.DefinitionWhatIf, definition.Name);
if (ShouldProcess(targetString, VerbsLifecycle.Unregister))
{
// Removes the ScheduledJobDefintion from the job store,
// Task Scheduler, and disposes the object.
try
{
definition.Remove(_force);
}
catch (ScheduledJobException e)
{
string msg = StringUtil.Format(ScheduledJobErrorStrings.CantUnregisterDefinition, definition.Name);
Exception reason = new RuntimeException(msg, e);
ErrorRecord errorRecord = new ErrorRecord(reason, "CantUnregisterScheduledJobDefinition", ErrorCategory.InvalidOperation, definition);
WriteError(errorRecord);
}
}
}
}
// Check for unknown definition names.
if ((_names != null && _names.Length > 0) &&
(_definitions == null || _definitions.Length < _names.Length))
{
// Make sure there is no PowerShell task in Task Scheduler with removed names.
// This covers the case where the scheduled job defintion was manually removed from
// the job store but remains as a PowerShell task in Task Scheduler.
using (ScheduledJobWTS taskScheduler = new ScheduledJobWTS())
{
foreach (string name in _names)
{
taskScheduler.RemoveTaskByName(name, true, true);
}
}
}
}
#endregion
}
}

View File

@ -0,0 +1,30 @@
{
"monad/src/ScheduledJob/ScheduledJob.cs" : "ScheduledJob.cs",
"monad/src/ScheduledJob/ScheduledJobDefinition.cs" : "ScheduledJobDefinition.cs",
"monad/src/ScheduledJob/ScheduledJobOptions.cs" : "ScheduledJobOptions.cs",
"monad/src/ScheduledJob/ScheduledJobSourceAdapter.cs" : "ScheduledJobSourceAdapter.cs",
"monad/src/ScheduledJob/ScheduledJobStore.cs" : "ScheduledJobStore.cs",
"monad/src/ScheduledJob/ScheduledJobTrigger.cs" : "ScheduledJobTrigger.cs",
"monad/src/ScheduledJob/ScheduledJobWTS.cs" : "ScheduledJobWTS.cs",
"monad/src/ScheduledJob/commands/NewJobTrigger.cs": "commands/NewJobTrigger.cs",
"monad/src/ScheduledJob/commands/AddJobTrigger.cs": "commands/AddJobTrigger.cs",
"monad/src/ScheduledJob/commands/SchedJobCmdletBase.cs": "commands/SchedJobCmdletBase.cs",
"monad/src/ScheduledJob/commands/RemoveJobTrigger.cs": "commands/RemoveJobTrigger.cs",
"monad/src/ScheduledJob/commands/GetJobTrigger.cs": "commands/GetJobTrigger.cs",
"monad/src/ScheduledJob/commands/SetJobTrigger.cs": "commands/SetJobTrigger.cs",
"monad/src/ScheduledJob/commands/DisableJobTrigger.cs": "commands/DisableJobTrigger.cs",
"monad/src/ScheduledJob/commands/EnableJobTrigger.cs": "commands/EnableJobTrigger.cs",
"monad/src/ScheduledJob/commands/EnableDisableCmdletBase.cs": "commands/EnableDisableCmdletBase.cs",
"monad/src/ScheduledJob/commands/ScheduledJobOptionCmdletBase.cs": "commands/ScheduledJobOptionCmdletBase.cs",
"monad/src/ScheduledJob/commands/NewScheduledJobOption.cs": "commands/NewScheduledJobOption.cs",
"monad/src/ScheduledJob/commands/SetScheduledJobOption.cs": "commands/SetScheduledJobOption.cs",
"monad/src/ScheduledJob/commands/GetScheduledJobOption.cs": "commands/GetScheduledJobOption.cs",
"monad/src/ScheduledJob/commands/RegisterJobDefinition.cs": "commands/RegisterJobDefinition.cs",
"monad/src/ScheduledJob/commands/SetJobDefinition.cs": "commands/SetJobDefinition.cs",
"monad/src/ScheduledJob/commands/GetJobDefinition.cs": "commands/GetJobDefinition.cs",
"monad/src/ScheduledJob/commands/UnregisterJobDefinition.cs": "commands/UnregisterJobDefinition.cs",
"monad/src/ScheduledJob/commands/DisableJobDefinitionBase.cs": "commands/DisableJobDefinitionBase.cs",
"monad/src/ScheduledJob/commands/DisableJobDefinition.cs": "commands/DisableJobDefinition.cs",
"monad/src/ScheduledJob/commands/EnableJobDefinition.cs": "commands/EnableJobDefinition.cs",
"monad/src/ScheduledJob/resources/ScheduledJobErrorStrings.resx": "resources/ScheduledJobErrorStrings.resx"
}

View File

@ -0,0 +1,25 @@
{
"name": "Microsoft.PowerShell.ScheduledJob",
"version": "1.0.0-*",
"buildOptions": {
"keyFile": "../signing/visualstudiopublic.snk",
"delaySign": true,
"publicSign": false,
"warningsAsErrors": true,
},
"dependencies": {
"System.Management.Automation": "1.0.0-*",
"Microsoft.PowerShell.ScheduledJob.Interop": "1.0.0-*"
},
"frameworks": {
"net451": {
"frameworkAssemblies": {
"System.Threading": "",
"System.Threading.Tasks": ""
}
}
}
}

View File

@ -0,0 +1,387 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="CannotFindJobDefinition" xml:space="preserve">
<value>Cannot find scheduled job {0}.</value>
<comment>{0} is the scheduled job defintion name that cannot be found.</comment>
</data>
<data name="CannotFindTaskId" xml:space="preserve">
<value>Cannot find scheduled job definition {0} in the Task Scheduler.</value>
</data>
<data name="CannotRemoveTaskRunningInstance" xml:space="preserve">
<value>The scheduled job definition {0} cannot be removed because one or more instances are currently running. You can remove and stop all running instances by using the Force parameter.</value>
</data>
<data name="CantAddJobTriggersToDefinition" xml:space="preserve">
<value>An error occurred while adding triggers to the scheduled job {0}.</value>
</data>
<data name="CantFindInWTS" xml:space="preserve">
<value>There is no entry in Task Scheduler for scheduled job definition {0}. A new Task Scheduler entry has been created for this scheduled job definition.</value>
</data>
<data name="CantLoadDefinitionFromStore" xml:space="preserve">
<value>Cannot get the {0} scheduled job because it is corrupted or in an irresolvable state. Because it cannot run, Windows PowerShell has deleted {0} and its results from the computer. To recreate the scheduled job, use the Register-ScheduledJob cmdlet. For more information about corrupted scheduled jobs, see about_Scheduled_Jobs_Troubleshooting.</value>
<comment>{0} is the name of the scheduled job definition.</comment>
</data>
<data name="CantLoadJobRunFromStore" xml:space="preserve">
<value>An error occurred while loading job run results for scheduled job {0} with job run date {1}. </value>
</data>
<data name="CantRegisterJobDefinition" xml:space="preserve">
<value>An error occurred while registering the scheduled job {0}.</value>
</data>
<data name="CantRemoveTriggersFromDefinition" xml:space="preserve">
<value>An error occurred while removing job triggers from scheduled job {0}.</value>
</data>
<data name="CantRetrieveJobRuns" xml:space="preserve">
<value>One or more scheduled job runs could not be retrieved {0}.</value>
</data>
<data name="CantSaveJobNoFilePathSpecified" xml:space="preserve">
<value>Job {0} cannot be saved because no file path was specified.</value>
</data>
<data name="CantSaveJobNotRun" xml:space="preserve">
<value>Job {0} has not been run and cannot be saved. Run the job first, and then save results.</value>
</data>
<data name="CantSetEnableOnJobDefinition" xml:space="preserve">
<value>An error occurred while enabling or disabling the scheduled job {0}.</value>
</data>
<data name="CantSetJobDefinition" xml:space="preserve">
<value>An error occurred while setting properties on the scheduled job {0}.</value>
</data>
<data name="CantStartJobDefinition" xml:space="preserve">
<value>Cannot start a job from the {0} scheduled job definition.</value>
</data>
<data name="CantUnregisterDefinition" xml:space="preserve">
<value>An error occurred while unregistering the scheduled job {0}.</value>
</data>
<data name="CantUpdateTriggerOnJobDef" xml:space="preserve">
<value>An error occurred while updating the scheduled job definition {0} with this trigger {1}. See exception details for more information.</value>
</data>
<data name="ConflictingTypeParams" xml:space="preserve">
<value>Only one JobTrigger type can be specified: AtStartup, AtLogon, Once, Daily, or Weekly.</value>
</data>
<data name="DefinitionAlreadyExistsInLocal" xml:space="preserve">
<value>A scheduled job defintion object {0} already exists in the local scheduled job repository having this Global ID {1}.</value>
</data>
<data name="DefinitionNotFoundByGlobalId" xml:space="preserve">
<value>A scheduled job definition object with Global ID {0} could not be found.</value>
</data>
<data name="DefinitionNotFoundById" xml:space="preserve">
<value>A scheduled job definition with ID {0} could not be found.</value>
</data>
<data name="DefinitionNotFoundByName" xml:space="preserve">
<value>A scheduled job definition with Name {0} could not be found.</value>
</data>
<data name="DefinitionObjectDisposed" xml:space="preserve">
<value>This scheduled job definition object {0} has been disposed.</value>
</data>
<data name="DefinitionWhatIf" xml:space="preserve">
<value>Scheduled job definition {0}.</value>
</data>
<data name="DirectoryNotFoundError" xml:space="preserve">
<value>A directory not found error occurred while registering scheduled job definition {0}. Make sure you are running Windows PowerShell with elevated privileges.</value>
</data>
<data name="ErrorRegisteringDefinitionStore" xml:space="preserve">
<value>An error occurred while registering scheduled job definition {0}. Cannot add this definition object to the job store.</value>
</data>
<data name="ErrorRegisteringDefinitionTask" xml:space="preserve">
<value>An error occurred while registering scheduled job definition {0} to the Windows Task Scheduler. The Task Scheduler error is: {1}.</value>
</data>
<data name="ErrorRemovingDefinitionStore" xml:space="preserve">
<value>An error occurred while unregistering scheduled job definition {0}.</value>
</data>
<data name="ErrorSettingAccessPermissions" xml:space="preserve">
<value>An error occurred while setting file access permissions for job definition {0} and user {1}.</value>
</data>
<data name="ErrorUpdatingDefinitionStore" xml:space="preserve">
<value>An error occurred while updating scheduled job definition {0}. Cannot update this definition in the job store.</value>
</data>
<data name="ErrorUpdatingDefinitionTask" xml:space="preserve">
<value>An error occurred while updating scheduled job definition {0}. Cannot update this definition with the Windows Task Scheduler.</value>
</data>
<data name="GeneralWTSError" xml:space="preserve">
<value>An error has occurred within the Task Scheduler.</value>
</data>
<data name="InvalidAtTime" xml:space="preserve">
<value>The At parameter is not valid for the {0} job trigger type.</value>
</data>
<data name="InvalidDaysInterval" xml:space="preserve">
<value>The DaysInterval parameter is not valid for the {0} job trigger type.</value>
</data>
<data name="InvalidDaysIntervalParam" xml:space="preserve">
<value>The DaysInterval parameter value must be greater than zero.</value>
</data>
<data name="InvalidDaysOfWeek" xml:space="preserve">
<value>The DaysOfWeek parameter is not valid for the {0} job trigger type.</value>
</data>
<data name="InvalidFilePath" xml:space="preserve">
<value>The FilePath parameter is not valid.</value>
</data>
<data name="InvalidFilePathFile" xml:space="preserve">
<value>Only Windows PowerShell script files are allowed for FilePath parameter. Specify a file with .ps1 extension.</value>
</data>
<data name="InvalidIdleDuration" xml:space="preserve">
<value>The IdleDuration parameter cannot have a negative value.</value>
</data>
<data name="InvalidIdleTimeout" xml:space="preserve">
<value>The IdleTimeout parameter cannot have a negative value.</value>
</data>
<data name="InvalidJobDefName" xml:space="preserve">
<value>The scheduled job definition name {0} contains characters that are not valid.</value>
</data>
<data name="InvalidMaxResultCount" xml:space="preserve">
<value>The MaxResultCount parameter cannot have a negative or zero value.</value>
</data>
<data name="InvalidUser" xml:space="preserve">
<value>The User parameter is not valid for the {0} job trigger type.</value>
</data>
<data name="InvalidWeeksInterval" xml:space="preserve">
<value>The WeeksInterval parameter is not valid for the {0} job trigger type.</value>
</data>
<data name="InvalidWeeksIntervalParam" xml:space="preserve">
<value>The WeeksInterval parameter value must be greater than zero.</value>
</data>
<data name="IOFailureOnSetJobDefinition" xml:space="preserve">
<value>An I/O failure occurred while updating the scheduled job definition {0}. This could mean a file is missing or corrupted, either in Task Scheduler or in the Windows PowerShell scheduled job store. You might need to create the scheduled job definition again.</value>
<comment>{0} is the scheduled job definition name</comment>
</data>
<data name="JobAlreadyRunning" xml:space="preserve">
<value>Job {0} is currently running.</value>
</data>
<data name="JobDefFileAlreadyExists" xml:space="preserve">
<value>The scheduled job definition {0} already exists in the job definition store.</value>
</data>
<data name="JobRunResultsFileAlreadyExists" xml:space="preserve">
<value>The scheduled job results {0} already exist in the job results store.</value>
</data>
<data name="MissingAtTime" xml:space="preserve">
<value>The At parameter is required for the {0} job trigger type.</value>
</data>
<data name="MissingDaysOfWeek" xml:space="preserve">
<value>The DaysOfWeek parameter is required for the {0} job trigger type.</value>
</data>
<data name="MissingJobTriggerDaysOfWeek" xml:space="preserve">
<value>The job trigger {0} requires the DaysOfWeek parameter to be defined.</value>
</data>
<data name="MissingJobTriggerTime" xml:space="preserve">
<value>The Job trigger {0} requires the At parameter to be defined.</value>
</data>
<data name="MissingJobTriggerType" xml:space="preserve">
<value>No Frequency type has been specified for this job trigger. One of the following job trigger frequencies must be specified: AtStartup, AtLogon, Once, Daily, Weekly.</value>
</data>
<data name="NoAccessOnSetJobDefinition" xml:space="preserve">
<value>An access denied error occurred while updating the scheduled job definition {0}. Try running Windows PowerShell with elevated user rights; that is, Run as Administrator.</value>
<comment>{0} is the scheduled job definition name</comment>
</data>
<data name="NoAssociatedJobDefinitionForOption" xml:space="preserve">
<value>There is no scheduled job definition object associated with this options object.</value>
</data>
<data name="NoAssociatedJobDefinitionForTrigger" xml:space="preserve">
<value>There is no scheduled job definition object associated with this trigger {0}.</value>
</data>
<data name="ScheduledJobAlreadyExistsInLocal" xml:space="preserve">
<value>The scheduled job {0} already exists in the local repository.</value>
</data>
<data name="ScheduledJobNotInRepository" xml:space="preserve">
<value>The scheduled job {0} is not in the local job repository.</value>
</data>
<data name="TaskIdAlreadyExists" xml:space="preserve">
<value>The scheduled job definition {0} already exists in Task Scheduler.</value>
</data>
<data name="TriggerDailyType" xml:space="preserve">
<value>Daily</value>
</data>
<data name="TriggerLogonType" xml:space="preserve">
<value>AtLogon</value>
</data>
<data name="TriggerNotFound" xml:space="preserve">
<value>A scheduled job trigger with ID {0} was not found for the scheduled job definition {1}.</value>
</data>
<data name="TriggerOnceType" xml:space="preserve">
<value>Once</value>
</data>
<data name="TriggerStartUpType" xml:space="preserve">
<value>AtStartup</value>
</data>
<data name="TriggerWeeklyType" xml:space="preserve">
<value>Weekly</value>
</data>
<data name="UnauthorizedAccessError" xml:space="preserve">
<value>An access denied error occurred when registering scheduled job definition {0}. Try running Windows PowerShell with elevated user rights; that is, Run As Administrator.</value>
</data>
<data name="UnknownTriggerFrequency" xml:space="preserve">
<value>Cannot convert a ScheduledJobTrigger object with TriggerFrequency value of {0}.</value>
</data>
<data name="UnknownTriggerType" xml:space="preserve">
<value>An unknown trigger type was returned from Task Scheduler for scheduled job definition {0} with trigger ID {1}.</value>
</data>
<data name="CannotSerializeData" xml:space="preserve">
<value>The scheduled job definition {0} could not be saved because one of the values in the ArgumentList parameter cannot be converted to XML. If possible, change the ArgumentList values to types that are easily converted to XML, such as strings, integers, and hash tables. {1}</value>
<comment>{0} is the name of the scheduled job definition that cannot be registered
{1} is the inner exception message from .Net serialization, or emtpy if no exception message.</comment>
</data>
<data name="UnsupportedHostFunction" xml:space="preserve">
<value>Commands that interact with the host program, such as Write-Host, cannot be included in Windows PowerShell scheduled jobs because scheduled jobs do not interact with the host program. Use an alternate command that does not interact with the host program, such as Write-Output or Out-File.</value>
</data>
<data name="InvalidRepetitionInterval" xml:space="preserve">
<value>The RepetitionInterval parameter value must be less than or equal to the RepetitionDuration parameter value.</value>
</data>
<data name="InvalidRepetitionIntervalValue" xml:space="preserve">
<value>The RepetitionInterval parameter value must be greater than 1 minute.</value>
</data>
<data name="InvalidRepetitionParams" xml:space="preserve">
<value>The RepetitionInterval and RepetitionDuration Job trigger parameters must be specified together.</value>
</data>
<data name="InvalidRepetitionParamValues" xml:space="preserve">
<value>The Repetition parameters cannot have negative values.</value>
</data>
<data name="InvalidSetTriggerRepetition" xml:space="preserve">
<value>The Repetition parameters are not valid for the {0} job trigger type.</value>
</data>
<data name="MismatchedRepetitionParamValues" xml:space="preserve">
<value>The RepetitionInterval parameter cannot have a value of zero unless the RepetitionDuration parameter also has a zero value. A zero value removes repetition behavior from the Job trigger.</value>
</data>
<data name="ErrorRenamingScheduledJob" xml:space="preserve">
<value>An error occured while attempting to rename scheduled job from {0} to {1}.</value>
</data>
<data name="ErrorRenamingScheduledJobWithMessage" xml:space="preserve">
<value>An error occured while attempting to rename scheduled job from {0} to {1} with error message: {2}.</value>
</data>
<data name="BrokenRenamingScheduledJob" xml:space="preserve">
<value>An unrecoverable error occurred while renaming the scheduled job from {0} to {1}. The scheduled job will be removed.</value>
</data>
<data name="BrokenRenamingScheduledJobWithMessage" xml:space="preserve">
<value>An unrecoverable error occurred while renaming the scheduled job from {0} to {1} with message {2}. The scheduled job will be removed.</value>
</data>
<data name="ErrorRunningAsTask" xml:space="preserve">
<value>An error occurred while running scheduled job defintion {0} from the Task Scheduler.</value>
</data>
<data name="ErrorRunningAsTaskWithReason" xml:space="preserve">
<value>An error occurred while running scheduled job defintion {0} from the Task Scheduler because {1}.</value>
</data>
<data name="InvalidRepeatIndefinitelyParams" xml:space="preserve">
<value>You cannot specify the RepetitionDuration and RepeatIndefinitely parameters in the same command.</value>
</data>
<data name="InvalidRepetitionRepeatParams" xml:space="preserve">
<value>When you use the RepeatIndefinitely parameter, the RepetitionInterval parameter is required.</value>
</data>
<data name="reasonJobNotFound" xml:space="preserve">
<value>the scheduled job definition could not be found</value>
</data>
<data name="ReasonTaskDisabled" xml:space="preserve">
<value>the scheduled job definition is disabled</value>
</data>
</root>

View File

@ -1,7 +1,6 @@
{
"name": "Microsoft.PowerShell.Security",
"version": "1.0.0-*",
"authors": [ "garretts", "andschwa" ],
"buildOptions": {
"keyFile": "../signing/visualstudiopublic.snk",

View File

@ -1,7 +1,6 @@
{
"name": "System.Management.Automation",
"version": "1.0.0-*",
"authors": [ "garretts", "andschwa" ],
"buildOptions": {
"keyFile": "../signing/visualstudiopublic.snk",

View File

@ -2,7 +2,6 @@
"name": "System.Security.SecureString",
"version": "4.0.0-*",
"description": "SecureString Stub borrowed from Mono",
"authors": [ "garretts" ],
"buildOptions": {
"keyFile": "key.snk",

View File

@ -2,7 +2,6 @@
"name": "TypeCatalogGen",
"version": "1.0.0-*",
"description": "Generates CorePsTypeCatalog.cs given powershell.inc",
"authors": [ "andschwa" ],
"buildOptions": {
"emitEntryPoint": true

View File

@ -2,7 +2,6 @@
"name": "powershell",
"version": "1.0.0-*",
"description": ".NET CLI PowerShell app",
"authors": [ "andschwa" ],
"buildOptions": {
"warningsAsErrors": true,

@ -1 +1 @@
Subproject commit 0f47c9600d98e987e0ff777842e5149a1f03fc91
Subproject commit 2b61bc608620a988bf88b16f80014b9996a0186c

View File

@ -43,7 +43,7 @@ Describe 'Modules for the packge' {
It 'loads Microsoft.PowerShell.LocalAccounts' {
try
{
Import-Module Microsoft.PowerShell.LocalAccounts
Import-Module Microsoft.PowerShell.LocalAccounts -ErrorAction Stop
Get-LocalUser | Should Not Be $null
}
finally
@ -55,7 +55,7 @@ Describe 'Modules for the packge' {
It 'loads Microsoft.PowerShell.Archive' {
try
{
Import-Module Microsoft.PowerShell.LocalAccounts
Import-Module Microsoft.PowerShell.LocalAccounts -ErrorAction Stop
Set-Content -Path TestDrive:\1.txt -Value ''
Compress-Archive -Path TestDrive:\1.txt -DestinationPath TestDrive:\1.zip
Get-ChildItem -Path TestDrive:\1.zip | Should Not Be $null
@ -65,6 +65,18 @@ Describe 'Modules for the packge' {
Remove-Module -ErrorAction SilentlyContinue Microsoft.PowerShell.Archive
}
}
It 'loads PsScheduledJob' {
try
{
Import-Module PsScheduledJob -ErrorAction Stop
New-ScheduledJobOption | Should Not Be $null
}
finally
{
Remove-Module -ErrorAction SilentlyContinue PsScheduledJob
}
}
}
finally
{