diff --git a/src/Microsoft.PowerShell.ScheduledJob/AssemblyInfo.cs b/src/Microsoft.PowerShell.ScheduledJob/AssemblyInfo.cs deleted file mode 100644 index 3e2e4ff3268..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/AssemblyInfo.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System.Reflection; -using System.Resources; - -[assembly:AssemblyFileVersionAttribute("3.0.0.0")] -[assembly:AssemblyVersion("3.0.0.0")] - -[assembly:AssemblyCulture("")] -[assembly:NeutralResourcesLanguage("en-US")] diff --git a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJob.cs b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJob.cs deleted file mode 100644 index 5641b2d6540..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJob.cs +++ /dev/null @@ -1,1286 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.IO; -using System.Management.Automation; -using System.Management.Automation.Host; -using System.Management.Automation.Runspaces; -using System.Runtime.Serialization; -using System.Security.Permissions; -using System.Text; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This is a Job2 derived class that contains a DefinitionJob for - /// running job definition based jobs but can also save and load job - /// results data from file. This class is used to load job result - /// data from previously run jobs so that a user can view results of - /// scheduled job runs. This class also contains the definition of - /// the scheduled job and so can run an instance of the scheduled - /// job and optionally save results to file. - /// - public sealed class ScheduledJob : Job2, ISerializable - { - #region Private Members - - private ScheduledJobDefinition _jobDefinition; - private Runspace _runspace; - private System.Management.Automation.PowerShell _powerShell; - private Job _job = null; - private bool _asyncJobStop; - private bool _allowSetShouldExit; - private PSHost _host; - - private const string AllowHostSetShouldExit = "AllowSetShouldExitFromRemote"; - - private StatusInfo _statusInfo; - - #endregion - - #region Public Properties - - /// - /// ScheduledJobDefinition. - /// - public ScheduledJobDefinition Definition - { - get { return _jobDefinition; } - - internal set { _jobDefinition = value; } - } - - /// - /// Location of job being run. - /// - public override string Location - { - get - { - return Status.Location; - } - } - - /// - /// Status Message associated with the Job. - /// - public override string StatusMessage - { - get - { - return Status.StatusMessage; - } - } - - /// - /// Indicates whether more data is available from Job. - /// - public override bool HasMoreData - { - get - { - return (_job != null) ? - _job.HasMoreData - : - (Output.Count > 0 || - Error.Count > 0 || - Warning.Count > 0 || - Verbose.Count > 0 || - Progress.Count > 0 || - Debug.Count > 0 || - Information.Count > 0 - ); - } - } - - /// - /// Job command string. - /// - public new string Command - { - get - { - return Status.Command; - } - } - - /// - /// Internal property indicating whether a SetShouldExit is honored - /// while running the scheduled job script. - /// - internal bool AllowSetShouldExit - { - get { return _allowSetShouldExit; } - - set { _allowSetShouldExit = value; } - } - - #endregion - - #region Constructors - - /// - /// Constructor. - /// - /// Job command string for display. - /// Name of job. - /// ScheduledJobDefinition defining job to run. - public ScheduledJob( - string command, - string name, - ScheduledJobDefinition jobDefinition) : - base(command, name) - { - if (command == null) - { - throw new PSArgumentNullException("command"); - } - - if (name == null) - { - throw new PSArgumentNullException("name"); - } - - if (jobDefinition == null) - { - throw new PSArgumentNullException("jobDefinition"); - } - - _jobDefinition = jobDefinition; - - PSJobTypeName = ScheduledJobSourceAdapter.AdapterTypeName; - } - - #endregion - - #region Public Overrides - - /// - /// Starts a job as defined by the contained ScheduledJobDefinition object. - /// - public override void StartJob() - { - lock (SyncRoot) - { - if (_job != null && !IsFinishedState(_job.JobStateInfo.State)) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.JobAlreadyRunning, _jobDefinition.Name); - throw new PSInvalidOperationException(msg); - } - - _statusInfo = null; - _asyncJobStop = false; - PSBeginTime = DateTime.Now; - - if (_powerShell == null) - { - InitialSessionState iss = InitialSessionState.CreateDefault2(); - iss.Commands.Clear(); - iss.Formats.Clear(); - iss.Commands.Add( - new SessionStateCmdletEntry("Start-Job", typeof(Microsoft.PowerShell.Commands.StartJobCommand), null)); - - // Get the default host from the default runspace. - _host = GetDefaultHost(); - _runspace = RunspaceFactory.CreateRunspace(_host, iss); - _runspace.Open(); - _powerShell = System.Management.Automation.PowerShell.Create(); - _powerShell.Runspace = _runspace; - - // Indicate SetShouldExit to host. - AddSetShouldExitToHost(); - } - else - { - _powerShell.Commands.Clear(); - } - - _job = StartJobCommand(_powerShell); - - _job.StateChanged += new EventHandler(HandleJobStateChanged); - SetJobState(_job.JobStateInfo.State); - - // Add all child jobs to this object's list so that - // the user and Receive-Job can retrieve results. - foreach (Job childJob in _job.ChildJobs) - { - this.ChildJobs.Add(childJob); - } - - // Add this job to the local repository. - ScheduledJobSourceAdapter.AddToRepository(this); - } - } - - /// - /// Start job asynchronously. - /// - public override void StartJobAsync() - { - // StartJob(); - throw new PSNotSupportedException(); - } - - /// - /// Stop the job. - /// - public override void StopJob() - { - Job job; - JobState state; - lock (SyncRoot) - { - job = _job; - state = Status.State; - _asyncJobStop = false; - } - - if (IsFinishedState(state)) - { - return; - } - - if (job == null) - { - // Set job state to failed so that it can be removed from the - // cache using Remove-Job. - SetJobState(JobState.Failed); - } - else - { - job.StopJob(); - } - } - - /// - /// Stop the job asynchronously. - /// - public override void StopJobAsync() - { - Job job; - JobState state; - lock (SyncRoot) - { - job = _job; - state = Status.State; - _asyncJobStop = true; - } - - if (IsFinishedState(state)) - { - return; - } - - if (job == null) - { - // Set job state to failed so that it can be removed from the - // cache using Remove-Job. - SetJobState(JobState.Failed); - HandleJobStateChanged(this, - new JobStateEventArgs( - new JobStateInfo(JobState.Failed))); - } - else - { - job.StopJob(); - } - } - - /// - /// SuspendJob. - /// - public override void SuspendJob() - { - throw new PSNotSupportedException(); - } - - /// - /// SuspendJobAsync. - /// - public override void SuspendJobAsync() - { - throw new PSNotSupportedException(); - } - - /// - /// ResumeJob. - /// - public override void ResumeJob() - { - throw new PSNotSupportedException(); - } - - /// - /// ResumeJobAsync. - /// - public override void ResumeJobAsync() - { - throw new PSNotSupportedException(); - } - - /// - /// UnblockJob. - /// - public override void UnblockJob() - { - throw new PSNotSupportedException(); - } - - /// - /// UnblockJobAsync. - /// - public override void UnblockJobAsync() - { - throw new PSNotSupportedException(); - } - - /// - /// StopJob. - /// - /// - /// - public override void StopJob(bool force, string reason) - { - throw new PSNotSupportedException(); - } - - /// - /// StopJobAsync. - /// - /// - /// - public override void StopJobAsync(bool force, string reason) - { - throw new PSNotSupportedException(); - } - /// - /// SuspendJob. - /// - /// - /// - public override void SuspendJob(bool force, string reason) - { - throw new PSNotSupportedException(); - } - - /// - /// SuspendJobAsync. - /// - /// - /// - public override void SuspendJobAsync(bool force, string reason) - { - throw new PSNotSupportedException(); - } - - #endregion - - #region Implementation of ISerializable - - /// - /// Deserialize constructor. - /// - /// SerializationInfo. - /// StreamingContext. - private ScheduledJob( - SerializationInfo info, - StreamingContext context) - { - if (info == null) - { - throw new PSArgumentNullException("info"); - } - - DeserializeStatusInfo(info); - DeserializeResultsInfo(info); - PSJobTypeName = ScheduledJobSourceAdapter.AdapterTypeName; - } - - /// - /// Serialize method. - /// - /// SerializationInfo. - /// StreamingContext. - public void GetObjectData( - SerializationInfo info, - StreamingContext context) - { - if (info == null) - { - throw new PSArgumentException("info"); - } - - SerializeStatusInfo(info); - SerializeResultsInfo(info); - } - - private void SerializeStatusInfo(SerializationInfo info) - { - StatusInfo statusInfo = new StatusInfo( - InstanceId, - Name, - Location, - Command, - StatusMessage, - (_job != null) ? _job.JobStateInfo.State : JobStateInfo.State, - HasMoreData, - PSBeginTime, - PSEndTime, - _jobDefinition); - - info.AddValue("StatusInfo", statusInfo); - } - - private void SerializeResultsInfo(SerializationInfo info) - { - // All other job information is in the child jobs. - Collection output = new Collection(); - Collection error = new Collection(); - Collection warning = new Collection(); - Collection verbose = new Collection(); - Collection progress = new Collection(); - Collection debug = new Collection(); - Collection information = new Collection(); - - if (_job != null) - { - // Collect data from "live" job. - - if (JobStateInfo.Reason != null) - { - error.Add(new ErrorRecord(JobStateInfo.Reason, "ScheduledJobFailedState", ErrorCategory.InvalidResult, null)); - } - - foreach (var item in _job.Error) - { - error.Add(item); - } - - foreach (Job childJob in ChildJobs) - { - if (childJob.JobStateInfo.Reason != null) - { - error.Add(new ErrorRecord(childJob.JobStateInfo.Reason, "ScheduledJobFailedState", ErrorCategory.InvalidResult, null)); - } - - foreach (var item in childJob.Output) - { - output.Add(item); - } - - foreach (var item in childJob.Error) - { - error.Add(item); - } - - foreach (var item in childJob.Warning) - { - warning.Add(item); - } - - foreach (var item in childJob.Verbose) - { - verbose.Add(item); - } - - foreach (var item in childJob.Progress) - { - progress.Add(item); - } - - foreach (var item in childJob.Debug) - { - debug.Add(item); - } - - foreach (var item in childJob.Information) - { - information.Add(item); - } - } - } - else - { - // Collect data from object collections. - - foreach (var item in Output) - { - // Wrap the base object in a new PSObject. This is necessary because the - // source deserialized PSObject doesn't serialize again correctly and breaks - // PS F&O. Not sure if this is a PSObject serialization bug or not. - output.Add(new PSObject(item.BaseObject)); - } - - foreach (var item in Error) - { - error.Add(item); - } - - foreach (var item in Warning) - { - warning.Add(item); - } - - foreach (var item in Verbose) - { - verbose.Add(item); - } - - foreach (var item in Progress) - { - progress.Add(item); - } - - foreach (var item in Debug) - { - debug.Add(item); - } - - foreach (var item in Information) - { - information.Add(item); - } - } - - ResultsInfo resultsInfo = new ResultsInfo( - output, error, warning, verbose, progress, debug, information); - - info.AddValue("ResultsInfo", resultsInfo); - } - - private void DeserializeStatusInfo(SerializationInfo info) - { - StatusInfo statusInfo = (StatusInfo)info.GetValue("StatusInfo", typeof(StatusInfo)); - - Name = statusInfo.Name; - PSBeginTime = statusInfo.StartTime; - PSEndTime = statusInfo.StopTime; - _jobDefinition = statusInfo.Definition; - SetJobState(statusInfo.State, null); - - lock (SyncRoot) - { - _statusInfo = statusInfo; - } - } - - private void DeserializeResultsInfo(SerializationInfo info) - { - ResultsInfo resultsInfo = (ResultsInfo)info.GetValue("ResultsInfo", typeof(ResultsInfo)); - - // Output - CopyOutput(resultsInfo.Output); - - // Error - CopyError(resultsInfo.Error); - - // Warning - CopyWarning(resultsInfo.Warning); - - // Verbose - CopyVerbose(resultsInfo.Verbose); - - // Progress - CopyProgress(resultsInfo.Progress); - - // Debug - CopyDebug(resultsInfo.Debug); - - // Information - CopyInformation(resultsInfo.Information); - } - - #endregion - - #region Internal Methods - - /// - /// Method to update a ScheduledJob based on new state and - /// result data from a provided Job. - /// - /// ScheduledJob to update from. - internal void Update(ScheduledJob fromJob) - { - // We do not update "live" jobs. - if (_job != null || fromJob == null) - { - return; - } - - // - // Update status. - // - PSEndTime = fromJob.PSEndTime; - JobState state = fromJob.JobStateInfo.State; - if (Status.State != state) - { - SetJobState(state, null); - } - - lock (SyncRoot) - { - _statusInfo = new StatusInfo( - fromJob.InstanceId, - fromJob.Name, - fromJob.Location, - fromJob.Command, - fromJob.StatusMessage, - state, - fromJob.HasMoreData, - fromJob.PSBeginTime, - fromJob.PSEndTime, - fromJob._jobDefinition); - } - - // - // Update results. - // - CopyOutput(fromJob.Output); - CopyError(fromJob.Error); - CopyWarning(fromJob.Warning); - CopyVerbose(fromJob.Verbose); - CopyProgress(fromJob.Progress); - CopyDebug(fromJob.Debug); - CopyInformation(fromJob.Information); - } - - #endregion - - #region Private Methods - - private System.Management.Automation.Host.PSHost GetDefaultHost() - { - System.Management.Automation.PowerShell ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace).AddScript("$host"); - Collection hosts = ps.Invoke(); - if (hosts == null || hosts.Count == 0) - { - System.Diagnostics.Debug.Assert(false, "Current runspace should always return default host."); - return null; - } - - return hosts[0]; - } - - private Job StartJobCommand(System.Management.Automation.PowerShell powerShell) - { - Job job = null; - - // Use PowerShell Start-Job cmdlet to run job. - powerShell.AddCommand("Start-Job"); - - powerShell.AddParameter("Name", _jobDefinition.Name); - - // Add job parameters from the JobInvocationInfo object. - CommandParameterCollection parameters = _jobDefinition.InvocationInfo.Parameters[0]; - foreach (CommandParameter parameter in parameters) - { - switch (parameter.Name) - { - case "ScriptBlock": - powerShell.AddParameter("ScriptBlock", parameter.Value as ScriptBlock); - break; - - case "FilePath": - powerShell.AddParameter("FilePath", parameter.Value as string); - break; - - case "RunAs32": - powerShell.AddParameter("RunAs32", (bool)parameter.Value); - break; - - case "Authentication": - powerShell.AddParameter("Authentication", (AuthenticationMechanism)parameter.Value); - break; - - case "InitializationScript": - powerShell.AddParameter("InitializationScript", parameter.Value as ScriptBlock); - break; - - case "ArgumentList": - powerShell.AddParameter("ArgumentList", parameter.Value as object[]); - break; - } - } - - // Start the job. - Collection rtn = powerShell.Invoke(); - if (rtn != null && rtn.Count == 1) - { - job = rtn[0].BaseObject as Job; - } - - return job; - } - - private void HandleJobStateChanged(object sender, JobStateEventArgs e) - { - SetJobState(e.JobStateInfo.State); - - if (IsFinishedState(e.JobStateInfo.State)) - { - PSEndTime = DateTime.Now; - - // Dispose the PowerShell and Runspace objects. - System.Management.Automation.PowerShell disposePowerShell = null; - Runspace disposeRunspace = null; - lock (SyncRoot) - { - if (_job != null && - IsFinishedState(_job.JobStateInfo.State)) - { - disposePowerShell = _powerShell; - _powerShell = null; - disposeRunspace = _runspace; - _runspace = null; - } - } - - if (disposePowerShell != null) - { - disposePowerShell.Dispose(); - } - - if (disposeRunspace != null) - { - disposeRunspace.Dispose(); - } - - // Raise async job stopped event, if needed. - if (_asyncJobStop) - { - _asyncJobStop = false; - OnStopJobCompleted(new AsyncCompletedEventArgs(null, false, null)); - } - - // Remove AllowSetShouldExit from host. - RemoveSetShouldExitFromHost(); - } - } - - internal bool IsFinishedState(JobState state) - { - return (state == JobState.Completed || state == JobState.Failed || state == JobState.Stopped); - } - - private StatusInfo Status - { - get - { - StatusInfo statusInfo; - lock (SyncRoot) - { - if (_statusInfo != null) - { - // Pass back static status. - statusInfo = _statusInfo; - } - else if (_job != null) - { - // Create current job status. - statusInfo = new StatusInfo( - _job.InstanceId, - _job.Name, - _job.Location, - _job.Command, - _job.StatusMessage, - _job.JobStateInfo.State, - _job.HasMoreData, - PSBeginTime, - PSEndTime, - _jobDefinition); - } - else - { - // Create default static empty status. - _statusInfo = new StatusInfo( - Guid.Empty, - string.Empty, - string.Empty, - string.Empty, - string.Empty, - JobState.NotStarted, - false, - PSBeginTime, - PSEndTime, - _jobDefinition); - - statusInfo = _statusInfo; - } - } - - return statusInfo; - } - } - - private void CopyOutput(ICollection fromOutput) - { - PSDataCollection output = CopyResults(fromOutput); - if (output != null) - { - try - { - Output = output; - } - catch (InvalidJobStateException) { } - } - } - - private void CopyError(ICollection fromError) - { - PSDataCollection error = CopyResults(fromError); - if (error != null) - { - try - { - Error = error; - } - catch (InvalidJobStateException) { } - } - } - - private void CopyWarning(ICollection fromWarning) - { - PSDataCollection warning = CopyResults(fromWarning); - if (warning != null) - { - try - { - Warning = warning; - } - catch (InvalidJobStateException) { } - } - } - - private void CopyVerbose(ICollection fromVerbose) - { - PSDataCollection verbose = CopyResults(fromVerbose); - if (verbose != null) - { - try - { - Verbose = verbose; - } - catch (InvalidJobStateException) { } - } - } - - private void CopyProgress(ICollection fromProgress) - { - PSDataCollection progress = CopyResults(fromProgress); - if (progress != null) - { - try - { - Progress = progress; - } - catch (InvalidJobStateException) { } - } - } - - private void CopyDebug(ICollection fromDebug) - { - PSDataCollection debug = CopyResults(fromDebug); - if (debug != null) - { - try - { - Debug = debug; - } - catch (InvalidJobStateException) { } - } - } - - private void CopyInformation(ICollection fromInformation) - { - PSDataCollection information = CopyResults(fromInformation); - if (information != null) - { - try - { - Information = information; - } - catch (InvalidJobStateException) { } - } - } - - private PSDataCollection CopyResults(ICollection fromResults) - { - if (fromResults != null && fromResults.Count > 0) - { - PSDataCollection returnResults = new PSDataCollection(); - foreach (var item in fromResults) - { - returnResults.Add(item); - } - - return returnResults; - } - - return null; - } - - private void AddSetShouldExitToHost() - { - if (!_allowSetShouldExit || _host == null) - { - return; - } - - PSObject hostPrivateData = _host.PrivateData as PSObject; - if (hostPrivateData != null) - { - // Adds or replaces. - hostPrivateData.Properties.Add(new PSNoteProperty(AllowHostSetShouldExit, true)); - } - } - - private void RemoveSetShouldExitFromHost() - { - if (!_allowSetShouldExit || _host == null) - { - return; - } - - PSObject hostPrivateData = _host.PrivateData as PSObject; - if (hostPrivateData != null) - { - // Removes if exists. - hostPrivateData.Properties.Remove(AllowHostSetShouldExit); - } - } - - #endregion - - #region Private ResultsInfo class - private sealed class ResultsInfo : ISerializable - { - // Private Members - private Collection _output; - private Collection _error; - private Collection _warning; - private Collection _verbose; - private Collection _progress; - private Collection _debug; - private Collection _information; - - // Properties - internal Collection Output - { - get { return _output; } - } - - internal Collection Error - { - get { return _error; } - } - - internal Collection Warning - { - get { return _warning; } - } - - internal Collection Verbose - { - get { return _verbose; } - } - - internal Collection Progress - { - get { return _progress; } - } - - internal Collection Debug - { - get { return _debug; } - } - - internal Collection Information - { - get { return _information; } - } - - // Constructors - internal ResultsInfo( - Collection output, - Collection error, - Collection warning, - Collection verbose, - Collection progress, - Collection debug, - Collection information - ) - { - if (output == null) - { - throw new PSArgumentNullException("output"); - } - - if (error == null) - { - throw new PSArgumentNullException("error"); - } - - if (warning == null) - { - throw new PSArgumentNullException("warning"); - } - - if (verbose == null) - { - throw new PSArgumentNullException("verbose"); - } - - if (progress == null) - { - throw new PSArgumentNullException("progress"); - } - - if (debug == null) - { - throw new PSArgumentNullException("debug"); - } - - if (information == null) - { - throw new PSArgumentNullException("information"); - } - - _output = output; - _error = error; - _warning = warning; - _verbose = verbose; - _progress = progress; - _debug = debug; - _information = information; - } - - // ISerializable - private ResultsInfo( - SerializationInfo info, - StreamingContext context) - { - if (info == null) - { - throw new PSArgumentNullException("info"); - } - - _output = (Collection)info.GetValue("Results_Output", typeof(Collection)); - _error = (Collection)info.GetValue("Results_Error", typeof(Collection)); - _warning = (Collection)info.GetValue("Results_Warning", typeof(Collection)); - _verbose = (Collection)info.GetValue("Results_Verbose", typeof(Collection)); - _progress = (Collection)info.GetValue("Results_Progress", typeof(Collection)); - _debug = (Collection)info.GetValue("Results_Debug", typeof(Collection)); - - try - { - _information = (Collection)info.GetValue("Results_Information", typeof(Collection)); - } - catch (SerializationException) - { - // The job might not have the info stream. Ignore. - _information = new Collection(); - } - } - - public void GetObjectData( - SerializationInfo info, - StreamingContext context) - { - if (info == null) - { - throw new PSArgumentException("info"); - } - - info.AddValue("Results_Output", _output); - info.AddValue("Results_Error", _error); - info.AddValue("Results_Warning", _warning); - info.AddValue("Results_Verbose", _verbose); - info.AddValue("Results_Progress", _progress); - info.AddValue("Results_Debug", _debug); - info.AddValue("Results_Information", _information); - } - } - - #endregion - } - - #region Internal StatusInfo Class - internal class StatusInfo : ISerializable - { - // Private Members - private Guid _instanceId; - private string _name; - private string _location; - private string _command; - private string _statusMessage; - private JobState _jobState; - private bool _hasMoreData; - private DateTime? _startTime; - private DateTime? _stopTime; - private ScheduledJobDefinition _definition; - - // Properties - internal Guid InstanceId - { - get { return _instanceId; } - } - - internal string Name - { - get { return _name; } - } - - internal string Location - { - get { return _location; } - } - - internal string Command - { - get { return _command; } - } - - internal string StatusMessage - { - get { return _statusMessage; } - } - - internal JobState State - { - get { return _jobState; } - } - - internal bool HasMoreData - { - get { return _hasMoreData; } - } - - internal DateTime? StartTime - { - get { return _startTime; } - } - - internal DateTime? StopTime - { - get { return _stopTime; } - } - - internal ScheduledJobDefinition Definition - { - get { return _definition; } - } - - // Constructors - internal StatusInfo( - Guid instanceId, - string name, - string location, - string command, - string statusMessage, - JobState jobState, - bool hasMoreData, - DateTime? startTime, - DateTime? stopTime, - ScheduledJobDefinition definition) - { - if (definition == null) - { - throw new PSArgumentNullException("definition"); - } - - _instanceId = instanceId; - _name = name; - _location = location; - _command = command; - _statusMessage = statusMessage; - _jobState = jobState; - _hasMoreData = hasMoreData; - _startTime = startTime; - _stopTime = stopTime; - _definition = definition; - } - - // ISerializable - private StatusInfo( - SerializationInfo info, - StreamingContext context) - { - if (info == null) - { - throw new PSArgumentNullException("info"); - } - - _instanceId = Guid.Parse(info.GetString("Status_InstanceId")); - _name = info.GetString("Status_Name"); - _location = info.GetString("Status_Location"); - _command = info.GetString("Status_Command"); - _statusMessage = info.GetString("Status_Message"); - _jobState = (JobState)info.GetValue("Status_State", typeof(JobState)); - _hasMoreData = info.GetBoolean("Status_MoreData"); - _definition = (ScheduledJobDefinition)info.GetValue("Status_Definition", typeof(ScheduledJobDefinition)); - - DateTime startTime = info.GetDateTime("Status_StartTime"); - if (startTime != DateTime.MinValue) - { - _startTime = startTime; - } - else - { - _startTime = null; - } - - DateTime stopTime = info.GetDateTime("Status_StopTime"); - if (stopTime != DateTime.MinValue) - { - _stopTime = stopTime; - } - else - { - _stopTime = null; - } - } - - public void GetObjectData( - SerializationInfo info, - StreamingContext context) - { - if (info == null) - { - throw new PSArgumentNullException("info"); - } - - info.AddValue("Status_InstanceId", _instanceId); - info.AddValue("Status_Name", _name); - info.AddValue("Status_Location", _location); - info.AddValue("Status_Command", _command); - info.AddValue("Status_Message", _statusMessage); - info.AddValue("Status_State", _jobState); - info.AddValue("Status_MoreData", _hasMoreData); - info.AddValue("Status_Definition", _definition); - - if (_startTime != null) - { - info.AddValue("Status_StartTime", _startTime); - } - else - { - info.AddValue("Status_StartTime", DateTime.MinValue); - } - - if (_stopTime != null) - { - info.AddValue("Status_StopTime", _stopTime); - } - else - { - info.AddValue("Status_StopTime", DateTime.MinValue); - } - } - } - - #endregion -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobDefinition.cs b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobDefinition.cs deleted file mode 100644 index bfe2e87f6ee..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobDefinition.cs +++ /dev/null @@ -1,2583 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; -using System.IO; -using System.Management.Automation; -using System.Management.Automation.Runspaces; -using System.Management.Automation.Tracing; -using System.Runtime.Serialization; -using System.Security.Permissions; -using System.Text.RegularExpressions; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This class contains all information needed to define a PowerShell job that - /// can be scheduled to run through either stand-alone or through the Windows - /// Task Scheduler. - /// - public sealed class ScheduledJobDefinition : ISerializable, IDisposable - { - #region Private Members - - private JobInvocationInfo _invocationInfo; - private ScheduledJobOptions _options; - private PSCredential _credential; - private Guid _globalId = Guid.NewGuid(); - private string _name = string.Empty; - private int _id = GetCurrentId(); - private int _executionHistoryLength = DefaultExecutionHistoryLength; - private bool _enabled = true; - private Dictionary _triggers = new Dictionary(); - private Int32 _currentTriggerId; - - private string _definitionFilePath; - private string _definitionOutputPath; - - private bool _isDisposed; - - // Task Action strings. - private const string TaskExecutionPath = @"pwsh.exe"; - private const string TaskArguments = @"-NoLogo -NonInteractive -WindowStyle Hidden -Command ""Import-Module PSScheduledJob; $jobDef = [Microsoft.PowerShell.ScheduledJob.ScheduledJobDefinition]::LoadFromStore('{0}', '{1}'); $jobDef.Run()"""; - private static object LockObject = new object(); - private static int CurrentId = 0; - private static int DefaultExecutionHistoryLength = 32; - - internal static ScheduledJobDefinitionRepository Repository = new ScheduledJobDefinitionRepository(); - - // Task Scheduler COM error codes. - private const int TSErrorDisabledTask = -2147216602; - - #endregion - - #region Public Properties - - /// - /// Contains information needed to run the job such as script parameters, - /// job definition, user credentials, etc. - /// - public JobInvocationInfo InvocationInfo - { - get { return _invocationInfo; } - } - - /// - /// Contains the script commands that define the job. - /// - public JobDefinition Definition - { - get { return _invocationInfo.Definition; } - } - - /// - /// Specifies Task Scheduler options for the scheduled job. - /// - public ScheduledJobOptions Options - { - get { return new ScheduledJobOptions(_options); } - } - - /// - /// Credential. - /// - public PSCredential Credential - { - get { return _credential; } - - internal set { _credential = value; } - } - - /// - /// An array of trigger objects that specify a time/condition - /// for when the job is run. - /// - public List JobTriggers - { - get - { - List notFoundIds; - return GetTriggers(null, out notFoundIds); - } - } - - /// - /// Local instance Id for object instance. - /// - public int Id - { - get { return _id; } - } - - /// - /// Global Id for scheduled job definition. - /// - public Guid GlobalId - { - get { return _globalId; } - } - - /// - /// Name of scheduled job definition. - /// - public string Name - { - get { return _name; } - } - - /// - /// Job command. - /// - public string Command - { - get { return _invocationInfo.Command; } - } - - /// - /// Returns the maximum number of job execution data - /// allowed in the job store. - /// - public int ExecutionHistoryLength - { - get { return _executionHistoryLength; } - } - - /// - /// Determines whether this scheduled job definition is enabled - /// in Task Scheduler. - /// - public bool Enabled - { - get { return _enabled; } - } - - /// - /// Returns the PowerShell command line execution path. - /// - public string PSExecutionPath - { - get { return TaskExecutionPath; } - } - - /// - /// Returns PowerShell command line arguments to run - /// the scheduled job. - /// - public string PSExecutionArgs - { - get - { - // Escape single quotes in name. Double quotes are not allowed - // and are caught during name validation. - string nameEscapeQuotes = _invocationInfo.Name.Replace("'", "''"); - - return string.Format(CultureInfo.InvariantCulture, TaskArguments, nameEscapeQuotes, _definitionFilePath); - } - } - - /// - /// Returns the job run output path for this job definition. - /// - internal string OutputPath - { - get { return _definitionOutputPath; } - } - - #endregion - - #region Constructors - - /// - /// Default constructor is not accessible. - /// - private ScheduledJobDefinition() - { } - - /// - /// Constructor. - /// - /// Information to invoke Job. - /// ScheduledJobTriggers. - /// ScheduledJobOptions. - /// Credential. - public ScheduledJobDefinition( - JobInvocationInfo invocationInfo, - IEnumerable triggers, - ScheduledJobOptions options, - PSCredential credential) - { - if (invocationInfo == null) - { - throw new PSArgumentNullException("invocationInfo"); - } - - _name = invocationInfo.Name; - _invocationInfo = invocationInfo; - - SetTriggers(triggers, false); - _options = (options != null) ? new ScheduledJobOptions(options) : - new ScheduledJobOptions(); - _options.JobDefinition = this; - - _credential = credential; - } - - #endregion - - #region ISerializable Implementation - - /// - /// Serialization constructor. - /// - /// SerializationInfo. - /// StreamingContext. - private ScheduledJobDefinition( - SerializationInfo info, - StreamingContext context) - { - if (info == null) - { - throw new PSArgumentNullException("info"); - } - - _options = (ScheduledJobOptions)info.GetValue("Options_Member", typeof(ScheduledJobOptions)); - _globalId = Guid.Parse(info.GetString("GlobalId_Member")); - _name = info.GetString("Name_Member"); - _executionHistoryLength = info.GetInt32("HistoryLength_Member"); - _enabled = info.GetBoolean("Enabled_Member"); - _triggers = (Dictionary)info.GetValue("Triggers_Member", typeof(Dictionary)); - _currentTriggerId = info.GetInt32("CurrentTriggerId_Member"); - _definitionFilePath = info.GetString("FilePath_Member"); - _definitionOutputPath = info.GetString("OutputPath_Member"); - - object invocationObject = info.GetValue("InvocationInfo_Member", typeof(object)); - _invocationInfo = invocationObject as JobInvocationInfo; - - // Set the JobDefinition reference for the ScheduledJobTrigger and - // ScheduledJobOptions objects. - _options.JobDefinition = this; - foreach (ScheduledJobTrigger trigger in _triggers.Values) - { - trigger.JobDefinition = this; - } - - // Instance information. - _isDisposed = false; - } - - /// - /// Serialization constructor. - /// - /// SerializationInfo. - /// StreamingContext. - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - if (info == null) - { - throw new PSArgumentNullException("info"); - } - - info.AddValue("Options_Member", _options); - info.AddValue("GlobalId_Member", _globalId.ToString()); - info.AddValue("Name_Member", _name); - info.AddValue("HistoryLength_Member", _executionHistoryLength); - info.AddValue("Enabled_Member", _enabled); - info.AddValue("Triggers_Member", _triggers); - info.AddValue("CurrentTriggerId_Member", _currentTriggerId); - info.AddValue("FilePath_Member", _definitionFilePath); - info.AddValue("OutputPath_Member", _definitionOutputPath); - - info.AddValue("InvocationInfo_Member", _invocationInfo); - } - - #endregion - - #region Private Methods - - /// - /// Updates existing information if scheduled job already exists. - /// WTS entry includes command line, options, and trigger conditions. - /// - private void UpdateWTSFromDefinition() - { - using (ScheduledJobWTS taskScheduler = new ScheduledJobWTS()) - { - taskScheduler.UpdateTask(this); - } - } - - /// - /// Compares the current ScheduledJobDefinition task scheduler information - /// with the corresponding information stored in Task Scheduler. If the - /// information is different then the task scheduler information in this - /// object is updated to match what is in Task Scheduler, since that information - /// takes precedence. - /// - /// Task Scheduler information: - /// - Triggers - /// - Options - /// - Enabled state. - /// - /// Boolean if this object data is modified. - private bool UpdateDefinitionFromWTS() - { - bool dataModified = false; - - // Get information from Task Scheduler. - using (ScheduledJobWTS taskScheduler = new ScheduledJobWTS()) - { - bool wtsEnabled = taskScheduler.GetTaskEnabled(_name); - ScheduledJobOptions wtsOptions = taskScheduler.GetJobOptions(_name); - Collection wtsTriggers = taskScheduler.GetJobTriggers(_name); - - // - // Compare with existing object data and modify if necessary. - // - - // Enabled. - if (wtsEnabled != _enabled) - { - _enabled = wtsEnabled; - dataModified = true; - } - - // Options. - if (wtsOptions.DoNotAllowDemandStart != _options.DoNotAllowDemandStart || - wtsOptions.IdleDuration != _options.IdleDuration || - wtsOptions.IdleTimeout != _options.IdleTimeout || - wtsOptions.MultipleInstancePolicy != _options.MultipleInstancePolicy || - wtsOptions.RestartOnIdleResume != _options.RestartOnIdleResume || - wtsOptions.RunElevated != _options.RunElevated || - wtsOptions.RunWithoutNetwork != _options.RunWithoutNetwork || - wtsOptions.ShowInTaskScheduler != _options.ShowInTaskScheduler || - wtsOptions.StartIfNotIdle != _options.StartIfNotIdle || - wtsOptions.StartIfOnBatteries != _options.StartIfOnBatteries || - wtsOptions.StopIfGoingOffIdle != _options.StopIfGoingOffIdle || - wtsOptions.StopIfGoingOnBatteries != _options.StopIfGoingOnBatteries || - wtsOptions.WakeToRun != _options.WakeToRun) - { - // Keep the current scheduled job definition reference. - wtsOptions.JobDefinition = _options.JobDefinition; - _options = wtsOptions; - dataModified = true; - } - - // Triggers. - if (_triggers.Count != wtsTriggers.Count) - { - SetTriggers(wtsTriggers, false); - dataModified = true; - } - else - { - bool foundTriggerDiff = false; - - // Compare each trigger object. - foreach (var wtsTrigger in wtsTriggers) - { - if (_triggers.ContainsKey(wtsTrigger.Id) == false) - { - foundTriggerDiff = true; - break; - } - - ScheduledJobTrigger trigger = _triggers[wtsTrigger.Id]; - if (trigger.DaysOfWeek != wtsTrigger.DaysOfWeek || - trigger.Enabled != wtsTrigger.Enabled || - trigger.Frequency != wtsTrigger.Frequency || - trigger.Interval != wtsTrigger.Interval || - trigger.RandomDelay != wtsTrigger.RandomDelay || - trigger.At != wtsTrigger.At || - trigger.User != wtsTrigger.User) - { - foundTriggerDiff = true; - break; - } - } - - if (foundTriggerDiff) - { - SetTriggers(wtsTriggers, false); - dataModified = true; - } - } - } - - return dataModified; - } - - /// - /// Adds this scheduled job definition to the Task Scheduler. - /// - private void AddToWTS() - { - using (ScheduledJobWTS taskScheduler = new ScheduledJobWTS()) - { - taskScheduler.CreateTask(this); - } - } - - /// - /// Removes this scheduled job definition from the Task Scheduler. - /// This operation will fail if a current instance of this job definition - /// is running. - /// If force == true then all current instances will be stopped. - /// - /// Force removal and stop all running instances. - private void RemoveFromWTS(bool force) - { - using (ScheduledJobWTS taskScheduler = new ScheduledJobWTS()) - { - taskScheduler.RemoveTask(this, force); - } - } - - /// - /// Adds this scheduled job definition to the job definition store. - /// - private void AddToJobStore() - { - FileStream fs = null; - try - { - fs = ScheduledJobStore.CreateFileForJobDefinition(Name); - _definitionFilePath = ScheduledJobStore.GetJobDefinitionLocation(); - _definitionOutputPath = ScheduledJobStore.GetJobRunOutputDirectory(Name); - - XmlObjectSerializer serializer = new System.Runtime.Serialization.NetDataContractSerializer(); - serializer.WriteObject(fs, this); - fs.Flush(); - } - finally - { - if (fs != null) - { - fs.Close(); - } - } - - // If credentials are provided then update permissions. - if (Credential != null) - { - UpdateFilePermissions(Credential.UserName); - } - } - - /// - /// Updates existing file with this definition information. - /// - private void UpdateJobStore() - { - FileStream fs = null; - try - { - // Overwrite the existing file. - fs = GetFileStream( - Name, - _definitionFilePath, - FileMode.Create, - FileAccess.Write, - FileShare.None); - - XmlObjectSerializer serializer = new System.Runtime.Serialization.NetDataContractSerializer(); - serializer.WriteObject(fs, this); - fs.Flush(); - } - finally - { - if (fs != null) - { - fs.Close(); - } - } - - // If credentials are provided then update permissions. - if (Credential != null) - { - UpdateFilePermissions(Credential.UserName); - } - } - - /// - /// Updates definition file permissions for provided user account. - /// - /// Account user name. - private void UpdateFilePermissions(string user) - { - Exception ex = null; - try - { - // Add user for read access to the job definition file. - ScheduledJobStore.SetReadAccessOnDefinitionFile(Name, user); - - // Add user for write access to the job run Output directory. - ScheduledJobStore.SetWriteAccessOnJobRunOutput(Name, user); - } - catch (System.Security.Principal.IdentityNotMappedException e) - { - ex = e; - } - catch (IOException e) - { - ex = e; - } - catch (UnauthorizedAccessException e) - { - ex = e; - } - catch (ArgumentNullException e) - { - ex = e; - } - - if (ex != null) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.ErrorSettingAccessPermissions, this.Name, Credential.UserName); - throw new ScheduledJobException(msg, ex); - } - } - - /// - /// Removes this scheduled job definition from the job definition store. - /// - private void RemoveFromJobStore() - { - ScheduledJobStore.RemoveJobDefinition(Name); - } - - /// - /// Throws exception if object is disposed. - /// - private void IsDisposed() - { - if (_isDisposed == true) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.DefinitionObjectDisposed, Name); - throw new RuntimeException(msg); - } - } - - /// - /// If repository is empty try refreshing it from the store. - /// - private void LoadRepository() - { - ScheduledJobDefinition.RefreshRepositoryFromStore(); - } - - /// - /// Validates all triggers in collection. An exception is thrown - /// for invalid triggers. - /// - /// - private void ValidateTriggers(IEnumerable triggers) - { - if (triggers != null) - { - foreach (var trigger in triggers) - { - trigger.Validate(); - } - } - } - - /// - /// Validates the job definition name. Since the job definition - /// name is used in the job store as a directory name, make sure - /// it does not contain any invalid characters. - /// - private static void ValidateName(string name) - { - if (name.IndexOfAny(System.IO.Path.GetInvalidFileNameChars()) != -1) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidJobDefName, name); - throw new ScheduledJobException(msg); - } - } - - /// - /// Iterates through all job run files, opens each job - /// run and renames it to the provided new name. - /// - /// New job run name. - private void UpdateJobRunNames( - string newDefName) - { - // Job run results will be under the new scheduled job definition name. - Collection jobRuns = ScheduledJobSourceAdapter.GetJobRuns(newDefName); - if (jobRuns == null) - { - return; - } - - // Load and rename each job. - ScheduledJobDefinition definition = ScheduledJobDefinition.LoadFromStore(newDefName, null); - foreach (DateTime jobRun in jobRuns) - { - ScheduledJob job = null; - try - { - job = ScheduledJobSourceAdapter.LoadJobFromStore(definition.Name, jobRun) as ScheduledJob; - } - catch (ScheduledJobException) - { - continue; - } - catch (DirectoryNotFoundException) - { - continue; - } - catch (FileNotFoundException) - { - continue; - } - catch (UnauthorizedAccessException) - { - continue; - } - catch (IOException) - { - continue; - } - - if (job != null) - { - job.Name = newDefName; - job.Definition = definition; - ScheduledJobSourceAdapter.SaveJobToStore(job); - } - } - } - - /// - /// Handles known Task Scheduler COM error codes. - /// - /// COMException. - /// Error message. - private string ConvertCOMErrorCode(System.Runtime.InteropServices.COMException e) - { - string msg = null; - switch (e.ErrorCode) - { - case TSErrorDisabledTask: - msg = ScheduledJobErrorStrings.ReasonTaskDisabled; - break; - } - - return msg; - } - - #endregion - - #region Internal Methods - - /// - /// Save object to store. - /// - internal void SaveToStore() - { - IsDisposed(); - - UpdateJobStore(); - } - - /// - /// Compares the task scheduler information in this object with - /// what is stored in Task Scheduler. If there is a difference - /// then this object is updated with the information from Task - /// Scheduler and saved to the job store. - /// - internal void SyncWithWTS() - { - Exception notFoundEx = null; - try - { - if (UpdateDefinitionFromWTS()) - { - SaveToStore(); - } - } - catch (DirectoryNotFoundException e) - { - notFoundEx = e; - } - catch (FileNotFoundException e) - { - notFoundEx = e; - } - - if (notFoundEx != null) - { - // There is no corresponding Task Scheduler item for this - // scheduled job definition. Remove this definition from - // the job store for consistency. - Remove(true); - throw notFoundEx; - } - } - - /// - /// Renames scheduled job definition, store directory and task scheduler task. - /// - /// New name of job definition. - internal void RenameAndSave(string newName) - { - if (InvocationInfo.Name.Equals(newName, StringComparison.OrdinalIgnoreCase)) - { - return; - } - - ValidateName(newName); - - // Attempt to rename job store directory. Detect if new name - // is not unique. - string oldName = InvocationInfo.Name; - Exception ex = null; - try - { - ScheduledJobStore.RenameScheduledJobDefDir(oldName, newName); - } - catch (ArgumentException e) - { - ex = e; - } - catch (DirectoryNotFoundException e) - { - ex = e; - } - catch (FileNotFoundException e) - { - ex = e; - } - catch (UnauthorizedAccessException e) - { - ex = e; - } - catch (IOException e) - { - ex = e; - } - - if (ex != null) - { - string msg; - if (!string.IsNullOrEmpty(ex.Message)) - { - msg = StringUtil.Format(ScheduledJobErrorStrings.ErrorRenamingScheduledJobWithMessage, oldName, newName, ex.Message); - } - else - { - msg = StringUtil.Format(ScheduledJobErrorStrings.ErrorRenamingScheduledJob, oldName, newName); - } - - throw new ScheduledJobException(msg, ex); - } - - try - { - // Remove old named Task Scheduler task. - // This also stops any existing running job. - RemoveFromWTS(true); - - // Update job definition names. - _name = newName; - InvocationInfo.Name = newName; - InvocationInfo.Definition.Name = newName; - _definitionOutputPath = ScheduledJobStore.GetJobRunOutputDirectory(Name); - - // Update job definition in new job store location. - UpdateJobStore(); - - // Add new Task Scheduler task with new name. - // Jobs can start running again. - AddToWTS(); - - // Update any existing job run names. - UpdateJobRunNames(newName); - } - catch (ArgumentException e) - { - ex = e; - } - catch (DirectoryNotFoundException e) - { - ex = e; - } - catch (FileNotFoundException e) - { - ex = e; - } - catch (UnauthorizedAccessException e) - { - ex = e; - } - catch (IOException e) - { - ex = e; - } - finally - { - // Clear job run cache since job runs now appear in new directory location. - ScheduledJobSourceAdapter.ClearRepository(); - } - - // If any part of renaming the various scheduled job components fail, - // aggressively remove scheduled job corrupted state and inform user. - if (ex != null) - { - try - { - Remove(true); - } - catch (ScheduledJobException e) - { - ex.Data.Add("SchedJobRemoveError", e); - } - - string msg; - if (!string.IsNullOrEmpty(ex.Message)) - { - msg = StringUtil.Format(ScheduledJobErrorStrings.BrokenRenamingScheduledJobWithMessage, oldName, newName, ex.Message); - } - else - { - msg = StringUtil.Format(ScheduledJobErrorStrings.BrokenRenamingScheduledJob, oldName, newName); - } - - throw new ScheduledJobException(msg, ex); - } - } - - #endregion - - #region Public Methods - - /// - /// Registers this scheduled job definition object by doing the - /// following: - /// a) Writing this object to the scheduled job object store. - /// b) Registering this job as a Windows Task Scheduler task. - /// c) Adding this object to the local repository. - /// - public void Register() - { - IsDisposed(); - - LoadRepository(); - - ValidateName(Name); - - // First add to the job store. If an exception occurs here - // then this method fails with no clean up. - Exception ex = null; - bool corruptedFile = false; - try - { - AddToJobStore(); - } - catch (ArgumentException e) - { - ex = e; - } - catch (DirectoryNotFoundException e) - { - ex = e; - } - catch (FileNotFoundException e) - { - ex = e; - } - catch (UnauthorizedAccessException e) - { - ex = e; - } - catch (IOException e) - { - ex = e; - } - catch (System.Runtime.Serialization.SerializationException e) - { - corruptedFile = true; - ex = e; - } - catch (System.Runtime.Serialization.InvalidDataContractException e) - { - corruptedFile = true; - ex = e; - } - catch (ScheduledJobException e) - { - // Can be thrown for error setting file access permissions with supplied credentials. - // But file is not considered corrupted if it already exists. - corruptedFile = !(e.FQEID.Equals(ScheduledJobStore.ScheduledJobDefExistsFQEID, StringComparison.OrdinalIgnoreCase)); - ex = e; - } - - if (ex != null) - { - if (corruptedFile) - { - // Remove from store. - try - { - ScheduledJobStore.RemoveJobDefinition(Name); - } - catch (DirectoryNotFoundException) - { } - catch (FileNotFoundException) - { } - catch (UnauthorizedAccessException) - { } - catch (IOException) - { } - } - - if (ex is not ScheduledJobException) - { - // Wrap in ScheduledJobException type. - string msg = StringUtil.Format(ScheduledJobErrorStrings.ErrorRegisteringDefinitionStore, this.Name); - throw new ScheduledJobException(msg, ex); - } - else - { - // Otherwise just re-throw. - throw ex; - } - } - - // Next register with the Task Scheduler. - ex = null; - try - { - AddToWTS(); - } - catch (ArgumentException e) - { - ex = e; - } - catch (DirectoryNotFoundException e) - { - ex = e; - } - catch (FileNotFoundException e) - { - ex = e; - } - catch (UnauthorizedAccessException e) - { - ex = e; - } - catch (IOException e) - { - ex = e; - } - catch (System.Runtime.InteropServices.COMException e) - { - ex = e; - } - - if (ex != null) - { - // Clean up job store. - RemoveFromJobStore(); - - string msg = StringUtil.Format(ScheduledJobErrorStrings.ErrorRegisteringDefinitionTask, - this.Name, - (string.IsNullOrEmpty(ex.Message) == false) ? ex.Message : string.Empty); - throw new ScheduledJobException(msg, ex); - } - - // Finally add to the local repository. - Repository.AddOrReplace(this); - } - - /// - /// Saves this scheduled job definition object: - /// a) Rewrites this object to the scheduled job object store. - /// b) Updates the Windows Task Scheduler task. - /// - public void Save() - { - IsDisposed(); - - LoadRepository(); - - ValidateName(Name); - - // First update the Task Scheduler. If an exception occurs here then - // we fail with no clean up. - Exception ex = null; - try - { - UpdateWTSFromDefinition(); - } - catch (ArgumentException e) - { - ex = e; - } - catch (DirectoryNotFoundException e) - { - ex = e; - } - catch (FileNotFoundException e) - { - ex = e; - } - catch (UnauthorizedAccessException e) - { - ex = e; - } - catch (IOException e) - { - ex = e; - } - catch (System.Runtime.InteropServices.COMException e) - { - ex = e; - } - - if (ex != null) - { - // We want this object to remain synchronized with what is in WTS. - SyncWithWTS(); - - string msg = StringUtil.Format(ScheduledJobErrorStrings.ErrorUpdatingDefinitionTask, this.Name); - throw new ScheduledJobException(msg, ex); - } - - // Next save to job store. - ex = null; - try - { - UpdateJobStore(); - } - catch (ArgumentException e) - { - ex = e; - } - catch (DirectoryNotFoundException e) - { - ex = e; - } - catch (FileNotFoundException e) - { - ex = e; - } - catch (UnauthorizedAccessException e) - { - ex = e; - } - catch (IOException e) - { - ex = e; - } - - if (ex != null) - { - // Remove this from WTS for consistency. - RemoveFromWTS(true); - - string msg = StringUtil.Format(ScheduledJobErrorStrings.ErrorUpdatingDefinitionStore, this.Name); - throw new ScheduledJobException(msg, ex); - } - - // Finally update this object in the local repository. - ScheduledJobDefinition.RefreshRepositoryFromStore(); - Repository.AddOrReplace(this); - } - - /// - /// Removes this definition object: - /// a) Removes from the Task Scheduler - /// or fails if an instance is currently running. - /// or stops any running instances if force is true. - /// b) Removes from the scheduled job definition store. - /// c) Removes from the local repository. - /// d) Disposes this object. - /// - public void Remove(bool force) - { - IsDisposed(); - - // First remove from Task Scheduler. Catch not found - // exceptions and continue. - try - { - RemoveFromWTS(force); - } - catch (System.IO.DirectoryNotFoundException) - { - // Continue with removal. - } - catch (System.IO.FileNotFoundException) - { - // Continue with removal. - } - - // Remove from the Job Store. Catch exceptions and continue - // with removal. - Exception ex = null; - try - { - RemoveFromJobStore(); - } - catch (DirectoryNotFoundException) - { - } - catch (FileNotFoundException) - { - } - catch (ArgumentException e) - { - ex = e; - } - catch (UnauthorizedAccessException e) - { - ex = e; - } - catch (IOException e) - { - ex = e; - } - finally - { - // Remove from the local repository. - Repository.Remove(this); - - // Remove job runs for this definition from local repository. - ScheduledJobSourceAdapter.ClearRepositoryForDefinition(this.Name); - - // Dispose this object. - Dispose(); - } - - if (ex != null) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.ErrorRemovingDefinitionStore, this.Name); - throw new ScheduledJobException(msg, ex); - } - } - - /// - /// Starts the scheduled job immediately. A ScheduledJob object is - /// returned that represents the running command, and this returned - /// job is also added to the local job repository. Job results are - /// not written to the job store. - /// - /// ScheduledJob object for running job. - public ScheduledJob StartJob() - { - IsDisposed(); - - ScheduledJob job = new ScheduledJob(_invocationInfo.Command, _invocationInfo.Name, this); - job.StartJob(); - - return job; - } - - /// - /// Starts registered job definition running from the Task Scheduler. - /// - public void RunAsTask() - { - IsDisposed(); - - Exception ex = null; - string reason = null; - try - { - using (ScheduledJobWTS taskScheduler = new ScheduledJobWTS()) - { - taskScheduler.RunTask(this); - } - } - catch (System.IO.DirectoryNotFoundException e) - { - reason = ScheduledJobErrorStrings.reasonJobNotFound; - ex = e; - } - catch (System.IO.FileNotFoundException e) - { - reason = ScheduledJobErrorStrings.reasonJobNotFound; - ex = e; - } - catch (System.Runtime.InteropServices.COMException e) - { - reason = ConvertCOMErrorCode(e); - ex = e; - } - - if (ex != null) - { - string msg; - if (reason != null) - { - msg = StringUtil.Format(ScheduledJobErrorStrings.ErrorRunningAsTaskWithReason, this.Name, reason); - } - else - { - msg = StringUtil.Format(ScheduledJobErrorStrings.ErrorRunningAsTask, this.Name); - } - - throw new ScheduledJobException(msg, ex); - } - } - - #endregion - - #region Public Trigger Methods - - /// - /// Adds new ScheduledJobTriggers. - /// - /// Collection of ScheduledJobTrigger objects. - /// Update Windows Task Scheduler and save to store. - public void AddTriggers( - IEnumerable triggers, - bool save) - { - IsDisposed(); - - if (triggers == null) - { - throw new PSArgumentNullException("triggers"); - } - - // First validate all triggers. - ValidateTriggers(triggers); - - Collection newTriggerIds = new Collection(); - foreach (ScheduledJobTrigger trigger in triggers) - { - ScheduledJobTrigger newTrigger = new ScheduledJobTrigger(trigger); - - newTrigger.Id = ++_currentTriggerId; - newTriggerIds.Add(newTrigger.Id); - newTrigger.JobDefinition = this; - _triggers.Add(newTrigger.Id, newTrigger); - } - - if (save) - { - Save(); - } - } - - /// - /// Removes triggers matching passed in trigger Ids. - /// - /// Trigger Ids to remove. - /// Update Windows Task Scheduler and save to store. - /// Trigger Ids not found. - public List RemoveTriggers( - IEnumerable triggerIds, - bool save) - { - IsDisposed(); - - List idsNotFound = new List(); - bool triggerFound = false; - - // triggerIds is null then remove all triggers. - if (triggerIds == null) - { - _currentTriggerId = 0; - if (_triggers.Count > 0) - { - triggerFound = true; - - foreach (ScheduledJobTrigger trigger in _triggers.Values) - { - trigger.Id = 0; - trigger.JobDefinition = null; - } - - // Create new empty trigger collection. - _triggers = new Dictionary(); - } - } - else - { - foreach (Int32 removeId in triggerIds) - { - if (_triggers.ContainsKey(removeId)) - { - _triggers[removeId].JobDefinition = null; - _triggers[removeId].Id = 0; - _triggers.Remove(removeId); - triggerFound = true; - } - else - { - idsNotFound.Add(removeId); - } - } - } - - if (save && triggerFound) - { - Save(); - } - - return idsNotFound; - } - - /// - /// Updates triggers with provided trigger objects, matching passed in - /// trigger Id with existing trigger Id. - /// - /// Collection of ScheduledJobTrigger objects to update. - /// Update Windows Task Scheduler and save to store. - /// Trigger Ids not found. - public List UpdateTriggers( - IEnumerable triggers, - bool save) - { - IsDisposed(); - - if (triggers == null) - { - throw new PSArgumentNullException("triggers"); - } - - // First validate all triggers. - ValidateTriggers(triggers); - - List idsNotFound = new List(); - bool triggerFound = false; - foreach (ScheduledJobTrigger updateTrigger in triggers) - { - if (_triggers.ContainsKey(updateTrigger.Id)) - { - // Disassociate old trigger from this definition. - _triggers[updateTrigger.Id].JobDefinition = null; - - // Replace older trigger object with new updated one. - ScheduledJobTrigger newTrigger = new ScheduledJobTrigger(updateTrigger); - newTrigger.Id = updateTrigger.Id; - newTrigger.JobDefinition = this; - _triggers[newTrigger.Id] = newTrigger; - triggerFound = true; - } - else - { - idsNotFound.Add(updateTrigger.Id); - } - } - - if (save && triggerFound) - { - Save(); - } - - return idsNotFound; - } - - /// - /// Creates a new set of ScheduledJobTriggers for this object. - /// - /// Array of ScheduledJobTrigger objects to set. - /// Update Windows Task Scheduler and save to store. - public void SetTriggers( - IEnumerable newTriggers, - bool save) - { - IsDisposed(); - - // First validate all triggers. - ValidateTriggers(newTriggers); - - // Disassociate any old trigger objects from this definition. - foreach (ScheduledJobTrigger trigger in _triggers.Values) - { - trigger.JobDefinition = null; - } - - _currentTriggerId = 0; - _triggers = new Dictionary(); - if (newTriggers != null) - { - foreach (ScheduledJobTrigger trigger in newTriggers) - { - ScheduledJobTrigger newTrigger = new ScheduledJobTrigger(trigger); - - newTrigger.Id = ++_currentTriggerId; - newTrigger.JobDefinition = this; - _triggers.Add(newTrigger.Id, newTrigger); - } - } - - if (save) - { - Save(); - } - } - - /// - /// Returns a list of new ScheduledJobTrigger objects corresponding - /// to the passed in trigger Ids. Also returns an array of trigger Ids - /// that were not found in an out parameter. - /// - /// List of trigger Ids. - /// List of not found trigger Ids. - /// List of ScheduledJobTrigger objects. - public List GetTriggers( - IEnumerable triggerIds, - out List notFoundIds) - { - IsDisposed(); - - List newTriggers; - List notFoundList = new List(); - if (triggerIds == null) - { - // Return all triggers. - newTriggers = new List(); - foreach (ScheduledJobTrigger trigger in _triggers.Values) - { - newTriggers.Add(new ScheduledJobTrigger(trigger)); - } - } - else - { - // Filter returned triggers to match requested. - newTriggers = new List(); - foreach (Int32 triggerId in triggerIds) - { - if (_triggers.ContainsKey(triggerId)) - { - newTriggers.Add(new ScheduledJobTrigger(_triggers[triggerId])); - } - else - { - notFoundList.Add(triggerId); - } - } - } - - notFoundIds = notFoundList; - - // Return array of ScheduledJobTrigger objects sorted by Id. - newTriggers.Sort((firstTrigger, secondTrigger) => - { - return ((int)firstTrigger.Id - (int)secondTrigger.Id); - }); - - return newTriggers; - } - - /// - /// Finds and returns a copy of the ScheduledJobTrigger corresponding to - /// the passed in trigger Id. - /// - /// Trigger Id. - /// ScheduledJobTrigger object. - public ScheduledJobTrigger GetTrigger( - Int32 triggerId) - { - IsDisposed(); - - if (_triggers.ContainsKey(triggerId)) - { - return new ScheduledJobTrigger(_triggers[triggerId]); - } - - return null; - } - - #endregion - - #region Public Update Methods - - /// - /// Updates scheduled job options. - /// - /// ScheduledJobOptions or null for default. - /// Update Windows Task Scheduler and save to store. - public void UpdateOptions( - ScheduledJobOptions options, - bool save) - { - IsDisposed(); - - // Disassociate current options object from this definition. - _options.JobDefinition = null; - - // options == null is allowed and signals the use default - // Task Scheduler options. - _options = (options != null) ? new ScheduledJobOptions(options) : - new ScheduledJobOptions(); - _options.JobDefinition = this; - - if (save) - { - Save(); - } - } - - /// - /// Sets the execution history length property. - /// - /// Execution history length. - /// Save to store. - public void SetExecutionHistoryLength( - int executionHistoryLength, - bool save) - { - IsDisposed(); - - _executionHistoryLength = executionHistoryLength; - - if (save) - { - SaveToStore(); - } - } - - /// - /// Clears all execution results in the job store. - /// - public void ClearExecutionHistory() - { - IsDisposed(); - - ScheduledJobStore.RemoveAllJobRuns(Name); - ScheduledJobSourceAdapter.ClearRepositoryForDefinition(Name); - } - - /// - /// Updates the JobInvocationInfo object. - /// - /// JobInvocationInfo. - /// Save to store. - public void UpdateJobInvocationInfo( - JobInvocationInfo jobInvocationInfo, - bool save) - { - IsDisposed(); - - if (jobInvocationInfo == null) - { - throw new PSArgumentNullException("jobInvocationInfo"); - } - - _invocationInfo = jobInvocationInfo; - _name = jobInvocationInfo.Name; - - if (save) - { - SaveToStore(); - } - } - - /// - /// Sets the enabled state of this object. - /// - /// True if enabled. - /// Update Windows Task Scheduler and save to store. - public void SetEnabled( - bool enabled, - bool save) - { - IsDisposed(); - - _enabled = enabled; - - if (save) - { - Save(); - } - } - - /// - /// Sets the name of this scheduled job definition. - /// - /// Name. - /// Update Windows Task Scheduler and save to store. - public void SetName( - string name, - bool save) - { - IsDisposed(); - - _name = (name != null) ? name : string.Empty; - - if (save) - { - Save(); - } - } - - #endregion - - #region IDisposable - - /// - /// Dispose. - /// - public void Dispose() - { - _isDisposed = true; - - GC.SuppressFinalize(this); - } - - #endregion - - #region Static Methods - - /// - /// Synchronizes the local ScheduledJobDefinition repository with the - /// scheduled job definitions in the job store. - /// - /// Callback delegate for each discovered item. - /// Dictionary of errors. - internal static Dictionary RefreshRepositoryFromStore( - Action itemFound = null) - { - Dictionary errors = new Dictionary(); - - // Get current list of job definition files in store, and create hash - // table for quick look up. - IEnumerable jobDefinitionPathNames = ScheduledJobStore.GetJobDefinitions(); - HashSet jobDefinitionNamesHash = new HashSet(); - foreach (string pathName in jobDefinitionPathNames) - { - // Remove path information and use job definition name only. - int indx = pathName.LastIndexOf('\\'); - string jobDefName = (indx != -1) ? pathName.Substring(indx + 1) : pathName; - jobDefinitionNamesHash.Add(jobDefName); - } - - // First remove definition objects not in store. - // Repository.Definitions returns a *copy* of current repository items. - foreach (ScheduledJobDefinition jobDef in Repository.Definitions) - { - if (jobDefinitionNamesHash.Contains(jobDef.Name) == false) - { - Repository.Remove(jobDef); - } - else - { - jobDefinitionNamesHash.Remove(jobDef.Name); - - if (itemFound != null) - { - itemFound(jobDef); - } - } - } - - // Next add definition items not in local repository. - foreach (string jobDefinitionName in jobDefinitionNamesHash) - { - try - { - // Read the job definition object from file and add to local repository. - ScheduledJobDefinition jobDefinition = ScheduledJobDefinition.LoadDefFromStore(jobDefinitionName, null); - Repository.AddOrReplace(jobDefinition); - - if (itemFound != null) - { - itemFound(jobDefinition); - } - } - catch (System.IO.IOException e) - { - errors.Add(jobDefinitionName, e); - } - catch (System.Xml.XmlException e) - { - errors.Add(jobDefinitionName, e); - } - catch (System.TypeInitializationException e) - { - errors.Add(jobDefinitionName, e); - } - catch (System.Runtime.Serialization.SerializationException e) - { - errors.Add(jobDefinitionName, e); - } - catch (System.ArgumentNullException e) - { - errors.Add(jobDefinitionName, e); - } - catch (System.UnauthorizedAccessException e) - { - errors.Add(jobDefinitionName, e); - } - } - - return errors; - } - - /// - /// Reads a ScheduledJobDefinition object from file and - /// returns object. - /// - /// Name of definition to load. - /// Path to definition file. - /// ScheduledJobDefinition object. - internal static ScheduledJobDefinition LoadDefFromStore( - string definitionName, - string definitionPath) - { - ScheduledJobDefinition definition = null; - FileStream fs = null; - try - { - fs = GetFileStream( - definitionName, - definitionPath, - FileMode.Open, - FileAccess.Read, - FileShare.Read); - - XmlObjectSerializer serializer = new System.Runtime.Serialization.NetDataContractSerializer(); - definition = serializer.ReadObject(fs) as ScheduledJobDefinition; - } - finally - { - if (fs != null) - { - fs.Close(); - } - } - - return definition; - } - - /// - /// Creates a new ScheduledJobDefinition object from a file. - /// - /// Name of definition to load. - /// Path to definition file. - /// ScheduledJobDefinition object. - public static ScheduledJobDefinition LoadFromStore( - string definitionName, - string definitionPath) - { - if (string.IsNullOrEmpty(definitionName)) - { - throw new PSArgumentNullException("definitionName"); - } - - ScheduledJobDefinition definition = null; - bool corruptedFile = false; - Exception ex = null; - - try - { - definition = LoadDefFromStore(definitionName, definitionPath); - } - catch (DirectoryNotFoundException e) - { - ex = e; - } - catch (FileNotFoundException e) - { - ex = e; - corruptedFile = true; - } - catch (UnauthorizedAccessException e) - { - ex = e; - } - catch (IOException e) - { - ex = e; - } - catch (System.Xml.XmlException e) - { - ex = e; - corruptedFile = true; - } - catch (System.TypeInitializationException e) - { - ex = e; - corruptedFile = true; - } - catch (System.ArgumentNullException e) - { - ex = e; - corruptedFile = true; - } - catch (System.Runtime.Serialization.SerializationException e) - { - ex = e; - corruptedFile = true; - } - - if (ex != null) - { - // - // Remove definition if corrupted. - // But only if the corrupted file is in the default scheduled jobs - // path for the current user. - // - if (corruptedFile && - (definitionPath == null || - ScheduledJobStore.IsDefaultUserPath(definitionPath))) - { - // Remove corrupted scheduled job definition. - RemoveDefinition(definitionName); - - // Throw exception for corrupted/removed job definition. - throw new ScheduledJobException( - StringUtil.Format(ScheduledJobErrorStrings.CantLoadDefinitionFromStore, definitionName), - ex); - } - - // Throw exception for not found job definition. - throw new ScheduledJobException( - StringUtil.Format(ScheduledJobErrorStrings.CannotFindJobDefinition, definitionName), - ex); - } - - // Make sure the deserialized ScheduledJobDefinition object contains the same - // Task Scheduler information that is stored in Task Scheduler. - definition.SyncWithWTS(); - - return definition; - } - - /// - /// Internal helper method to remove a scheduled job definition - /// by name from job store and Task Scheduler. - /// - /// Scheduled job definition name. - internal static void RemoveDefinition( - string definitionName) - { - // Remove from store. - try - { - ScheduledJobStore.RemoveJobDefinition(definitionName); - } - catch (DirectoryNotFoundException) - { } - catch (FileNotFoundException) - { } - catch (UnauthorizedAccessException) - { } - catch (IOException) - { } - - // Check and remove from Task Scheduler. - using (ScheduledJobWTS taskScheduler = new ScheduledJobWTS()) - { - try - { - taskScheduler.RemoveTaskByName(definitionName, true, true); - } - catch (UnauthorizedAccessException) - { } - catch (IOException) - { } - } - } - - private static int GetCurrentId() - { - lock (LockObject) - { - return ++CurrentId; - } - } - - /// - /// Starts a scheduled job based on definition name and returns the - /// running job object. Returned job is also added to the local - /// job repository. Job results are not written to store. - /// - /// ScheduledJobDefinition name. - public static Job2 StartJob( - string DefinitionName) - { - // Load scheduled job definition. - ScheduledJobDefinition jobDefinition = ScheduledJobDefinition.LoadFromStore(DefinitionName, null); - - // Start job. - return jobDefinition.StartJob(); - } - - private static FileStream GetFileStream( - string definitionName, - string definitionPath, - FileMode fileMode, - FileAccess fileAccess, - FileShare fileShare) - { - FileStream fs; - - if (definitionPath == null) - { - // Look for definition in default current user location. - fs = ScheduledJobStore.GetFileForJobDefinition( - definitionName, - fileMode, - fileAccess, - fileShare); - } - else - { - // Look for definition in known path. - fs = ScheduledJobStore.GetFileForJobDefinition( - definitionName, - definitionPath, - fileMode, - fileAccess, - fileShare); - } - - return fs; - } - - #endregion - - #region Running Job - - /// - /// Create a Job2 job, runs it and waits for it to complete. - /// Job status and results are written to the job store. - /// - /// Job2 job object that was run. - public Job2 Run() - { - Job2 job = null; - - using (PowerShellTraceSource _tracer = PowerShellTraceSourceFactory.GetTraceSource()) - { - Exception ex = null; - try - { - JobManager jobManager = Runspace.DefaultRunspace.JobManager; - - job = jobManager.NewJob(InvocationInfo); - - // If this is a scheduled job type then include this object so - // so that ScheduledJobSourceAdapter knows where the results are - // to be stored. - ScheduledJob schedJob = job as ScheduledJob; - if (schedJob != null) - { - schedJob.Definition = this; - schedJob.AllowSetShouldExit = true; - } - - // Update job store data when job begins. - job.StateChanged += (object sender, JobStateEventArgs e) => - { - if (e.JobStateInfo.State == JobState.Running) - { - // Write job to store with this running state. - jobManager.PersistJob(job, Definition); - } - }; - - job.StartJob(); - - // Log scheduled job start. - _tracer.WriteScheduledJobStartEvent( - job.Name, - job.PSBeginTime.ToString()); - - // Wait for job to finish. - job.Finished.WaitOne(); - - // Ensure that the job run results are persisted to store. - jobManager.PersistJob(job, Definition); - - // Perform a Receive-Job on the job object. Output data will be dropped - // but we do this to execute any client method calls, in particular we - // want SetShouldExit to set the correct exit code on the process for - // use inside Task Scheduler. - using (System.Management.Automation.PowerShell ps = System.Management.Automation.PowerShell.Create()) - { - // Run on the default runspace. - ps.AddCommand("Receive-Job").AddParameter("Job", job).AddParameter("Keep", true); - ps.Invoke(); - } - - // Log scheduled job finish. - _tracer.WriteScheduledJobCompleteEvent( - job.Name, - job.PSEndTime.ToString(), - job.JobStateInfo.State.ToString()); - } - catch (RuntimeException e) - { - ex = e; - } - catch (InvalidOperationException e) - { - ex = e; - } - catch (System.Security.SecurityException e) - { - ex = e; - } - catch (IOException e) - { - ex = e; - } - catch (UnauthorizedAccessException e) - { - ex = e; - } - catch (ArgumentException e) - { - ex = e; - } - catch (ScriptCallDepthException e) - { - ex = e; - } - catch (System.Runtime.Serialization.SerializationException e) - { - ex = e; - } - catch (System.Runtime.Serialization.InvalidDataContractException e) - { - ex = e; - } - catch (System.Xml.XmlException e) - { - ex = e; - } - catch (Microsoft.PowerShell.ScheduledJob.ScheduledJobException e) - { - ex = e; - } - - if (ex != null) - { - // Log error. - _tracer.WriteScheduledJobErrorEvent( - this.Name, - ex.Message, - ex.StackTrace.ToString(), - (ex.InnerException != null) ? ex.InnerException.Message : string.Empty); - - throw ex; - } - } - - return job; - } - - #endregion - } - - #region ScheduledJobDefinition Repository - - /// - /// Collection of ScheduledJobDefinition objects. - /// - internal class ScheduledJobDefinitionRepository - { - #region Private Members - - private object _syncObject = new object(); - private Dictionary _definitions = new Dictionary(); - - #endregion - - #region Public Properties - - /// - /// Returns all definition objects in the repository as a List. - /// - public List Definitions - { - get - { - lock (_syncObject) - { - // Sort returned list by Ids. - List rtnList = - new List(_definitions.Values); - - rtnList.Sort((firstJob, secondJob) => - { - if (firstJob.Id > secondJob.Id) - { - return 1; - } - else if (firstJob.Id < secondJob.Id) - { - return -1; - } - else - { - return 0; - } - }); - - return rtnList; - } - } - } - - /// - /// Returns count of object in repository. - /// - public int Count - { - get - { - lock (_syncObject) - { - return _definitions.Count; - } - } - } - - #endregion - - #region Public Methods - - /// - /// Add ScheduledJobDefinition to repository. - /// - /// - public void Add(ScheduledJobDefinition jobDef) - { - if (jobDef == null) - { - throw new PSArgumentNullException("jobDef"); - } - - lock (_syncObject) - { - if (_definitions.ContainsKey(jobDef.Name)) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.DefinitionAlreadyExistsInLocal, jobDef.Name, jobDef.GlobalId); - throw new ScheduledJobException(msg); - } - - _definitions.Add(jobDef.Name, jobDef); - } - } - - /// - /// Add or replace passed in ScheduledJobDefinition object to repository. - /// - /// - public void AddOrReplace(ScheduledJobDefinition jobDef) - { - if (jobDef == null) - { - throw new PSArgumentNullException("jobDef"); - } - - lock (_syncObject) - { - if (_definitions.ContainsKey(jobDef.Name)) - { - _definitions.Remove(jobDef.Name); - } - - _definitions.Add(jobDef.Name, jobDef); - } - } - - /// - /// Remove ScheduledJobDefinition from repository. - /// - /// - public void Remove(ScheduledJobDefinition jobDef) - { - if (jobDef == null) - { - throw new PSArgumentNullException("jobDef"); - } - - lock (_syncObject) - { - if (_definitions.ContainsKey(jobDef.Name)) - { - _definitions.Remove(jobDef.Name); - } - } - } - - /// - /// Checks to see if a ScheduledJobDefinition object exists with - /// the provided definition name. - /// - /// Definition name. - /// True if definition exists. - public bool Contains(string jobDefName) - { - lock (_syncObject) - { - return _definitions.ContainsKey(jobDefName); - } - } - - /// - /// Clears all ScheduledJobDefinition items from the repository. - /// - public void Clear() - { - lock (_syncObject) - { - _definitions.Clear(); - } - } - - #endregion - } - - #endregion - - #region Exceptions - - /// - /// Exception thrown for errors in Scheduled Jobs. - /// - public class ScheduledJobException : SystemException - { - /// - /// Creates a new instance of ScheduledJobException class. - /// - public ScheduledJobException() - : base - ( - StringUtil.Format(ScheduledJobErrorStrings.GeneralWTSError) - ) - { - } - - /// - /// Creates a new instance of ScheduledJobException class. - /// - /// - /// The error message that explains the reason for the exception. - /// - public ScheduledJobException(string message) - : base(message) - { - } - - /// - /// Creates a new instance of ScheduledJobException class. - /// - /// - /// The error message that explains the reason for the exception. - /// - /// - /// The exception that is the cause of the current exception. - /// - public ScheduledJobException(string message, Exception innerException) - : base(message, innerException) - { - } - - /// - /// Fully qualified error id for exception. - /// - internal string FQEID - { - get { return _fqeid; } - - set { _fqeid = value ?? string.Empty; } - } - - private string _fqeid = string.Empty; - } - - #endregion - - #region Utilities - - /// - /// Simple string formatting helper. - /// - internal class StringUtil - { - internal static string Format(string formatSpec, object o) - { - return string.Format(System.Threading.Thread.CurrentThread.CurrentCulture, formatSpec, o); - } - - internal static string Format(string formatSpec, params object[] o) - { - return string.Format(System.Threading.Thread.CurrentThread.CurrentCulture, formatSpec, o); - } - } - - #endregion - - #region ScheduledJobInvocationInfo Class - - /// - /// This class defines the JobInvocationInfo class for PowerShell jobs - /// for job scheduling. The following parameters are supported: - /// - /// "ScriptBlock" -> ScriptBlock - /// "FilePath" -> String - /// "InitializationScript" -> ScriptBlock - /// "ArgumentList" -> object[] - /// "RunAs32" -> Boolean - /// "Authentication" -> AuthenticationMechanism. - /// - [Serializable] - public sealed class ScheduledJobInvocationInfo : JobInvocationInfo - { - #region Constructors - - /// - /// Constructor. - /// - /// JobDefinition. - /// Dictionary of parameters. - public ScheduledJobInvocationInfo(JobDefinition definition, Dictionary parameters) - : base(definition, parameters) - { - if (definition == null) - { - throw new PSArgumentNullException("definition"); - } - - Name = definition.Name; - } - - #endregion - - #region Public Strings - - /// - /// ScriptBlock parameter. - /// - public const string ScriptBlockParameter = "ScriptBlock"; - - /// - /// FilePath parameter. - /// - public const string FilePathParameter = "FilePath"; - - /// - /// RunAs32 parameter. - /// - public const string RunAs32Parameter = "RunAs32"; - - /// - /// Authentication parameter. - /// - public const string AuthenticationParameter = "Authentication"; - - /// - /// InitializationScript parameter. - /// - public const string InitializationScriptParameter = "InitializationScript"; - - /// - /// ArgumentList parameter. - /// - public const string ArgumentListParameter = "ArgumentList"; - - #endregion - - #region ISerializable Implementation - - /// - /// Serialization constructor. - /// - /// SerializationInfo. - /// StreamingContext. - internal ScheduledJobInvocationInfo( - SerializationInfo info, - StreamingContext context) - { - if (info == null) - { - throw new PSArgumentNullException("info"); - } - - DeserializeInvocationInfo(info); - } - - /// - /// Serialization implementation. - /// - /// SerializationInfo. - /// StreamingContext. - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - if (info == null) - { - throw new PSArgumentNullException("info"); - } - - SerializeInvocationInfo(info); - } - - #endregion - - #region Private Methods - - private void SerializeInvocationInfo(SerializationInfo info) - { - info.AddValue("InvocationInfo_Command", this.Command); - info.AddValue("InvocationInfo_Name", this.Name); - info.AddValue("InvocationInfo_AdapterType", this.Definition.JobSourceAdapterType); - info.AddValue("InvocationInfo_ModuleName", this.Definition.ModuleName); - info.AddValue("InvocationInfo_AdapterTypeName", this.Definition.JobSourceAdapterTypeName); - - // Get the job parameters. - Dictionary parameters = new Dictionary(); - foreach (var commandParam in this.Parameters[0]) - { - if (!parameters.ContainsKey(commandParam.Name)) - { - parameters.Add(commandParam.Name, commandParam.Value); - } - } - - // - // Serialize only parameters that scheduled job knows about. - // - - // ScriptBlock - if (parameters.ContainsKey(ScriptBlockParameter)) - { - ScriptBlock scriptBlock = (ScriptBlock)parameters[ScriptBlockParameter]; - info.AddValue("InvocationParam_ScriptBlock", scriptBlock.ToString()); - } - else - { - info.AddValue("InvocationParam_ScriptBlock", null); - } - - // FilePath - if (parameters.ContainsKey(FilePathParameter)) - { - string filePath = (string)parameters[FilePathParameter]; - info.AddValue("InvocationParam_FilePath", filePath); - } - else - { - info.AddValue("InvocationParam_FilePath", string.Empty); - } - - // InitializationScript - if (parameters.ContainsKey(InitializationScriptParameter)) - { - ScriptBlock scriptBlock = (ScriptBlock)parameters[InitializationScriptParameter]; - info.AddValue("InvocationParam_InitScript", scriptBlock.ToString()); - } - else - { - info.AddValue("InvocationParam_InitScript", string.Empty); - } - - // RunAs32 - if (parameters.ContainsKey(RunAs32Parameter)) - { - bool runAs32 = (bool)parameters[RunAs32Parameter]; - info.AddValue("InvocationParam_RunAs32", runAs32); - } - else - { - info.AddValue("InvocationParam_RunAs32", false); - } - - // Authentication - if (parameters.ContainsKey(AuthenticationParameter)) - { - AuthenticationMechanism authentication = (AuthenticationMechanism)parameters[AuthenticationParameter]; - info.AddValue("InvocationParam_Authentication", authentication); - } - else - { - info.AddValue("InvocationParam_Authentication", AuthenticationMechanism.Default); - } - - // ArgumentList - if (parameters.ContainsKey(ArgumentListParameter)) - { - object[] argList = (object[])parameters[ArgumentListParameter]; - info.AddValue("InvocationParam_ArgList", argList); - } - else - { - info.AddValue("InvocationParam_ArgList", null); - } - } - - private void DeserializeInvocationInfo(SerializationInfo info) - { - string command = info.GetString("InvocationInfo_Command"); - string name = info.GetString("InvocationInfo_Name"); - string moduleName = info.GetString("InvocationInfo_ModuleName"); - string adapterTypeName = info.GetString("InvocationInfo_AdapterTypeName"); - - // - // Parameters - Dictionary parameters = new Dictionary(); - - // ScriptBlock - string script = info.GetString("InvocationParam_ScriptBlock"); - if (script != null) - { - parameters.Add(ScriptBlockParameter, ScriptBlock.Create(script)); - } - - // FilePath - string filePath = info.GetString("InvocationParam_FilePath"); - if (!string.IsNullOrEmpty(filePath)) - { - parameters.Add(FilePathParameter, filePath); - } - - // InitializationScript - script = info.GetString("InvocationParam_InitScript"); - if (!string.IsNullOrEmpty(script)) - { - parameters.Add(InitializationScriptParameter, ScriptBlock.Create(script)); - } - - // RunAs32 - bool runAs32 = info.GetBoolean("InvocationParam_RunAs32"); - parameters.Add(RunAs32Parameter, runAs32); - - // Authentication - AuthenticationMechanism authentication = (AuthenticationMechanism)info.GetValue("InvocationParam_Authentication", - typeof(AuthenticationMechanism)); - parameters.Add(AuthenticationParameter, authentication); - - // ArgumentList - object[] argList = (object[])info.GetValue("InvocationParam_ArgList", typeof(object[])); - if (argList != null) - { - parameters.Add(ArgumentListParameter, argList); - } - - JobDefinition jobDefinition = new JobDefinition(null, command, name); - jobDefinition.ModuleName = moduleName; - jobDefinition.JobSourceAdapterTypeName = adapterTypeName; - - // Convert to JobInvocationParameter collection - CommandParameterCollection paramCollection = new CommandParameterCollection(); - foreach (KeyValuePair param in parameters) - { - CommandParameter paramItem = new CommandParameter(param.Key, param.Value); - paramCollection.Add(paramItem); - } - - this.Definition = jobDefinition; - this.Name = name; - this.Command = command; - this.Parameters.Add(paramCollection); - } - - #endregion - } - - #endregion -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobOptions.cs b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobOptions.cs deleted file mode 100644 index 8f171cd02ba..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobOptions.cs +++ /dev/null @@ -1,405 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Management.Automation; -using System.Runtime.Serialization; -using System.Security.Permissions; -using System.Text; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This class contains Windows Task Scheduler options. - /// - [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 - - /// - /// Start task if on batteries. - /// - public bool StartIfOnBatteries - { - get { return _startIfOnBatteries; } - - set { _startIfOnBatteries = value; } - } - - /// - /// Stop task if computer is going on batteries. - /// - public bool StopIfGoingOnBatteries - { - get { return _stopIfGoingOnBatteries; } - - set { _stopIfGoingOnBatteries = value; } - } - - /// - /// Wake computer to run task. - /// - public bool WakeToRun - { - get { return _wakeToRun; } - - set { _wakeToRun = value; } - } - - /// - /// Start task only if computer is not idle. - /// - public bool StartIfNotIdle - { - get { return _startIfNotIdle; } - - set { _startIfNotIdle = value; } - } - - /// - /// Stop task if computer is no longer idle. - /// - public bool StopIfGoingOffIdle - { - get { return _stopIfGoingOffIdle; } - - set { _stopIfGoingOffIdle = value; } - } - /// - /// Restart task on idle resuming. - /// - public bool RestartOnIdleResume - { - get { return _restartOnIdleResume; } - - set { _restartOnIdleResume = value; } - } - - /// - /// How long computer must be idle before task starts. - /// - public TimeSpan IdleDuration - { - get { return _idleDuration; } - - set { _idleDuration = value; } - } - - /// - /// How long task manager will wait for required idle duration. - /// - public TimeSpan IdleTimeout - { - get { return _idleTimeout; } - - set { _idleTimeout = value; } - } - - /// - /// When true task is not shown in Task Scheduler UI. - /// - public bool ShowInTaskScheduler - { - get { return _showInTaskScheduler; } - - set { _showInTaskScheduler = value; } - } - - /// - /// Run task with elevated privileges. - /// - public bool RunElevated - { - get { return _runElevated; } - - set { _runElevated = value; } - } - - /// - /// Run task even if network is not available. - /// - public bool RunWithoutNetwork - { - get { return _runWithoutNetwork; } - - set { _runWithoutNetwork = value; } - } - - /// - /// Do not allow a task to be started on demand. - /// - public bool DoNotAllowDemandStart - { - get { return _donotAllowDemandStart; } - - set { _donotAllowDemandStart = value; } - } - - /// - /// Multiple task instance policy. - /// - public TaskMultipleInstancePolicy MultipleInstancePolicy - { - get { return _multipleInstancePolicy; } - - set { _multipleInstancePolicy = value; } - } - - /// - /// ScheduledJobDefinition object associated with this options object. - /// - public ScheduledJobDefinition JobDefinition - { - get { return _jobDefAssociation; } - - internal set { _jobDefAssociation = value; } - } - - #endregion - - #region Constructors - - /// - /// Default constructor. - /// - 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; - } - - /// - /// Constructor. - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - 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; - } - - /// - /// Copy Constructor. - /// - /// Copy from. - 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 - - /// - /// Serialization constructor. - /// - /// SerializationInfo. - /// StreamingContext. - 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; - } - - /// - /// GetObjectData for ISerializable implementation. - /// - /// SerializationInfo. - /// StreamingContext. - 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 - - /// - /// Update the associated ScheduledJobDefinition object with the - /// current properties of this object. - /// - public void UpdateJobDefinition() - { - if (_jobDefAssociation == null) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.NoAssociatedJobDefinitionForOption); - - throw new RuntimeException(msg); - } - - _jobDefAssociation.UpdateOptions(this, true); - } - - #endregion - } - - #region Public Enums - - /// - /// Enumerates Task Scheduler options for multiple instance polices of - /// scheduled tasks (jobs). - /// - public enum TaskMultipleInstancePolicy - { - /// - /// None. - /// - None = 0, - /// - /// Ignore a new instance of the task (job) - /// - IgnoreNew = 1, - /// - /// Allow parallel running of a task (job) - /// - Parallel = 2, - /// - /// Queue up multiple instances of a task (job) - /// - Queue = 3, - /// - /// Stop currently running task (job) and start a new one. - /// - StopExisting = 4 - } - - #endregion -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobSourceAdapter.cs b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobSourceAdapter.cs deleted file mode 100644 index 53434c729e7..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobSourceAdapter.cs +++ /dev/null @@ -1,1088 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Management.Automation; -using System.Management.Automation.Runspaces; -using System.Runtime.Serialization; -using System.Text; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This class provides functionality for retrieving scheduled job run results - /// from the scheduled job store. An instance of this object will be registered - /// with the PowerShell JobManager so that GetJobs commands will retrieve schedule - /// job runs from the file based scheduled job store. This allows scheduled job - /// runs to be managed from PowerShell in the same way workflow jobs are managed. - /// - public sealed class ScheduledJobSourceAdapter : JobSourceAdapter - { - #region Private Members - - private static FileSystemWatcher StoreWatcher; - private static object SyncObject = new object(); - private static ScheduledJobRepository JobRepository = new ScheduledJobRepository(); - internal const string AdapterTypeName = "PSScheduledJob"; - - #endregion - - #region Public Strings - - /// - /// BeforeFilter. - /// - public const string BeforeFilter = "Before"; - - /// - /// AfterFilter. - /// - public const string AfterFilter = "After"; - - /// - /// NewestFilter. - /// - public const string NewestFilter = "Newest"; - - #endregion - - #region Constructor - - /// - /// Constructor. - /// - public ScheduledJobSourceAdapter() - { - Name = AdapterTypeName; - } - - #endregion - - #region JobSourceAdapter Implementation - - /// - /// Create a new Job2 results instance. - /// - /// Job specification. - /// Job2. - public override Job2 NewJob(JobInvocationInfo specification) - { - if (specification == null) - { - throw new PSArgumentNullException("specification"); - } - - ScheduledJobDefinition scheduledJobDef = new ScheduledJobDefinition( - specification, null, null, null); - - return new ScheduledJob( - specification.Command, - specification.Name, - scheduledJobDef); - } - - /// - /// Creates a new Job2 object based on a definition name - /// that can be run manually. If the path parameter is - /// null then a default location will be used to find the - /// job definition by name. - /// - /// ScheduledJob definition name. - /// ScheduledJob definition file path. - /// Job2 object. - public override Job2 NewJob(string definitionName, string definitionPath) - { - if (string.IsNullOrEmpty(definitionName)) - { - throw new PSArgumentException("definitionName"); - } - - Job2 rtnJob = null; - try - { - ScheduledJobDefinition scheduledJobDef = - ScheduledJobDefinition.LoadFromStore(definitionName, definitionPath); - - rtnJob = new ScheduledJob( - scheduledJobDef.Command, - scheduledJobDef.Name, - scheduledJobDef); - } - catch (FileNotFoundException) - { - // Return null if no job definition exists. - } - - return rtnJob; - } - - /// - /// Get the list of jobs that are currently available in this - /// store. - /// - /// Collection of job objects. - public override IList GetJobs() - { - RefreshRepository(); - - List rtnJobs = new List(); - foreach (var job in JobRepository.Jobs) - { - rtnJobs.Add(job); - } - - return rtnJobs; - } - - /// - /// Get list of jobs that matches the specified names. - /// - /// names to match, can support - /// wildcard if the store supports - /// - /// Collection of jobs that match the specified - /// criteria. - public override IList GetJobsByName(string name, bool recurse) - { - if (string.IsNullOrEmpty(name)) - { - throw new PSArgumentException("name"); - } - - RefreshRepository(); - - WildcardPattern namePattern = new WildcardPattern(name, WildcardOptions.IgnoreCase); - List rtnJobs = new List(); - foreach (var job in JobRepository.Jobs) - { - if (namePattern.IsMatch(job.Name)) - { - rtnJobs.Add(job); - } - } - - return rtnJobs; - } - - /// - /// Get list of jobs that run the specified command. - /// - /// Command to match. - /// - /// Collection of jobs that match the specified - /// criteria. - public override IList GetJobsByCommand(string command, bool recurse) - { - if (string.IsNullOrEmpty(command)) - { - throw new PSArgumentException("command"); - } - - RefreshRepository(); - - WildcardPattern commandPattern = new WildcardPattern(command, WildcardOptions.IgnoreCase); - List rtnJobs = new List(); - foreach (var job in JobRepository.Jobs) - { - if (commandPattern.IsMatch(job.Command)) - { - rtnJobs.Add(job); - } - } - - return rtnJobs; - } - - /// - /// Get job that has the specified id. - /// - /// Guid to match. - /// - /// Job with the specified guid. - public override Job2 GetJobByInstanceId(Guid instanceId, bool recurse) - { - RefreshRepository(); - - foreach (var job in JobRepository.Jobs) - { - if (Guid.Equals(job.InstanceId, instanceId)) - { - return job; - } - } - - return null; - } - - /// - /// Get job that has specific session id. - /// - /// Id to match. - /// - /// Job with the specified id. - public override Job2 GetJobBySessionId(int id, bool recurse) - { - RefreshRepository(); - - foreach (var job in JobRepository.Jobs) - { - if (id == job.Id) - { - return job; - } - } - - return null; - } - - /// - /// Get list of jobs that are in the specified state. - /// - /// State to match. - /// - /// Collection of jobs with the specified - /// state. - public override IList GetJobsByState(JobState state, bool recurse) - { - RefreshRepository(); - - List rtnJobs = new List(); - foreach (var job in JobRepository.Jobs) - { - if (state == job.JobStateInfo.State) - { - rtnJobs.Add(job); - } - } - - return rtnJobs; - } - - /// - /// Get list of jobs based on the adapter specific - /// filter parameters. - /// - /// dictionary containing name value - /// pairs for adapter specific filters - /// - /// Collection of jobs that match the - /// specified criteria. - public override IList GetJobsByFilter(Dictionary filter, bool recurse) - { - if (filter == null) - { - throw new PSArgumentNullException("filter"); - } - - List rtnJobs = new List(); - foreach (var filterItem in filter) - { - switch (filterItem.Key) - { - case BeforeFilter: - GetJobsBefore((DateTime)filterItem.Value, ref rtnJobs); - break; - - case AfterFilter: - GetJobsAfter((DateTime)filterItem.Value, ref rtnJobs); - break; - - case NewestFilter: - GetNewestJobs((int)filterItem.Value, ref rtnJobs); - break; - } - } - - return rtnJobs; - } - - /// - /// Remove a job from the store. - /// - /// Job object to remove. - public override void RemoveJob(Job2 job) - { - if (job == null) - { - throw new PSArgumentNullException("job"); - } - - RefreshRepository(); - - try - { - JobRepository.Remove(job); - ScheduledJobStore.RemoveJobRun( - job.Name, - job.PSBeginTime ?? DateTime.MinValue); - } - catch (DirectoryNotFoundException) - { - } - catch (FileNotFoundException) - { - } - } - - /// - /// Saves job to scheduled job run store. - /// - /// ScheduledJob. - public override void PersistJob(Job2 job) - { - if (job == null) - { - throw new PSArgumentNullException("job"); - } - - SaveJobToStore(job as ScheduledJob); - } - - #endregion - - #region Save Job - - /// - /// Serializes a ScheduledJob and saves it to store. - /// - /// ScheduledJob. - internal static void SaveJobToStore(ScheduledJob job) - { - string outputPath = job.Definition.OutputPath; - if (string.IsNullOrEmpty(outputPath)) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.CantSaveJobNoFilePathSpecified, - job.Name); - throw new ScheduledJobException(msg); - } - - FileStream fsStatus = null; - FileStream fsResults = null; - try - { - // Check the job store results and if maximum number of results exist - // remove the oldest results folder to make room for these new results. - CheckJobStoreResults(outputPath, job.Definition.ExecutionHistoryLength); - - fsStatus = ScheduledJobStore.CreateFileForJobRunItem( - outputPath, - job.PSBeginTime ?? DateTime.MinValue, - ScheduledJobStore.JobRunItem.Status); - - // Save status only in status file stream. - SaveStatusToFile(job, fsStatus); - - fsResults = ScheduledJobStore.CreateFileForJobRunItem( - outputPath, - job.PSBeginTime ?? DateTime.MinValue, - ScheduledJobStore.JobRunItem.Results); - - // Save entire job in results file stream. - SaveResultsToFile(job, fsResults); - } - finally - { - if (fsStatus != null) - { - fsStatus.Close(); - } - - if (fsResults != null) - { - fsResults.Close(); - } - } - } - - /// - /// Writes the job status information to the provided - /// file stream. - /// - /// ScheduledJob job to save. - /// FileStream. - private static void SaveStatusToFile(ScheduledJob job, FileStream fs) - { - StatusInfo statusInfo = new StatusInfo( - job.InstanceId, - job.Name, - job.Location, - job.Command, - job.StatusMessage, - job.JobStateInfo.State, - job.HasMoreData, - job.PSBeginTime, - job.PSEndTime, - job.Definition); - - XmlObjectSerializer serializer = new System.Runtime.Serialization.NetDataContractSerializer(); - serializer.WriteObject(fs, statusInfo); - fs.Flush(); - } - - /// - /// Writes the job (which implements ISerializable) to the provided - /// file stream. - /// - /// ScheduledJob job to save. - /// FileStream. - private static void SaveResultsToFile(ScheduledJob job, FileStream fs) - { - XmlObjectSerializer serializer = new System.Runtime.Serialization.NetDataContractSerializer(); - serializer.WriteObject(fs, job); - fs.Flush(); - } - - /// - /// Check the job store results and if maximum number of results exist - /// remove the oldest results folder to make room for these new results. - /// - /// Output path. - /// Maximum size of stored job results. - private static void CheckJobStoreResults(string outputPath, int executionHistoryLength) - { - // Get current results for this job definition. - Collection jobRuns = ScheduledJobStore.GetJobRunsForDefinitionPath(outputPath); - if (jobRuns.Count <= executionHistoryLength) - { - // There is room for another job run in the store. - return; - } - - // Remove the oldest job run from the store. - DateTime jobRunToRemove = DateTime.MaxValue; - foreach (DateTime jobRun in jobRuns) - { - jobRunToRemove = (jobRun < jobRunToRemove) ? jobRun : jobRunToRemove; - } - - try - { - ScheduledJobStore.RemoveJobRunFromOutputPath(outputPath, jobRunToRemove); - } - catch (UnauthorizedAccessException) - { } - } - - #endregion - - #region Retrieve Job - - /// - /// Finds and load the Job associated with this ScheduledJobDefinition object - /// having the job run date time provided. - /// - /// DateTime of job run to load. - /// ScheduledJobDefinition name. - /// Job2 job loaded from store. - internal static Job2 LoadJobFromStore(string definitionName, DateTime jobRun) - { - FileStream fsResults = null; - Exception ex = null; - bool corruptedFile = false; - Job2 job = null; - - try - { - // Results - fsResults = ScheduledJobStore.GetFileForJobRunItem( - definitionName, - jobRun, - ScheduledJobStore.JobRunItem.Results, - FileMode.Open, - FileAccess.Read, - FileShare.Read); - - job = LoadResultsFromFile(fsResults); - } - catch (ArgumentException e) - { - ex = e; - } - catch (DirectoryNotFoundException e) - { - ex = e; - } - catch (FileNotFoundException e) - { - ex = e; - corruptedFile = true; - } - catch (UnauthorizedAccessException e) - { - ex = e; - } - catch (IOException e) - { - ex = e; - } - catch (System.Runtime.Serialization.SerializationException) - { - corruptedFile = true; - } - catch (System.Runtime.Serialization.InvalidDataContractException) - { - corruptedFile = true; - } - catch (System.Xml.XmlException) - { - corruptedFile = true; - } - catch (System.TypeInitializationException) - { - corruptedFile = true; - } - finally - { - if (fsResults != null) - { - fsResults.Close(); - } - } - - if (corruptedFile) - { - // Remove the corrupted job results file. - ScheduledJobStore.RemoveJobRun(definitionName, jobRun); - } - - if (ex != null) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.CantLoadJobRunFromStore, definitionName, jobRun); - throw new ScheduledJobException(msg, ex); - } - - return job; - } - - /// - /// Loads the Job2 object from provided files stream. - /// - /// FileStream from which to read job object. - /// Created Job2 from file stream. - private static Job2 LoadResultsFromFile(FileStream fs) - { - XmlObjectSerializer serializer = new System.Runtime.Serialization.NetDataContractSerializer(); - return (Job2)serializer.ReadObject(fs); - } - - #endregion - - #region Static Methods - - /// - /// Adds a Job2 object to the repository. - /// - /// Job2. - internal static void AddToRepository(Job2 job) - { - if (job == null) - { - throw new PSArgumentNullException("job"); - } - - JobRepository.AddOrReplace(job); - } - - /// - /// Clears all items in the repository. - /// - internal static void ClearRepository() - { - JobRepository.Clear(); - } - - /// - /// Clears all items for given job definition name in the - /// repository. - /// - /// Scheduled job definition name. - internal static void ClearRepositoryForDefinition(string definitionName) - { - if (string.IsNullOrEmpty(definitionName)) - { - throw new PSArgumentException("definitionName"); - } - - // This returns a new list object of repository jobs. - List jobList = JobRepository.Jobs; - foreach (var job in jobList) - { - if (string.Compare(definitionName, job.Name, - StringComparison.OrdinalIgnoreCase) == 0) - { - JobRepository.Remove(job); - } - } - } - - #endregion - - #region Private Methods - - private void RefreshRepository() - { - ScheduledJobStore.CreateDirectoryIfNotExists(); - CreateFileSystemWatcher(); - - IEnumerable jobDefinitions = ScheduledJobStore.GetJobDefinitions(); - foreach (string definitionName in jobDefinitions) - { - // Create Job2 objects for each job run in store. - Collection jobRuns = GetJobRuns(definitionName); - if (jobRuns == null) - { - continue; - } - - ScheduledJobDefinition definition = null; - foreach (DateTime jobRun in jobRuns) - { - if (jobRun > JobRepository.GetLatestJobRun(definitionName)) - { - Job2 job; - try - { - if (definition == null) - { - definition = ScheduledJobDefinition.LoadFromStore(definitionName, null); - } - - job = LoadJobFromStore(definition.Name, jobRun); - } - catch (ScheduledJobException) - { - continue; - } - catch (DirectoryNotFoundException) - { - continue; - } - catch (FileNotFoundException) - { - continue; - } - catch (UnauthorizedAccessException) - { - continue; - } - catch (IOException) - { - continue; - } - - JobRepository.AddOrReplace(job); - JobRepository.SetLatestJobRun(definitionName, jobRun); - } - } - } - } - - private void CreateFileSystemWatcher() - { - // Lazily create the static file system watcher - // on first use. - if (StoreWatcher == null) - { - lock (SyncObject) - { - if (StoreWatcher == null) - { - StoreWatcher = new FileSystemWatcher(ScheduledJobStore.GetJobDefinitionLocation()); - StoreWatcher.IncludeSubdirectories = true; - StoreWatcher.NotifyFilter = NotifyFilters.LastWrite; - StoreWatcher.Filter = "Results.xml"; - StoreWatcher.EnableRaisingEvents = true; - StoreWatcher.Changed += (object sender, FileSystemEventArgs e) => - { - UpdateRepositoryObjects(e); - }; - } - } - } - } - - private static void UpdateRepositoryObjects(FileSystemEventArgs e) - { - // Extract job run information from change file path. - string updateDefinitionName; - DateTime updateJobRun; - if (!GetJobRunInfo(e.Name, out updateDefinitionName, out updateJobRun)) - { - System.Diagnostics.Debug.Assert(false, "All job run updates should have valid directory names."); - return; - } - - // Find corresponding job in repository. - ScheduledJob updateJob = JobRepository.GetJob(updateDefinitionName, updateJobRun); - if (updateJob == null) - { - return; - } - - // Load updated job information from store. - Job2 job = null; - try - { - job = LoadJobFromStore(updateDefinitionName, updateJobRun); - } - catch (ScheduledJobException) - { } - catch (DirectoryNotFoundException) - { } - catch (FileNotFoundException) - { } - catch (UnauthorizedAccessException) - { } - catch (IOException) - { } - - // Update job in repository based on new job store data. - if (job != null) - { - updateJob.Update(job as ScheduledJob); - } - } - - /// - /// Parses job definition name and job run DateTime from provided path string. - /// Example: - /// path = "ScheduledJob1\\Output\\20111219-200921-369\\Results.xml" - /// 'ScheduledJob1' is the definition name. - /// '20111219-200921-369' is the jobRun DateTime. - /// - /// - /// - /// - /// - private static bool GetJobRunInfo( - string path, - out string definitionName, - out DateTime jobRunReturn) - { - // Parse definition name from path. - string[] pathItems = path.Split(System.IO.Path.DirectorySeparatorChar); - if (pathItems.Length == 4) - { - definitionName = pathItems[0]; - return ScheduledJobStore.ConvertJobRunNameToDateTime(pathItems[2], out jobRunReturn); - } - - definitionName = null; - jobRunReturn = DateTime.MinValue; - return false; - } - - internal static Collection GetJobRuns(string definitionName) - { - Collection jobRuns = null; - try - { - jobRuns = ScheduledJobStore.GetJobRunsForDefinition(definitionName); - } - catch (DirectoryNotFoundException) - { } - catch (FileNotFoundException) - { } - catch (UnauthorizedAccessException) - { } - catch (IOException) - { } - - return jobRuns; - } - - private void GetJobsBefore( - DateTime dateTime, - ref List jobList) - { - foreach (var job in JobRepository.Jobs) - { - if (job.PSEndTime < dateTime && - !jobList.Contains(job)) - { - jobList.Add(job); - } - } - } - - private void GetJobsAfter( - DateTime dateTime, - ref List jobList) - { - foreach (var job in JobRepository.Jobs) - { - if (job.PSEndTime > dateTime && - !jobList.Contains(job)) - { - jobList.Add(job); - } - } - } - - private void GetNewestJobs( - int maxNumber, - ref List jobList) - { - List allJobs = JobRepository.Jobs; - - // Sort descending. - allJobs.Sort((firstJob, secondJob) => - { - if (firstJob.PSEndTime > secondJob.PSEndTime) - { - return -1; - } - else if (firstJob.PSEndTime < secondJob.PSEndTime) - { - return 1; - } - else - { - return 0; - } - }); - - int count = 0; - foreach (var job in allJobs) - { - if (++count > maxNumber) - { - break; - } - - if (!jobList.Contains(job)) - { - jobList.Add(job); - } - } - } - - #endregion - - #region Private Repository Class - - /// - /// Collection of Job2 objects. - /// - internal class ScheduledJobRepository - { - #region Private Members - - private object _syncObject = new object(); - private Dictionary _jobs = new Dictionary(); - private Dictionary _latestJobRuns = new Dictionary(); - - #endregion - - #region Public Properties - - /// - /// Returns all job objects in the repository as a List. - /// - public List Jobs - { - get - { - lock (_syncObject) - { - return new List(_jobs.Values); - } - } - } - - /// - /// Returns count of jobs in repository. - /// - public int Count - { - get - { - lock (_syncObject) - { - return _jobs.Count; - } - } - } - - #endregion - - #region Public Methods - - /// - /// Add Job2 to repository. - /// - /// Job2 to add. - public void Add(Job2 job) - { - if (job == null) - { - throw new PSArgumentNullException("job"); - } - - lock (_syncObject) - { - if (_jobs.ContainsKey(job.InstanceId)) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.ScheduledJobAlreadyExistsInLocal, job.Name, job.InstanceId); - throw new ScheduledJobException(msg); - } - - _jobs.Add(job.InstanceId, job); - } - } - - /// - /// Add or replace passed in Job2 object to repository. - /// - /// Job2 to add. - public void AddOrReplace(Job2 job) - { - if (job == null) - { - throw new PSArgumentNullException("job"); - } - - lock (_syncObject) - { - if (_jobs.ContainsKey(job.InstanceId)) - { - _jobs.Remove(job.InstanceId); - } - - _jobs.Add(job.InstanceId, job); - } - } - - /// - /// Remove Job2 from repository. - /// - /// - public void Remove(Job2 job) - { - if (job == null) - { - throw new PSArgumentNullException("job"); - } - - lock (_syncObject) - { - if (_jobs.ContainsKey(job.InstanceId) == false) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.ScheduledJobNotInRepository, job.Name); - throw new ScheduledJobException(msg); - } - - _jobs.Remove(job.InstanceId); - } - } - - /// - /// Clears all Job2 items from the repository. - /// - public void Clear() - { - lock (_syncObject) - { - _jobs.Clear(); - } - } - - /// - /// Gets the latest job run Date/Time for the given definition name. - /// - /// ScheduledJobDefinition name. - /// Job Run DateTime. - public DateTime GetLatestJobRun(string definitionName) - { - if (string.IsNullOrEmpty(definitionName)) - { - throw new PSArgumentException("definitionName"); - } - - lock (_syncObject) - { - if (_latestJobRuns.ContainsKey(definitionName)) - { - return _latestJobRuns[definitionName]; - } - else - { - DateTime startJobRun = DateTime.MinValue; - _latestJobRuns.Add(definitionName, startJobRun); - return startJobRun; - } - } - } - - /// - /// Sets the latest job run Date/Time for the given definition name. - /// - /// - /// - public void SetLatestJobRun(string definitionName, DateTime jobRun) - { - if (string.IsNullOrEmpty(definitionName)) - { - throw new PSArgumentException("definitionName"); - } - - lock (_syncObject) - { - if (_latestJobRuns.ContainsKey(definitionName)) - { - _latestJobRuns.Remove(definitionName); - _latestJobRuns.Add(definitionName, jobRun); - } - else - { - _latestJobRuns.Add(definitionName, jobRun); - } - } - } - - /// - /// Search repository for specific job run. - /// - /// Definition name. - /// Job run DateTime. - /// Scheduled job if found. - public ScheduledJob GetJob(string definitionName, DateTime jobRun) - { - lock (_syncObject) - { - foreach (ScheduledJob job in _jobs.Values) - { - if (job.PSBeginTime == null) - { - continue; - } - - DateTime PSBeginTime = job.PSBeginTime ?? DateTime.MinValue; - if (definitionName.Equals(job.Definition.Name, StringComparison.OrdinalIgnoreCase) && - jobRun.Year == PSBeginTime.Year && - jobRun.Month == PSBeginTime.Month && - jobRun.Day == PSBeginTime.Day && - jobRun.Hour == PSBeginTime.Hour && - jobRun.Minute == PSBeginTime.Minute && - jobRun.Second == PSBeginTime.Second && - jobRun.Millisecond == PSBeginTime.Millisecond) - { - return job; - } - } - } - - return null; - } - - #endregion - } - - #endregion - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobStore.cs b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobStore.cs deleted file mode 100644 index e6bcd1c3b8d..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobStore.cs +++ /dev/null @@ -1,676 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; -using System.IO; -using System.Management.Automation; -using System.Security.AccessControl; -using System.Security.Principal; -using System.Text; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This class encapsulates the work of determining the file location where - /// a job definition will be stored and retrieved and where job runs will - /// be stored and retrieved. 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 - /// ... - /// - 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 - - /// - /// Returns FileStream object for existing scheduled job definition. - /// Definition file is looked for in the default user local appdata path. - /// - /// Scheduled job definition name. - /// File mode. - /// File access. - /// File share. - /// FileStream object. - 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); - } - - /// - /// Returns FileStream object for existing scheduled job definition. - /// Definition file is looked for in the path provided. - /// - /// Scheduled job definition name. - /// Scheduled job definition file path. - /// File mode. - /// File share. - /// File share. - /// - 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.Create(CultureInfo.InvariantCulture, $@"{definitionPath}\{definitionName}\{DefinitionFileName}.xml"); - return File.Open(filePathName, fileMode, fileAccess, fileShare); - } - - /// - /// Checks the provided path against the default path of scheduled jobs - /// for the current user. - /// - /// Path for scheduled job definitions. - /// True if paths are equal. - public static bool IsDefaultUserPath(string definitionPath) - { - return definitionPath.Equals(GetJobDefinitionLocation(), StringComparison.OrdinalIgnoreCase); - } - - /// - /// Returns a FileStream object for a new scheduled job definition name. - /// - /// Scheduled job definition name. - /// FileStream object. - public static FileStream CreateFileForJobDefinition( - string definitionName) - { - if (string.IsNullOrEmpty(definitionName)) - { - throw new PSArgumentException("definitionName"); - } - - string filePathName = CreateFilePathName(definitionName, DefinitionFileName); - return File.Create(filePathName); - } - - /// - /// Returns an IEnumerable object of scheduled job definition names in - /// the job store. - /// - /// IEnumerable of job definition names. - public static IEnumerable GetJobDefinitions() - { - // Directory names are identical to the corresponding scheduled job definition names. - string directoryPath = GetDirectoryPath(); - IEnumerable definitions = Directory.EnumerateDirectories(directoryPath); - return (definitions != null) ? definitions : new Collection() as IEnumerable; - } - - /// - /// Returns a FileStream object for an existing scheduled job definition - /// run. - /// - /// Scheduled job definition name. - /// DateTime of job run start time. - /// Job run item. - /// File access. - /// File mode. - /// File share. - /// FileStream object. - 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); - } - - /// - /// Returns a FileStream object for a new scheduled job definition run. - /// - /// Scheduled job definition path. - /// DateTime of job run start time. - /// Job run item. - /// FileStream object. - 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); - } - - /// - /// Returns a collection of DateTime objects which specify job run directories - /// that are currently in the store. - /// - /// Scheduled job definition name. - /// Collection of DateTime objects. - public static Collection GetJobRunsForDefinition( - string definitionName) - { - if (string.IsNullOrEmpty(definitionName)) - { - throw new PSArgumentException("definitionName"); - } - - string definitionOutputPath = GetJobRunOutputDirectory(definitionName); - - return GetJobRunsForDefinitionPath(definitionOutputPath); - } - - /// - /// Returns a collection of DateTime objects which specify job run directories - /// that are currently in the store. - /// - /// Scheduled job definition job run Output path. - /// Collection of DateTime objects. - public static Collection GetJobRunsForDefinitionPath( - string definitionOutputPath) - { - if (string.IsNullOrEmpty(definitionOutputPath)) - { - throw new PSArgumentException("definitionOutputPath"); - } - - Collection jobRunInfos = new Collection(); - IEnumerable 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; - } - - /// - /// Remove the job definition and all job runs from job store. - /// - /// Scheduled Job Definition name. - 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); - } - - /// - /// Renames the directory containing the old job definition name - /// to the new name provided. - /// - /// Existing job definition directory. - /// Renamed job definition directory. - 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); - } - - /// - /// Remove a single job definition job run from the job store. - /// - /// Scheduled Job Definition name. - /// DateTime of job run. - 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); - } - - /// - /// Remove a single job definition job run from the job store. - /// - /// Scheduled Job Definition Output path. - /// DateTime of job run. - 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); - } - - /// - /// Remove all job runs for this job definition. - /// - /// Scheduled Job Definition name. - public static void RemoveAllJobRuns( - string definitionName) - { - if (string.IsNullOrEmpty(definitionName)) - { - throw new PSArgumentException("definitionName"); - } - - Collection jobRuns = GetJobRunsForDefinition(definitionName); - foreach (DateTime jobRun in jobRuns) - { - string jobRunPath = GetRunDirectory(definitionName, jobRun); - Directory.Delete(jobRunPath, true); - } - } - - /// - /// Set read access on provided definition file for specified user. - /// - /// Definition name. - /// Account user name. - 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); - } - - /// - /// Set write access on Output directory for provided definition for - /// specified user. - /// - /// Definition name. - /// Account user name. - public static void SetWriteAccessOnJobRunOutput( - string definitionName, - string user) - { - string outputDirectoryPath = GetJobRunOutputDirectory(definitionName); - AddFullAccessToDirectory(user, outputDirectoryPath); - } - - /// - /// Returns the directory path for job run output for the specified - /// scheduled job definition. - /// - /// Definition name. - /// Directory Path. - public static string GetJobRunOutputDirectory( - string definitionName) - { - if (string.IsNullOrEmpty(definitionName)) - { - throw new PSArgumentException("definitionName"); - } - - return Path.Combine(GetJobDefinitionPath(definitionName), JobRunOutput); - } - - /// - /// Gets the directory path for a Scheduled Job Definition. - /// - /// Directory Path. - public static string GetJobDefinitionLocation() - { -#if UNIX - return Path.Combine(Platform.SelectProductNameForDirectory(Platform.XDG_Type.CACHE), "ScheduledJobs")); -#else - return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), ScheduledJobsPath); -#endif - } - - public static void CreateDirectoryIfNotExists() - { - GetDirectoryPath(); - } - - #endregion - - #region Private Methods - - /// - /// Gets the directory path for Scheduled Jobs. Will create the directory if - /// it does not exist. - /// - /// Directory Path. - private static string GetDirectoryPath() - { - string pathName; -#if UNIX - pathName = Path.Combine(Platform.SelectProductNameForDirectory(Platform.XDG_Type.CACHE), "ScheduledJobs")); -#else - pathName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), ScheduledJobsPath); -#endif - if (!Directory.Exists(pathName)) - { - Directory.CreateDirectory(pathName); - } - - return pathName; - } - - /// - /// 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\ - /// - /// Definition name. - /// File name. - /// File path/name. - 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.Create(CultureInfo.InstalledUICulture, $@"{filePath}\{fileName}.xml"); - } - - /// - /// Returns a file path/name for an existing Scheduled job definition directory. - /// - /// Definition name. - /// File name. - /// File path/name. - private static string GetFilePathName(string definitionName, string fileName) - { - string filePath = GetJobDefinitionPath(definitionName); - return string.Create(CultureInfo.InvariantCulture, $@"{filePath}\{fileName}.xml"); - } - - /// - /// Gets the directory path for a Scheduled Job Definition. - /// - /// Scheduled job definition name. - /// Directory Path. - private static string GetJobDefinitionPath(string definitionName) - { -#if UNIX - return Path.Combine(Platform.SelectProductNameForDirectory(Platform.XDG_Type.CACHE), "ScheduledJobs", definitionName); -#else - return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), - ScheduledJobsPath, - definitionName); -#endif - } - - /// - /// Returns a directory path for an existing ScheduledJob run result directory. - /// - /// Definition name. - /// File name. - /// Directory Path. - private static string GetRunDirectory( - string definitionName, - DateTime runStart) - { - string directoryPath = GetJobRunOutputDirectory(definitionName); - return string.Create(CultureInfo.InvariantCulture, $@"{directoryPath}\{ConvertDateTimeToJobRunName(runStart)}"); - } - - /// - /// Returns a directory path for an existing ScheduledJob run based on - /// provided definition Output directory path. - /// - /// Output directory path. - /// File name. - /// Directory Path. - private static string GetRunDirectoryFromPath( - string definitionOutputPath, - DateTime runStart) - { - return string.Create(CultureInfo.InvariantCulture, $@"{definitionOutputPath}\{ConvertDateTimeToJobRunName(runStart)}"); - } - - /// - /// Returns a file path/name for a run result file. Will create the - /// job run directory if it does not exist. - /// - /// Definition name. - /// Result type. - /// Run date. - /// File path/name. - private static string GetRunFilePathName( - string definitionName, - JobRunItem runItem, - DateTime runStart) - { - string directoryPath = GetJobRunOutputDirectory(definitionName); - string jobRunPath = string.Create(CultureInfo.InvariantCulture, $@"{directoryPath}\{ConvertDateTimeToJobRunName(runStart)}"); - - return string.Create(CultureInfo.InvariantCulture, $@"{jobRunPath}\{runItem}.xml"); - } - - /// - /// 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. - /// - /// Definition job run output path. - /// Result type. - /// Run date. - /// - private static string GetRunFilePathNameFromPath( - string outputPath, - JobRunItem runItem, - DateTime runStart) - { - string jobRunPath = string.Create(CultureInfo.InvariantCulture, $@"{outputPath}\{ConvertDateTimeToJobRunName(runStart)}"); - - if (!Directory.Exists(jobRunPath)) - { - // Create directory for this job run date. - Directory.CreateDirectory(jobRunPath); - } - - return string.Create(CultureInfo.InvariantCulture, $@"{jobRunPath}\{runItem}.xml"); - } - - 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); - } - - /// - /// Converts a jobRun name string to an equivalent DateTime. - /// - /// - /// - /// - 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 - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobTrigger.cs b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobTrigger.cs deleted file mode 100644 index 0f40ded9f95..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobTrigger.cs +++ /dev/null @@ -1,887 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; -using System.Management.Automation; -using System.Runtime.Serialization; -using System.Security.Permissions; -using System.Text; -using System.Threading; - -using Microsoft.Management.Infrastructure; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This class contains parameters used to define how/when a PowerShell job is - /// run via the Windows Task Scheduler (WTS). - /// - public sealed class ScheduledJobTrigger : ISerializable - { - #region Private Members - - private DateTime? _time; - private List _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 - - /// - /// Trigger time. - /// - public DateTime? At - { - get { return _time; } - - set { _time = value; } - } - - /// - /// Trigger days of week. - /// - public List DaysOfWeek - { - get { return _daysOfWeek; } - - set { _daysOfWeek = value; } - } - - /// - /// Trigger days or weeks interval. - /// - public Int32 Interval - { - get { return _interval; } - - set { _interval = value; } - } - - /// - /// Trigger frequency. - /// - public TriggerFrequency Frequency - { - get { return _frequency; } - - set { _frequency = value; } - } - - /// - /// Trigger random delay. - /// - public TimeSpan RandomDelay - { - get { return _randomDelay; } - - set { _randomDelay = value; } - } - - /// - /// Trigger Once frequency repetition interval. - /// - 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; - } - } - - /// - /// Trigger Once frequency repetition duration. - /// - 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; - } - } - - /// - /// Trigger user name. - /// - public string User - { - get { return _user; } - - set { _user = value; } - } - - /// - /// Returns the trigger local Id. - /// - public Int32 Id - { - get { return _id; } - - internal set { _id = value; } - } - - /// - /// Defines enabled state of trigger. - /// - public bool Enabled - { - get { return _enabled; } - - set { _enabled = value; } - } - - /// - /// ScheduledJobDefinition object this trigger is associated with. - /// - public ScheduledJobDefinition JobDefinition - { - get { return _jobDefAssociation; } - - internal set { _jobDefAssociation = value; } - } - - #endregion - - #region Constructors - - /// - /// Default constructor. - /// - public ScheduledJobTrigger() - { } - - /// - /// Constructor. - /// - /// Enabled. - /// Trigger frequency. - /// Trigger time. - /// Weekly days of week. - /// Daily or Weekly interval. - /// Random delay. - /// Repetition interval. - /// Repetition duration. - /// Logon user. - /// Trigger id. - private ScheduledJobTrigger( - bool enabled, - TriggerFrequency frequency, - DateTime? time, - List 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; - } - - /// - /// Copy constructor. - /// - /// ScheduledJobTrigger. - 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; - } - - /// - /// Serialization constructor. - /// - /// SerializationInfo. - /// StreamingContext. - 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)info.GetValue("DaysOfWeek_Value", typeof(List)); - _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 - - /// - /// GetObjectData for ISerializable implementation. - /// - /// - /// - 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 - - /// - /// Creates a one time ScheduledJobTrigger object. - /// - /// DateTime when trigger activates. - /// Random delay. - /// Repetition interval. - /// Repetition duration. - /// Trigger Id. - /// Trigger enabled state. - /// ScheduledJobTrigger. - 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); - } - - /// - /// Creates a daily ScheduledJobTrigger object. - /// - /// Time of day when trigger activates. - /// Days interval for trigger activation. - /// Random delay. - /// Trigger Id. - /// Trigger enabled state. - /// ScheduledJobTrigger. - 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); - } - - /// - /// Creates a weekly ScheduledJobTrigger object. - /// - /// Time of day when trigger activates. - /// Weeks interval for trigger activation. - /// Days of the week for trigger activation. - /// Random delay. - /// Trigger Id. - /// Trigger enabled state. - /// ScheduledJobTrigger. - public static ScheduledJobTrigger CreateWeeklyTrigger( - DateTime time, - Int32 interval, - IEnumerable daysOfWeek, - TimeSpan delay, - Int32 id, - bool enabled) - { - List lDaysOfWeek = (daysOfWeek != null) ? new List(daysOfWeek) : null; - - return new ScheduledJobTrigger( - enabled, - TriggerFrequency.Weekly, - time, - lDaysOfWeek, - interval, - delay, - null, - null, - null, - id); - } - - /// - /// Creates a trigger that activates after user log on. - /// - /// Name of user. - /// Random delay. - /// Trigger Id. - /// Trigger enabled state. - /// ScheduledJobTrigger. - 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); - } - - /// - /// Creates a trigger that activates after OS boot. - /// - /// Random delay. - /// Trigger Id. - /// Trigger enabled state. - /// ScheduledJobTrigger. - public static ScheduledJobTrigger CreateAtStartupTrigger( - TimeSpan delay, - Int32 id, - bool enabled) - { - return new ScheduledJobTrigger( - enabled, - TriggerFrequency.AtStartup, - null, - null, - 1, - delay, - null, - null, - null, - id); - } - - /// - /// Compares provided user name to All Users string ("*"). - /// - /// Logon user name. - /// Boolean, true if All Users. - internal static bool IsAllUsers(string userName) - { - return (string.Compare(userName, ScheduledJobTrigger.AllUsers, - StringComparison.OrdinalIgnoreCase) == 0); - } - - /// - /// Returns the All Users string. - /// - internal static string AllUsers - { - get { return _allUsers; } - } - - #endregion - - #region Public Methods - - /// - /// Update the associated ScheduledJobDefinition object with the - /// current properties of this object. - /// - 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 - - /// - /// Specifies trigger types in terms of the frequency that - /// the trigger is activated. - /// - public enum TriggerFrequency - { - /// - /// None. - /// - None = 0, - /// - /// Trigger activates once at a specified time. - /// - Once = 1, - /// - /// Trigger activates daily. - /// - Daily = 2, - /// - /// Trigger activates on a weekly basis and multiple days - /// during the week. - /// - Weekly = 3, - /// - /// Trigger activates at user logon to the operating system. - /// - AtLogon = 4, - /// - /// Trigger activates after machine boot up. - /// - AtStartup = 5 - } - - #endregion - - #region JobTriggerToCimInstanceConverter - /// - /// Class providing implementation of PowerShell conversions for types in Microsoft.Management.Infrastructure namespace. - /// - public sealed class JobTriggerToCimInstanceConverter : PSTypeConverter - { - private static readonly string CIM_TRIGGER_NAMESPACE = @"Root\Microsoft\Windows\TaskScheduler"; - - /// - /// Determines if the converter can convert the parameter to the parameter. - /// - /// The value to convert from. - /// The type to convert to. - /// True if the converter can convert the parameter to the parameter, otherwise false. - public override bool CanConvertFrom(object sourceValue, Type destinationType) - { - ArgumentNullException.ThrowIfNull(destinationType); - - return (sourceValue is ScheduledJobTrigger) && (destinationType.Equals(typeof(CimInstance))); - } - - /// - /// Converts the parameter to the parameter using formatProvider and ignoreCase. - /// - /// The value to convert from. - /// The type to convert to. - /// The format provider to use like in IFormattable's ToString. - /// True if case should be ignored. - /// The parameter converted to the parameter using formatProvider and ignoreCase. - /// If no conversion was possible. - public override object ConvertFrom(object sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase) - { - ArgumentNullException.ThrowIfNull(destinationType); - - ArgumentNullException.ThrowIfNull(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); - } - } - } - - /// - /// Returns true if the converter can convert the parameter to the parameter. - /// - /// The value to convert from. - /// The type to convert to. - /// True if the converter can convert the parameter to the parameter, otherwise false. - public override bool CanConvertTo(object sourceValue, Type destinationType) - { - return false; - } - - /// - /// Converts the parameter to the parameter using formatProvider and ignoreCase. - /// - /// The value to convert from. - /// The type to convert to. - /// The format provider to use like in IFormattable's ToString. - /// True if case should be ignored. - /// SourceValue converted to the parameter using formatProvider and ignoreCase. - /// If no conversion was possible. - 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 -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobWTS.cs b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobWTS.cs deleted file mode 100644 index b8714816a71..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobWTS.cs +++ /dev/null @@ -1,982 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Globalization; -using System.Management.Automation; -using System.Runtime.InteropServices; -using System.Security.AccessControl; -using System.Text; - -using TaskScheduler; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// Managed code class to provide Windows Task Scheduler functionality for - /// scheduled jobs. - /// - 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 - - /// - /// Retrieves job triggers from WTS with provided task Id. - /// - /// Task Id. - /// Task not found. - /// ScheduledJobTriggers. - public Collection GetJobTriggers( - string taskId) - { - if (string.IsNullOrEmpty(taskId)) - { - throw new PSArgumentException("taskId"); - } - - ITaskDefinition iTaskDefinition = FindTask(taskId); - - Collection jobTriggers = new Collection(); - 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; - } - - /// - /// Retrieves options for the provided task Id. - /// - /// Task Id. - /// Task not found. - /// ScheduledJobOptions. - public ScheduledJobOptions GetJobOptions( - string taskId) - { - if (string.IsNullOrEmpty(taskId)) - { - throw new PSArgumentException("taskId"); - } - - ITaskDefinition iTaskDefinition = FindTask(taskId); - - return CreateJobOptions(iTaskDefinition); - } - - /// - /// Returns a boolean indicating whether the job/task is enabled - /// in the Task Scheduler. - /// - /// - /// - public bool GetTaskEnabled( - string taskId) - { - if (string.IsNullOrEmpty(taskId)) - { - throw new PSArgumentException("taskId"); - } - - ITaskDefinition iTaskDefinition = FindTask(taskId); - - return iTaskDefinition.Settings.Enabled; - } - - /// - /// Creates a new task in WTS with information from ScheduledJobDefinition. - /// - /// ScheduledJobDefinition. - 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); - } - } - - /// - /// 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. - /// - /// ScheduledJobDefinition. - /// Force running instances to stop and remove task. - public void RemoveTask( - ScheduledJobDefinition definition, - bool force = false) - { - if (definition == null) - { - throw new PSArgumentNullException("definition"); - } - - RemoveTaskByName(definition.Name, force, false); - } - - /// - /// Removes a Task Scheduler task from the PowerShell/ScheduledJobs folder - /// based on a task name. - /// - /// Task Scheduler task name. - /// Force running instances to stop and remove task. - /// First check for existence of task. - 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); - } - - /// - /// Starts task running from Task Scheduler. - /// - /// ScheduledJobDefinition. - /// - /// - public void RunTask( - ScheduledJobDefinition definition) - { - // Get registered task. - IRegisteredTask iRegisteredTask = _iRootFolder.GetTask(definition.Name); - - // Run task. - iRegisteredTask.Run(null); - } - - /// - /// Updates an existing task in WTS with information from - /// ScheduledJobDefinition. - /// - /// ScheduledJobDefinition. - 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 - - /// - /// Creates a new WTS trigger based on the provided ScheduledJobTrigger object - /// and adds it to the provided ITaskDefinition object. - /// - /// ITaskDefinition. - /// ScheduledJobTrigger. - 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; - } - } - - /// - /// Creates a ScheduledJobTrigger object based on a provided WTS ITrigger. - /// - /// ITrigger. - /// ScheduledJobTrigger. - 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; - } - - /// - /// Gets and returns the unsecured password for the provided - /// PSCredential object. - /// - /// PSCredential. - /// Unsecured password string. - 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 - - /// - /// Gets the Task Scheduler root folder for Scheduled Jobs or - /// creates it if it does not exist. - /// - /// Scheduled Jobs root folder. - 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; - } - - /// - /// Finds a task with the provided Task Id and returns it as - /// a ITaskDefinition object. - /// - /// Task Id. - /// ITaskDefinition. - 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; - } - - /// - /// 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. - /// - /// Formatted time string. - /// TimeSpan. - 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); - } - - /// - /// Creates WTS formatted time string based on TimeSpan parameter. - /// - /// TimeSpan. - /// WTS time string. - 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); - } - - /// - /// Converts DateTime to string for WTS. - /// - /// DateTime. - /// DateTime string. - internal static string ConvertDateTimeToString(DateTime? dt) - { - if (dt == null) - { - return string.Empty; - } - else - { - return dt.Value.ToString("s", CultureInfo.InvariantCulture); - } - } - - /// - /// Returns a bitmask representing days of week as - /// required by Windows Task Scheduler API. - /// - /// Array of DayOfWeek. - /// WTS days of week mask. - internal static short ConvertDaysOfWeekToMask(IEnumerable 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; - } - - /// - /// Converts WTS days of week mask to an array of DayOfWeek type. - /// - /// WTS days of week mask. - /// Days of week as List. - private List ConvertMaskToDaysOfWeekArray(short mask) - { - List daysOfWeek = new List(); - - 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 - - /// - /// Dispose. - /// - 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 - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/AddJobTrigger.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/AddJobTrigger.cs deleted file mode 100644 index 2936fcf78c6..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/AddJobTrigger.cs +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Management.Automation; -using System.Management.Automation.Host; -using System.Management.Automation.Internal; -using System.Threading; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This cmdlet adds ScheduledJobTriggers to ScheduledJobDefinition objects. - /// - [Cmdlet(VerbsCommon.Add, "JobTrigger", DefaultParameterSetName = AddJobTriggerCommand.JobDefinitionParameterSet, - HelpUri = "https://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"; - - /// - /// ScheduledJobTrigger. - /// - [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; - - /// - /// ScheduledJobDefinition Id. - /// - [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; - - /// - /// ScheduledJobDefinition Name. - /// - [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; - - /// - /// ScheduledJobDefinition. - /// - [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 - - /// - /// Process input. - /// - 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 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 - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobDefinition.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobDefinition.cs deleted file mode 100644 index d76b1829d42..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobDefinition.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Management.Automation; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This cmdlet disables the specified ScheduledJobDefinition. - /// - [Cmdlet(VerbsLifecycle.Disable, "ScheduledJob", SupportsShouldProcess = true, DefaultParameterSetName = DisableScheduledJobDefinitionBase.DefinitionParameterSet, - HelpUri = "https://go.microsoft.com/fwlink/?LinkID=223927")] - [OutputType(typeof(ScheduledJobDefinition))] - public sealed class DisableScheduledJobCommand : DisableScheduledJobDefinitionBase - { - #region Properties - - /// - /// Returns true if scheduled job definition should be enabled, - /// false otherwise. - /// - protected override bool Enabled - { - get { return false; } - } - - #endregion - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobDefinitionBase.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobDefinitionBase.cs deleted file mode 100644 index d06020ed3d6..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobDefinitionBase.cs +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Management.Automation; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// Base class for the DisableScheduledJobCommand, EnableScheduledJobCommand cmdlets. - /// - public abstract class DisableScheduledJobDefinitionBase : ScheduleJobCmdletBase - { - #region Parameters - - /// - /// DefinitionIdParameterSet. - /// - protected const string DefinitionIdParameterSet = "DefinitionId"; - - /// - /// DefinitionNameParameterSet. - /// - protected const string DefinitionNameParameterSet = "DefinitionName"; - - /// - /// DefinitionParameterSet. - /// - protected const string DefinitionParameterSet = "Definition"; - - /// - /// ScheduledJobDefinition. - /// - [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true, - ParameterSetName = DisableScheduledJobDefinitionBase.DefinitionParameterSet)] - [ValidateNotNull] - public ScheduledJobDefinition InputObject - { - get { return _definition; } - - set { _definition = value; } - } - - private ScheduledJobDefinition _definition; - - /// - /// ScheduledJobDefinition Id. - /// - [Parameter(Position = 0, Mandatory = true, - ParameterSetName = DisableScheduledJobDefinitionBase.DefinitionIdParameterSet)] - public Int32 Id - { - get { return _definitionId; } - - set { _definitionId = value; } - } - - private Int32 _definitionId; - - /// - /// ScheduledJobDefinition Name. - /// - [Parameter(Position = 0, Mandatory = true, - ParameterSetName = DisableScheduledJobDefinitionBase.DefinitionNameParameterSet)] - [ValidateNotNullOrEmpty] - public string Name - { - get { return _definitionName; } - - set { _definitionName = value; } - } - - private string _definitionName; - - /// - /// Pass through ScheduledJobDefinition object. - /// - [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 - - /// - /// Process input. - /// - 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 - - /// - /// Returns true if scheduled job definition should be enabled, - /// false otherwise. - /// - protected abstract bool Enabled - { - get; - } - - #endregion - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobTrigger.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobTrigger.cs deleted file mode 100644 index 02e37c0acfb..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobTrigger.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Management.Automation; -using System.Management.Automation.Host; -using System.Management.Automation.Internal; -using System.Threading; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This cmdlet enables triggers on a ScheduledJobDefinition object. - /// - [Cmdlet(VerbsLifecycle.Disable, "JobTrigger", SupportsShouldProcess = true, DefaultParameterSetName = DisableJobTriggerCommand.EnabledParameterSet, - HelpUri = "https://go.microsoft.com/fwlink/?LinkID=223918")] - public sealed class DisableJobTriggerCommand : EnableDisableScheduledJobCmdletBase - { - #region Enabled Implementation - - /// - /// Property to determine if trigger should be enabled or disabled. - /// - internal override bool Enabled - { - get { return false; } - } - - #endregion - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/EnableDisableCmdletBase.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/EnableDisableCmdletBase.cs deleted file mode 100644 index c00626e6d64..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/EnableDisableCmdletBase.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Management.Automation; -using System.Management.Automation.Host; -using System.Management.Automation.Internal; -using System.Threading; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// Base class for DisableJobTrigger, EnableJobTrigger cmdlets. - /// - public abstract class EnableDisableScheduledJobCmdletBase : ScheduleJobCmdletBase - { - #region Parameters - - /// - /// JobDefinition parameter set. - /// - protected const string EnabledParameterSet = "JobEnabled"; - - /// - /// ScheduledJobTrigger objects to set properties on. - /// - [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; } - } - - /// - /// Pass through for scheduledjobtrigger object. - /// - [Parameter(ParameterSetName = EnableDisableScheduledJobCmdletBase.EnabledParameterSet)] - public SwitchParameter PassThru - { - get { return _passThru; } - - set { _passThru = value; } - } - - private SwitchParameter _passThru; - - private ScheduledJobTrigger[] _triggers; - - #endregion - - #region Cmdlet Overrides - - /// - /// Process input. - /// - 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 - - /// - /// Property to determine if trigger should be enabled or disabled. - /// - internal abstract bool Enabled - { - get; - } - - #endregion - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/EnableJobDefinition.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/EnableJobDefinition.cs deleted file mode 100644 index 6f236ea57af..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/EnableJobDefinition.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Management.Automation; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This cmdlet enables the specified ScheduledJobDefinition. - /// - [Cmdlet(VerbsLifecycle.Enable, "ScheduledJob", SupportsShouldProcess = true, DefaultParameterSetName = DisableScheduledJobDefinitionBase.DefinitionParameterSet, - HelpUri = "https://go.microsoft.com/fwlink/?LinkID=223926")] - [OutputType(typeof(ScheduledJobDefinition))] - public sealed class EnableScheduledJobCommand : DisableScheduledJobDefinitionBase - { - #region Properties - - /// - /// Returns true if scheduled job definition should be enabled, - /// false otherwise. - /// - protected override bool Enabled - { - get { return true; } - } - - #endregion - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/EnableJobTrigger.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/EnableJobTrigger.cs deleted file mode 100644 index 955dde31dfe..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/EnableJobTrigger.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Management.Automation; -using System.Management.Automation.Host; -using System.Management.Automation.Internal; -using System.Threading; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This cmdlet disables triggers on a ScheduledJobDefinition object. - /// - [Cmdlet(VerbsLifecycle.Enable, "JobTrigger", SupportsShouldProcess = true, DefaultParameterSetName = EnableJobTriggerCommand.EnabledParameterSet, - HelpUri = "https://go.microsoft.com/fwlink/?LinkID=223917")] - public sealed class EnableJobTriggerCommand : EnableDisableScheduledJobCmdletBase - { - #region Enabled Implementation - - /// - /// Property to determine if trigger should be enabled or disabled. - /// - internal override bool Enabled - { - get { return true; } - } - - #endregion - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/GetJobDefinition.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/GetJobDefinition.cs deleted file mode 100644 index 772027f4fa5..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/GetJobDefinition.cs +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Management.Automation; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This cmdlet gets scheduled job definition objects from the local repository. - /// - [Cmdlet(VerbsCommon.Get, "ScheduledJob", DefaultParameterSetName = GetScheduledJobCommand.DefinitionIdParameterSet, - HelpUri = "https://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"; - - /// - /// ScheduledJobDefinition Id. - /// - [Parameter(Position = 0, - ParameterSetName = GetScheduledJobCommand.DefinitionIdParameterSet)] - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - public Int32[] Id - { - get { return _definitionIds; } - - set { _definitionIds = value; } - } - - private Int32[] _definitionIds; - - /// - /// ScheduledJobDefinition Name. - /// - [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 - - /// - /// Process input. - /// - 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 - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/GetJobTrigger.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/GetJobTrigger.cs deleted file mode 100644 index 0218395f3a1..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/GetJobTrigger.cs +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Management.Automation; -using System.Management.Automation.Host; -using System.Management.Automation.Internal; -using System.Threading; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This cmdlet gets ScheduledJobTriggers for the specified ScheduledJobDefinition object. - /// - [Cmdlet(VerbsCommon.Get, "JobTrigger", DefaultParameterSetName = GetJobTriggerCommand.JobDefinitionParameterSet, - HelpUri = "https://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"; - - /// - /// Trigger number to get. - /// - [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; - - /// - /// ScheduledJobDefinition. - /// - [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true, - ParameterSetName = GetJobTriggerCommand.JobDefinitionParameterSet)] - [ValidateNotNull] - public ScheduledJobDefinition InputObject - { - get { return _definition; } - - set { _definition = value; } - } - - private ScheduledJobDefinition _definition; - - /// - /// ScheduledJobDefinition Id. - /// - [Parameter(Position = 0, Mandatory = true, - ParameterSetName = GetJobTriggerCommand.JobDefinitionIdParameterSet)] - public Int32 Id - { - get { return _definitionId; } - - set { _definitionId = value; } - } - - private Int32 _definitionId; - - /// - /// ScheduledJobDefinition Name. - /// - [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 - - /// - /// Process input. - /// - 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 notFoundIds; - List 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 - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/GetScheduledJobOption.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/GetScheduledJobOption.cs deleted file mode 100644 index 4de3131b223..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/GetScheduledJobOption.cs +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Management.Automation; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This cmdlet gets scheduled job option object from a provided ScheduledJobDefinition object. - /// - [Cmdlet(VerbsCommon.Get, "ScheduledJobOption", DefaultParameterSetName = GetScheduledJobOptionCommand.JobDefinitionParameterSet, - HelpUri = "https://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"; - - /// - /// ScheduledJobDefinition Id. - /// - [Parameter(Position = 0, Mandatory = true, - ParameterSetName = GetScheduledJobOptionCommand.JobDefinitionIdParameterSet)] - public Int32 Id - { - get { return _id; } - - set { _id = value; } - } - - private Int32 _id; - - /// - /// ScheduledJobDefinition Name. - /// - [Parameter(Position = 0, Mandatory = true, ValueFromPipelineByPropertyName = true, - ParameterSetName = GetScheduledJobOptionCommand.JobDefinitionNameParameterSet)] - [ValidateNotNullOrEmpty] - public string Name - { - get { return _name; } - - set { _name = value; } - } - - private string _name; - - /// - /// ScheduledJobDefinition. - /// - [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 - - /// - /// Process input. - /// - 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 - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/NewJobTrigger.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/NewJobTrigger.cs deleted file mode 100644 index 99ce575bec3..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/NewJobTrigger.cs +++ /dev/null @@ -1,360 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Management.Automation; -using System.Management.Automation.Host; -using System.Management.Automation.Internal; -using System.Threading; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This cmdlet creates a new scheduled job trigger based on the provided - /// parameter values. - /// - [Cmdlet(VerbsCommon.New, "JobTrigger", DefaultParameterSetName = NewJobTriggerCommand.OnceParameterSet, - HelpUri = "https://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"; - - /// - /// Daily interval for trigger. - /// - [Parameter(ParameterSetName = NewJobTriggerCommand.DailyParameterSet)] - public Int32 DaysInterval - { - get { return _daysInterval; } - - set { _daysInterval = value; } - } - - private Int32 _daysInterval = 1; - - /// - /// Weekly interval for trigger. - /// - [Parameter(ParameterSetName = NewJobTriggerCommand.WeeklyParameterSet)] - public Int32 WeeksInterval - { - get { return _weeksInterval; } - - set { _weeksInterval = value; } - } - - private Int32 _weeksInterval = 1; - - /// - /// Random delay for trigger. - /// - [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; - - /// - /// Job start date/time for trigger. - /// - [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; - - /// - /// User name for AtLogon trigger. User name is used to determine which user - /// log on causes the trigger to activate. - /// - [Parameter(ParameterSetName = NewJobTriggerCommand.AtLogonParameterSet)] - [ValidateNotNullOrEmpty] - public string User - { - get { return _user; } - - set { _user = value; } - } - - private string _user; - - /// - /// Days of week for trigger applies only to the Weekly parameter set. - /// Specifies which day(s) of the week the weekly trigger is activated. - /// - [Parameter(Mandatory = true, ParameterSetName = NewJobTriggerCommand.WeeklyParameterSet)] - [ValidateNotNullOrEmpty] - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - public DayOfWeek[] DaysOfWeek - { - get { return _daysOfWeek; } - - set { _daysOfWeek = value; } - } - - private DayOfWeek[] _daysOfWeek; - - /// - /// Switch to specify an AtStartup trigger. - /// - [Parameter(Mandatory = true, Position = 0, - ParameterSetName = NewJobTriggerCommand.AtStartupParameterSet)] - public SwitchParameter AtStartup - { - get { return _atStartup; } - - set { _atStartup = value; } - } - - private SwitchParameter _atStartup; - - /// - /// Switch to specify an AtLogon trigger. - /// - [Parameter(Mandatory = true, Position = 0, - ParameterSetName = NewJobTriggerCommand.AtLogonParameterSet)] - public SwitchParameter AtLogOn - { - get { return _atLogon; } - - set { _atLogon = value; } - } - - private SwitchParameter _atLogon; - - /// - /// Switch to specify a Once (one time) trigger. - /// - [Parameter(Mandatory = true, Position = 0, - ParameterSetName = NewJobTriggerCommand.OnceParameterSet)] - public SwitchParameter Once - { - get { return _once; } - - set { _once = value; } - } - - private SwitchParameter _once; - - /// - /// Repetition interval of a one time trigger. - /// - [Parameter(ParameterSetName = NewJobTriggerCommand.OnceParameterSet)] - public TimeSpan RepetitionInterval - { - get { return _repInterval; } - - set { _repInterval = value; } - } - - private TimeSpan _repInterval; - - /// - /// Repetition duration of a one time trigger. - /// - [Parameter(ParameterSetName = NewJobTriggerCommand.OnceParameterSet)] - public TimeSpan RepetitionDuration - { - get { return _repDuration; } - - set { _repDuration = value; } - } - - private TimeSpan _repDuration; - - /// - /// Repetition interval repeats indefinitely. - /// - [Parameter(ParameterSetName = NewJobTriggerCommand.OnceParameterSet)] - public SwitchParameter RepeatIndefinitely - { - get { return _repRepeatIndefinitely; } - - set { _repRepeatIndefinitely = value; } - } - - private SwitchParameter _repRepeatIndefinitely; - - /// - /// Switch to specify a Daily trigger. - /// - [Parameter(Mandatory = true, Position = 0, - ParameterSetName = NewJobTriggerCommand.DailyParameterSet)] - public SwitchParameter Daily - { - get { return _daily; } - - set { _daily = value; } - } - - private SwitchParameter _daily; - - /// - /// Switch to specify a Weekly trigger. - /// - [Parameter(Mandatory = true, Position = 0, - ParameterSetName = NewJobTriggerCommand.WeeklyParameterSet)] - public SwitchParameter Weekly - { - get { return _weekly; } - - set { _weekly = value; } - } - - private SwitchParameter _weekly; - - #endregion - - #region Cmdlet Overrides - - /// - /// Do begin processing. - /// - protected override void BeginProcessing() - { - base.BeginProcessing(); - - // Validate parameters. - if (_daysInterval < 1) - { - throw new PSArgumentException(ScheduledJobErrorStrings.InvalidDaysIntervalParam); - } - - if (_weeksInterval < 1) - { - throw new PSArgumentException(ScheduledJobErrorStrings.InvalidWeeksIntervalParam); - } - } - - /// - /// Process input. - /// - 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(nameof(RepetitionInterval)) || MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionDuration)) || - MyInvocation.BoundParameters.ContainsKey(nameof(RepeatIndefinitely))) - { - if (MyInvocation.BoundParameters.ContainsKey(nameof(RepeatIndefinitely))) - { - if (MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionDuration))) - { - throw new PSArgumentException(ScheduledJobErrorStrings.InvalidRepeatIndefinitelyParams); - } - - if (!MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionInterval))) - { - throw new PSArgumentException(ScheduledJobErrorStrings.InvalidRepetitionRepeatParams); - } - - _repDuration = TimeSpan.MaxValue; - } - else if (!MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionInterval)) || !MyInvocation.BoundParameters.ContainsKey(nameof(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 - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/NewScheduledJobOption.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/NewScheduledJobOption.cs deleted file mode 100644 index 09eab549426..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/NewScheduledJobOption.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Management.Automation; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This cmdlet creates a new scheduled job option object based on the provided - /// parameter values. - /// - [Cmdlet(VerbsCommon.New, "ScheduledJobOption", DefaultParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet, - HelpUri = "https://go.microsoft.com/fwlink/?LinkID=223919")] - [OutputType(typeof(ScheduledJobOptions))] - public sealed class NewScheduledJobOptionCommand : ScheduledJobOptionCmdletBase - { - #region Cmdlet Overrides - - /// - /// Process input. - /// - protected override void ProcessRecord() - { - WriteObject(new ScheduledJobOptions( - StartIfOnBattery, - !ContinueIfGoingOnBattery, - WakeToRun, - !StartIfIdle, - StopIfGoingOffIdle, - RestartOnIdleResume, - IdleDuration, - IdleTimeout, - !HideInTaskScheduler, - RunElevated, - !RequireNetwork, - DoNotAllowDemandStart, - MultipleInstancePolicy)); - } - - #endregion - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/RegisterJobDefinition.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/RegisterJobDefinition.cs deleted file mode 100644 index 608f6bcfd9f..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/RegisterJobDefinition.cs +++ /dev/null @@ -1,408 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics.CodeAnalysis; -using System.Management.Automation; -using System.Management.Automation.Runspaces; - -using Microsoft.PowerShell.Commands; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This cmdlet creates a new scheduled job definition object based on the provided - /// parameter values and registers it with the Task Scheduler. - /// - [SuppressMessage("Microsoft.PowerShell", "PS1012:CallShouldProcessOnlyIfDeclaringSupport")] - [Cmdlet(VerbsLifecycle.Register, "ScheduledJob", SupportsShouldProcess = true, DefaultParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet, - HelpUri = "https://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"; - - /// - /// File path for script to be run in job. - /// - [Parameter(Position = 1, Mandatory = true, - ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)] - [Alias("Path")] - [ValidateNotNullOrEmpty] - public string FilePath - { - get { return _filePath; } - - set { _filePath = value; } - } - - private string _filePath; - - /// - /// ScriptBlock containing script to run in job. - /// - [Parameter(Position = 1, Mandatory = true, - ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)] - [ValidateNotNull] - public ScriptBlock ScriptBlock - { - get { return _scriptBlock; } - - set { _scriptBlock = value; } - } - - private ScriptBlock _scriptBlock; - - /// - /// Name of scheduled job definition. - /// - [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; - - /// - /// Triggers to define when job will run. - /// - [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; - - /// - /// Initialization script to run before the job starts. - /// - [Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)] - [Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)] - [ValidateNotNull] - public ScriptBlock InitializationScript - { - get { return _initializationScript; } - - set { _initializationScript = value; } - } - - private ScriptBlock _initializationScript; - - /// - /// Runs the job in a 32-bit PowerShell process. - /// - [Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)] - [Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)] - public SwitchParameter RunAs32 - { - get { return _runAs32; } - - set { _runAs32 = value; } - } - - private SwitchParameter _runAs32; - - /// - /// Credentials for job. - /// - [Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)] - [Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)] - [Credential] - public PSCredential Credential - { - get { return _credential; } - - set { _credential = value; } - } - - private PSCredential _credential; - - /// - /// Authentication mechanism to use for job. - /// - [Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)] - [Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)] - public AuthenticationMechanism Authentication - { - get { return _authenticationMechanism; } - - set { _authenticationMechanism = value; } - } - - private AuthenticationMechanism _authenticationMechanism; - - /// - /// Scheduling options for job. - /// - [Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)] - [Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)] - [ValidateNotNull] - public ScheduledJobOptions ScheduledJobOption - { - get { return _options; } - - set { _options = value; } - } - - private ScheduledJobOptions _options; - - /// - /// Argument list for FilePath parameter. - /// - [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; - - /// - /// Maximum number of job results allowed in job store. - /// - [Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)] - [Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)] - public int MaxResultCount - { - get { return _executionHistoryLength; } - - set { _executionHistoryLength = value; } - } - - private int _executionHistoryLength; - - /// - /// Runs scheduled job immediately after successful registration. - /// - [Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)] - [Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)] - public SwitchParameter RunNow - { - get { return _runNow; } - - set { _runNow = value; } - } - - private SwitchParameter _runNow; - - /// - /// Runs scheduled job at the repetition interval indicated by the - /// TimeSpan value for an unending duration. - /// - [Parameter(ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)] - [Parameter(ParameterSetName = RegisterScheduledJobCommand.ScriptBlockParameterSet)] - public TimeSpan RunEvery - { - get { return _runEvery; } - - set { _runEvery = value; } - } - - private TimeSpan _runEvery; - - #endregion - - #region Cmdlet Overrides - - /// - /// Process input. - /// - 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(nameof(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(nameof(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 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 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 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 CreateCommonParameters() - { - Dictionary parameterCollection = new Dictionary(); - - 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 - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/RemoveJobTrigger.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/RemoveJobTrigger.cs deleted file mode 100644 index 81cdb8ecc35..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/RemoveJobTrigger.cs +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Management.Automation; -using System.Management.Automation.Host; -using System.Management.Automation.Internal; -using System.Threading; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This cmdlet removes ScheduledJobTriggers from ScheduledJobDefinition objects. - /// - [Cmdlet(VerbsCommon.Remove, "JobTrigger", DefaultParameterSetName = RemoveJobTriggerCommand.JobDefinitionParameterSet, - HelpUri = "https://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"; - - /// - /// Trigger number to remove. - /// - [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; - - /// - /// ScheduledJobDefinition Id. - /// - [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; - - /// - /// ScheduledJobDefinition Name. - /// - [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; - - /// - /// ScheduledJobDefinition. - /// - [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 - - /// - /// Process input. - /// - 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 definitions) - { - foreach (ScheduledJobDefinition definition in definitions) - { - List notFoundIds = new List(); - 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 - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/SchedJobCmdletBase.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/SchedJobCmdletBase.cs deleted file mode 100644 index e8112877019..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/SchedJobCmdletBase.cs +++ /dev/null @@ -1,468 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Management.Automation; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// Base class for ScheduledJob cmdlets. - /// - public abstract class ScheduleJobCmdletBase : PSCmdlet - { - #region Cmdlet Strings - - /// - /// Scheduled job module name. - /// - protected const string ModuleName = "PSScheduledJob"; - - #endregion - - #region Utility Methods - - /// - /// Makes delegate callback call for each scheduledjob definition object found. - /// - /// Callback delegate for each discovered item. - internal void FindAllJobDefinitions( - Action itemFound) - { - Dictionary errors = ScheduledJobDefinition.RefreshRepositoryFromStore((definition) => - { - if (ValidateJobDefinition(definition)) - { - itemFound(definition); - } - }); - HandleAllLoadErrors(errors); - } - - /// - /// Returns a single ScheduledJobDefinition object from the local - /// scheduled job definition repository corresponding to the provided id. - /// - /// Local repository scheduled job definition id. - /// Errors/warnings are written to host. - /// ScheduledJobDefinition object. - internal ScheduledJobDefinition GetJobDefinitionById( - Int32 id, - bool writeErrorsAndWarnings = true) - { - Dictionary 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; - } - - /// - /// Returns an array of ScheduledJobDefinition objects from the local - /// scheduled job definition repository corresponding to the provided Ids. - /// - /// Local repository scheduled job definition ids. - /// Errors/warnings are written to host. - /// List of ScheduledJobDefinition objects. - internal List GetJobDefinitionsById( - Int32[] ids, - bool writeErrorsAndWarnings = true) - { - Dictionary errors = ScheduledJobDefinition.RefreshRepositoryFromStore(null); - HandleAllLoadErrors(errors); - - List definitions = new List(); - HashSet findIds = new HashSet(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; - } - - /// - /// Makes delegate callback call for each scheduledjob definition object found. - /// - /// Local repository scheduled job definition ids. - /// Callback delegate for each discovered item. - /// Errors/warnings are written to host. - internal void FindJobDefinitionsById( - Int32[] ids, - Action itemFound, - bool writeErrorsAndWarnings = true) - { - HashSet findIds = new HashSet(ids); - Dictionary 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); - } - } - } - - /// - /// Returns an array of ScheduledJobDefinition objects from the local - /// scheduled job definition repository corresponding to the given name. - /// - /// Scheduled job definition name. - /// Errors/warnings are written to host. - /// ScheduledJobDefinition object. - internal ScheduledJobDefinition GetJobDefinitionByName( - string name, - bool writeErrorsAndWarnings = true) - { - Dictionary 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; - } - - /// - /// Returns an array of ScheduledJobDefinition objects from the local - /// scheduled job definition repository corresponding to the given names. - /// - /// Scheduled job definition names. - /// Errors/warnings are written to host. - /// List of ScheduledJobDefinition objects. - internal List GetJobDefinitionsByName( - string[] names, - bool writeErrorsAndWarnings = true) - { - Dictionary errors = ScheduledJobDefinition.RefreshRepositoryFromStore(null); - - List definitions = new List(); - 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; - } - - /// - /// Makes delegate callback call for each scheduledjob definition object found. - /// - /// Scheduled job definition names. - /// Callback delegate for each discovered item. - /// Errors/warnings are written to host. - internal void FindJobDefinitionsByName( - string[] names, - Action itemFound, - bool writeErrorsAndWarnings = true) - { - HashSet notFoundNames = new HashSet(names); - Dictionary patterns = new Dictionary(); - foreach (string name in names) - { - if (!patterns.ContainsKey(name)) - { - patterns.Add(name, new WildcardPattern(name, WildcardOptions.IgnoreCase)); - } - } - - Dictionary 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); - } - } - } - - /// - /// Writes a "Trigger not found" error to host. - /// - /// Trigger Id not found. - /// ScheduledJobDefinition name. - /// Error object. - 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); - } - - /// - /// Writes a "Definition not found for Id" error to host. - /// - /// Definition Id. - 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); - } - - /// - /// Writes a "Definition not found for Name" error to host. - /// - /// Definition Name. - 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); - } - - /// - /// Writes a "Load from job store" error to host. - /// - /// Scheduled job definition name. - /// Exception thrown during loading. - 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); - } - - /// - /// Creates a Once job trigger with provided repetition interval and an - /// infinite duration, and adds the trigger to the provided scheduled job - /// definition object. - /// - /// ScheduledJobDefinition. - /// Rep interval. - /// Save definition change. - 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 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); - } - } - - /// - /// 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. - /// - /// - /// - 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 - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/ScheduledJobOptionCmdletBase.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/ScheduledJobOptionCmdletBase.cs deleted file mode 100644 index cd70dc0a8f1..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/ScheduledJobOptionCmdletBase.cs +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Management.Automation; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// Base class for NewScheduledJobOption, SetScheduledJobOption cmdlets. - /// - public abstract class ScheduledJobOptionCmdletBase : ScheduleJobCmdletBase - { - #region Parameters - - /// - /// Options parameter set name. - /// - protected const string OptionsParameterSet = "Options"; - - /// - /// Scheduled job task is run with elevated privileges when this switch is selected. - /// - [Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)] - public SwitchParameter RunElevated - { - get { return _runElevated; } - - set { _runElevated = value; } - } - - private SwitchParameter _runElevated = false; - - /// - /// Scheduled job task is hidden in Windows Task Scheduler when true. - /// - [Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)] - public SwitchParameter HideInTaskScheduler - { - get { return _hideInTaskScheduler; } - - set { _hideInTaskScheduler = value; } - } - - private SwitchParameter _hideInTaskScheduler = false; - - /// - /// 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. - /// - [Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)] - public SwitchParameter RestartOnIdleResume - { - get { return _restartOnIdleResume; } - - set { _restartOnIdleResume = value; } - } - - private SwitchParameter _restartOnIdleResume = false; - - /// - /// Provides task scheduler options for multiple running instances of the job. - /// - [Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)] - public TaskMultipleInstancePolicy MultipleInstancePolicy - { - get { return _multipleInstancePolicy; } - - set { _multipleInstancePolicy = value; } - } - - private TaskMultipleInstancePolicy _multipleInstancePolicy = TaskMultipleInstancePolicy.IgnoreNew; - - /// - /// Prevents the job task from being started manually via Task Scheduler UI. - /// - [Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)] - public SwitchParameter DoNotAllowDemandStart - { - get { return _doNotAllowDemandStart; } - - set { _doNotAllowDemandStart = value; } - } - - private SwitchParameter _doNotAllowDemandStart = false; - - /// - /// Allows the job task to be run only when network connection available. - /// - [Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)] - public SwitchParameter RequireNetwork - { - get { return _requireNetwork; } - - set { _requireNetwork = value; } - } - - private SwitchParameter _requireNetwork = false; - - /// - /// Stops running job started by Task Scheduler if computer is no longer idle. - /// - [Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)] - public SwitchParameter StopIfGoingOffIdle - { - get { return _stopIfGoingOffIdle; } - - set { _stopIfGoingOffIdle = value; } - } - - private SwitchParameter _stopIfGoingOffIdle = false; - - /// - /// Will wake the computer to run the job if computer is in sleep mode when - /// trigger activates. - /// - [Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)] - public SwitchParameter WakeToRun - { - get { return _wakeToRun; } - - set { _wakeToRun = value; } - } - - private SwitchParameter _wakeToRun = false; - - /// - /// Continue running task job if computer going on battery. - /// - [Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)] - public SwitchParameter ContinueIfGoingOnBattery - { - get { return _continueIfGoingOnBattery; } - - set { _continueIfGoingOnBattery = value; } - } - - private SwitchParameter _continueIfGoingOnBattery = false; - - /// - /// Will start job task even if computer is running on battery power. - /// - [Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)] - public SwitchParameter StartIfOnBattery - { - get { return _startIfOnBattery; } - - set { _startIfOnBattery = value; } - } - - private SwitchParameter _startIfOnBattery = false; - - /// - /// 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. - /// - [Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)] - public TimeSpan IdleTimeout - { - get { return _idleTimeout; } - - set { _idleTimeout = value; } - } - - private TimeSpan _idleTimeout = new TimeSpan(1, 0, 0); - - /// - /// How long the computer needs to be idle before a triggered job task is started. - /// - [Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)] - public TimeSpan IdleDuration - { - get { return _idleDuration; } - - set { _idleDuration = value; } - } - - private TimeSpan _idleDuration = new TimeSpan(0, 10, 0); - - /// - /// Will start job task if machine is idle. - /// - [Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)] - public SwitchParameter StartIfIdle - { - get { return _startIfIdle; } - - set { _startIfIdle = value; } - } - - private SwitchParameter _startIfIdle = false; - - #endregion - - #region Cmdlet Overrides - - /// - /// Begin processing. - /// - protected override void BeginProcessing() - { - // Validate parameters. - if (MyInvocation.BoundParameters.ContainsKey(nameof(IdleTimeout)) && - _idleTimeout < TimeSpan.Zero) - { - throw new PSArgumentException(ScheduledJobErrorStrings.InvalidIdleTimeout); - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(IdleDuration)) && - _idleDuration < TimeSpan.Zero) - { - throw new PSArgumentException(ScheduledJobErrorStrings.InvalidIdleDuration); - } - } - - #endregion - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/SetJobDefinition.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/SetJobDefinition.cs deleted file mode 100644 index 0d56f5640e4..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/SetJobDefinition.cs +++ /dev/null @@ -1,552 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Management.Automation; -using System.Management.Automation.Runspaces; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This cmdlet updates a scheduled job definition object based on the provided - /// parameter values and saves changes to job store and Task Scheduler. - /// - [Cmdlet(VerbsCommon.Set, "ScheduledJob", DefaultParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet, - HelpUri = "https://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"; - - /// - /// Name of scheduled job definition. - /// - [Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)] - [Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)] - [ValidateNotNullOrEmpty] - public string Name - { - get { return _name; } - - set { _name = value; } - } - - private string _name; - - /// - /// File path for script to be run in job. - /// - [Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)] - [Alias("Path")] - [ValidateNotNullOrEmpty] - public string FilePath - { - get { return _filePath; } - - set { _filePath = value; } - } - - private string _filePath; - - /// - /// ScriptBlock containing script to run in job. - /// - [Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)] - [ValidateNotNull] - public ScriptBlock ScriptBlock - { - get { return _scriptBlock; } - - set { _scriptBlock = value; } - } - - private ScriptBlock _scriptBlock; - - /// - /// Triggers to define when job will run. - /// - [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; - - /// - /// Initialization script to run before the job starts. - /// - [Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)] - [Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)] - [ValidateNotNull] - public ScriptBlock InitializationScript - { - get { return _initializationScript; } - - set { _initializationScript = value; } - } - - private ScriptBlock _initializationScript; - - /// - /// Runs the job in a 32-bit PowerShell process. - /// - [Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)] - [Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)] - public SwitchParameter RunAs32 - { - get { return _runAs32; } - - set { _runAs32 = value; } - } - - private SwitchParameter _runAs32; - - /// - /// Credentials for job. - /// - [Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)] - [Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)] - [Credential()] - public PSCredential Credential - { - get { return _credential; } - - set { _credential = value; } - } - - private PSCredential _credential; - - /// - /// Authentication mechanism to use for job. - /// - [Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)] - [Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)] - public AuthenticationMechanism Authentication - { - get { return _authenticationMechanism; } - - set { _authenticationMechanism = value; } - } - - private AuthenticationMechanism _authenticationMechanism; - - /// - /// Scheduling options for job. - /// - [Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)] - [Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)] - [ValidateNotNull] - public ScheduledJobOptions ScheduledJobOption - { - get { return _options; } - - set { _options = value; } - } - - private ScheduledJobOptions _options; - - /// - /// Input for the job. - /// - [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; - - /// - /// ClearExecutionHistory. - /// - [Parameter(ParameterSetName = SetScheduledJobCommand.ExecutionParameterSet)] - public SwitchParameter ClearExecutionHistory - { - get { return _clearExecutionHistory; } - - set { _clearExecutionHistory = value; } - } - - private SwitchParameter _clearExecutionHistory; - - /// - /// Maximum number of job results allowed in job store. - /// - [Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)] - [Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)] - public int MaxResultCount - { - get { return _executionHistoryLength; } - - set { _executionHistoryLength = value; } - } - - private int _executionHistoryLength; - - /// - /// Pass the ScheduledJobDefinition object through to output. - /// - [Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)] - [Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)] - [Parameter(ParameterSetName = SetScheduledJobCommand.ExecutionParameterSet)] - public SwitchParameter PassThru - { - get { return _passThru; } - - set { _passThru = value; } - } - - private SwitchParameter _passThru; - - /// - /// Argument list. - /// - [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; - - /// - /// Runs scheduled job immediately after successfully setting job definition. - /// - [Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)] - [Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)] - public SwitchParameter RunNow - { - get { return _runNow; } - - set { _runNow = value; } - } - - private SwitchParameter _runNow; - - /// - /// Runs scheduled job at the repetition interval indicated by the - /// TimeSpan value for an unending duration. - /// - [Parameter(ParameterSetName = SetScheduledJobCommand.ScriptBlockParameterSet)] - [Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)] - public TimeSpan RunEvery - { - get { return _runEvery; } - - set { _runEvery = value; } - } - - private TimeSpan _runEvery; - - #endregion - - #region Cmdlet Overrides - - /// - /// Process input. - /// - 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(nameof(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(nameof(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); - } - } - - /// - /// Create new ScheduledJobInvocationInfo object with update information and - /// update the job definition object. - /// - private void UpdateJobInvocationInfo() - { - Dictionary 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); - } - - /// - /// Creates a new parameter dictionary with update parameters. - /// - /// Updated parameters. - private Dictionary UpdateParameters() - { - Debug.Assert(_definition.InvocationInfo.Parameters.Count != 0, - "ScheduledJobDefinition must always have some job invocation parameters"); - Dictionary newParameters = new Dictionary(); - foreach (CommandParameter parameter in _definition.InvocationInfo.Parameters[0]) - { - newParameters.Add(parameter.Name, parameter.Value); - } - - // RunAs32 - if (MyInvocation.BoundParameters.ContainsKey(nameof(RunAs32))) - { - if (newParameters.ContainsKey(ScheduledJobInvocationInfo.RunAs32Parameter)) - { - newParameters[ScheduledJobInvocationInfo.RunAs32Parameter] = RunAs32.ToBool(); - } - else - { - newParameters.Add(ScheduledJobInvocationInfo.RunAs32Parameter, RunAs32.ToBool()); - } - } - - // Authentication - if (MyInvocation.BoundParameters.ContainsKey(nameof(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 - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/SetJobTrigger.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/SetJobTrigger.cs deleted file mode 100644 index 4eeab7fcc72..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/SetJobTrigger.cs +++ /dev/null @@ -1,945 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Management.Automation; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This cmdlet sets properties on a trigger for a ScheduledJobDefinition. - /// - [Cmdlet(VerbsCommon.Set, "JobTrigger", DefaultParameterSetName = SetJobTriggerCommand.DefaultParameterSet, - HelpUri = "https://go.microsoft.com/fwlink/?LinkID=223916")] - [OutputType(typeof(ScheduledJobTrigger))] - public sealed class SetJobTriggerCommand : ScheduleJobCmdletBase - { - #region Parameters - - private const string DefaultParameterSet = "DefaultParams"; - - /// - /// ScheduledJobTrigger objects to set properties on. - /// - [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; - - /// - /// Daily interval for trigger. - /// - [Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)] - public Int32 DaysInterval - { - get { return _daysInterval; } - - set { _daysInterval = value; } - } - - private Int32 _daysInterval = 1; - - /// - /// Weekly interval for trigger. - /// - [Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)] - public Int32 WeeksInterval - { - get { return _weeksInterval; } - - set { _weeksInterval = value; } - } - - private Int32 _weeksInterval = 1; - - /// - /// Random delay for trigger. - /// - [Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)] - public TimeSpan RandomDelay - { - get { return _randomDelay; } - - set { _randomDelay = value; } - } - - private TimeSpan _randomDelay; - - /// - /// Job start date/time for trigger. - /// - [Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)] - public DateTime At - { - get { return _atTime; } - - set { _atTime = value; } - } - - private DateTime _atTime; - - /// - /// User name for AtLogon trigger. The AtLogon parameter set will create a trigger - /// that activates after log on for the provided user name. - /// - [Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)] - [ValidateNotNullOrEmpty] - public string User - { - get { return _user; } - - set { _user = value; } - } - - private string _user; - - /// - /// Days of week for trigger. - /// - [Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)] - [ValidateNotNullOrEmpty] - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - public DayOfWeek[] DaysOfWeek - { - get { return _daysOfWeek; } - - set { _daysOfWeek = value; } - } - - private DayOfWeek[] _daysOfWeek; - - /// - /// Switch to specify an AtStartup trigger. - /// - [Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)] - public SwitchParameter AtStartup - { - get { return _atStartup; } - - set { _atStartup = value; } - } - - private SwitchParameter _atStartup; - - /// - /// Switch to specify an AtLogon trigger. - /// - [Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)] - public SwitchParameter AtLogOn - { - get { return _atLogon; } - - set { _atLogon = value; } - } - - private SwitchParameter _atLogon; - - /// - /// Switch to specify an Once trigger. - /// - [Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)] - public SwitchParameter Once - { - get { return _once; } - - set { _once = value; } - } - - private SwitchParameter _once; - - /// - /// Repetition interval of a one time trigger. - /// - [Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)] - public TimeSpan RepetitionInterval - { - get { return _repInterval; } - - set { _repInterval = value; } - } - - private TimeSpan _repInterval; - - /// - /// Repetition duration of a one time trigger. - /// - [Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)] - public TimeSpan RepetitionDuration - { - get { return _repDuration; } - - set { _repDuration = value; } - } - - private TimeSpan _repDuration; - - /// - /// Repetition interval repeats indefinitely. - /// - [Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)] - public SwitchParameter RepeatIndefinitely - { - get { return _repRepeatIndefinitely; } - - set { _repRepeatIndefinitely = value; } - } - - private SwitchParameter _repRepeatIndefinitely; - - /// - /// Switch to specify an Daily trigger. - /// - [Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)] - public SwitchParameter Daily - { - get { return _daily; } - - set { _daily = value; } - } - - private SwitchParameter _daily; - - /// - /// Switch to specify an Weekly trigger. - /// - [Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)] - public SwitchParameter Weekly - { - get { return _weekly; } - - set { _weekly = value; } - } - - private SwitchParameter _weekly; - - /// - /// Pass through job trigger object. - /// - [Parameter(ParameterSetName = SetJobTriggerCommand.DefaultParameterSet)] - public SwitchParameter PassThru - { - get { return _passThru; } - - set { _passThru = value; } - } - - private SwitchParameter _passThru; - - #endregion - - #region Cmdlet Overrides - - /// - /// Process input. - /// - 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 switchParamList = new List(); - if (MyInvocation.BoundParameters.ContainsKey(nameof(AtStartup))) - { - switchParamList.Add(TriggerFrequency.AtStartup); - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(AtLogon))) - { - switchParamList.Add(TriggerFrequency.AtLogon); - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(Once))) - { - switchParamList.Add(TriggerFrequency.Once); - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(Daily))) - { - switchParamList.Add(TriggerFrequency.Daily); - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(Weekly))) - { - 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(nameof(DaysInterval))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidDaysInterval, ScheduledJobErrorStrings.TriggerStartUpType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(WeeksInterval))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidWeeksInterval, ScheduledJobErrorStrings.TriggerStartUpType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(At))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidAtTime, ScheduledJobErrorStrings.TriggerStartUpType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(User))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidUser, ScheduledJobErrorStrings.TriggerStartUpType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(DaysOfWeek))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidDaysOfWeek, ScheduledJobErrorStrings.TriggerStartUpType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionInterval)) || MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionDuration)) || - MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionInfiniteDuration))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidSetTriggerRepetition, ScheduledJobErrorStrings.TriggerStartUpType); - WriteValidationError(msg); - return false; - } - - return true; - } - - private bool ValidateLogonParams() - { - if (MyInvocation.BoundParameters.ContainsKey(nameof(DaysInterval))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidDaysInterval, ScheduledJobErrorStrings.TriggerLogonType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(WeeksInterval))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidWeeksInterval, ScheduledJobErrorStrings.TriggerLogonType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(At))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidAtTime, ScheduledJobErrorStrings.TriggerLogonType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(DaysOfWeek))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidDaysOfWeek, ScheduledJobErrorStrings.TriggerLogonType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionInterval)) || MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionDuration)) || - MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionInfiniteDuration))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidSetTriggerRepetition, ScheduledJobErrorStrings.TriggerLogonType); - WriteValidationError(msg); - return false; - } - - return true; - } - - private bool ValidateOnceParams(ScheduledJobTrigger trigger = null) - { - if (MyInvocation.BoundParameters.ContainsKey(nameof(DaysInterval))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidDaysInterval, ScheduledJobErrorStrings.TriggerOnceType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(WeeksInterval))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidWeeksInterval, ScheduledJobErrorStrings.TriggerOnceType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(User))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidUser, ScheduledJobErrorStrings.TriggerOnceType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(DaysOfWeek))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidDaysOfWeek, ScheduledJobErrorStrings.TriggerOnceType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionInfiniteDuration))) - { - _repDuration = TimeSpan.MaxValue; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionInterval)) || MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionDuration)) || - MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionInfiniteDuration))) - { - // 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(nameof(At))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.MissingAtTime, ScheduledJobErrorStrings.TriggerOnceType); - WriteValidationError(msg); - return false; - } - } - - return true; - } - - private bool ValidateDailyParams(ScheduledJobTrigger trigger = null) - { - if (MyInvocation.BoundParameters.ContainsKey(nameof(DaysInterval)) && - _daysInterval < 1) - { - WriteValidationError(ScheduledJobErrorStrings.InvalidDaysIntervalParam); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(WeeksInterval))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidWeeksInterval, ScheduledJobErrorStrings.TriggerDailyType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(User))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidUser, ScheduledJobErrorStrings.TriggerDailyType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(DaysOfWeek))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidDaysOfWeek, ScheduledJobErrorStrings.TriggerDailyType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionInterval)) || MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionDuration)) || - MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionInfiniteDuration))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidSetTriggerRepetition, ScheduledJobErrorStrings.TriggerDailyType); - WriteValidationError(msg); - return false; - } - - if (trigger != null) - { - if (trigger.At == null && !MyInvocation.BoundParameters.ContainsKey(nameof(At))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.MissingAtTime, ScheduledJobErrorStrings.TriggerDailyType); - WriteValidationError(msg); - return false; - } - } - - return true; - } - - private bool ValidateWeeklyParams(ScheduledJobTrigger trigger = null) - { - if (MyInvocation.BoundParameters.ContainsKey(nameof(DaysInterval))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidDaysInterval, ScheduledJobErrorStrings.TriggerWeeklyType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(WeeksInterval)) && - _weeksInterval < 1) - { - WriteValidationError(ScheduledJobErrorStrings.InvalidWeeksIntervalParam); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(User))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidUser, ScheduledJobErrorStrings.TriggerWeeklyType); - WriteValidationError(msg); - return false; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionInterval)) || MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionDuration)) || - MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionInfiniteDuration))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.InvalidSetTriggerRepetition, ScheduledJobErrorStrings.TriggerWeeklyType); - WriteValidationError(msg); - return false; - } - - if (trigger != null) - { - if (trigger.At == null && !MyInvocation.BoundParameters.ContainsKey(nameof(At))) - { - string msg = StringUtil.Format(ScheduledJobErrorStrings.MissingAtTime, ScheduledJobErrorStrings.TriggerDailyType); - WriteValidationError(msg); - return false; - } - - if ((trigger.DaysOfWeek == null || trigger.DaysOfWeek.Count == 0) && - !MyInvocation.BoundParameters.ContainsKey(nameof(DaysOfWeek))) - { - 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(nameof(RandomDelay))) - { - trigger.RandomDelay = _randomDelay; - } - } - - private void ModifyLogonTrigger(ScheduledJobTrigger trigger) - { - if (MyInvocation.BoundParameters.ContainsKey(nameof(RandomDelay))) - { - trigger.RandomDelay = _randomDelay; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(User))) - { - trigger.User = string.IsNullOrEmpty(_user) ? ScheduledJobTrigger.AllUsers : _user; - } - } - - private void ModifyOnceTrigger(ScheduledJobTrigger trigger) - { - if (MyInvocation.BoundParameters.ContainsKey(nameof(RandomDelay))) - { - trigger.RandomDelay = _randomDelay; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionInterval))) - { - trigger.RepetitionInterval = _repInterval; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionDuration))) - { - trigger.RepetitionDuration = _repDuration; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(At))) - { - trigger.At = _atTime; - } - } - - private void ModifyDailyTrigger(ScheduledJobTrigger trigger) - { - if (MyInvocation.BoundParameters.ContainsKey(nameof(RandomDelay))) - { - trigger.RandomDelay = _randomDelay; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(At))) - { - trigger.At = _atTime; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(DaysInterval))) - { - trigger.Interval = _daysInterval; - } - } - - private void ModifyWeeklyTrigger(ScheduledJobTrigger trigger) - { - if (MyInvocation.BoundParameters.ContainsKey(nameof(RandomDelay))) - { - trigger.RandomDelay = _randomDelay; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(At))) - { - trigger.At = _atTime; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(WeeksInterval))) - { - trigger.Interval = _weeksInterval; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(DaysOfWeek))) - { - trigger.DaysOfWeek = new List(_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(nameof(RandomDelay)) ? _randomDelay : randomDelay; - trigger.User = MyInvocation.BoundParameters.ContainsKey(nameof(User)) ? _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(nameof(RandomDelay)) ? _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(nameof(RandomDelay)) ? _randomDelay : randomDelay; - trigger.At = MyInvocation.BoundParameters.ContainsKey(nameof(At)) ? _atTime : atTime; - trigger.RepetitionInterval = MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionInterval)) ? _repInterval : repInterval; - trigger.RepetitionDuration = MyInvocation.BoundParameters.ContainsKey(nameof(RepetitionDuration)) ? _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(nameof(RandomDelay)) ? _randomDelay : randomDelay; - trigger.At = MyInvocation.BoundParameters.ContainsKey(nameof(At)) ? _atTime : atTime; - trigger.Interval = MyInvocation.BoundParameters.ContainsKey(nameof(DaysInterval)) ? _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 daysOfWeek = trigger.DaysOfWeek; - - trigger.ClearProperties(); - trigger.Frequency = TriggerFrequency.Weekly; - trigger.Enabled = enabled; - trigger.Id = id; - - trigger.RandomDelay = MyInvocation.BoundParameters.ContainsKey(nameof(RandomDelay)) ? _randomDelay : randomDelay; - trigger.At = MyInvocation.BoundParameters.ContainsKey(nameof(At)) ? _atTime : atTime; - trigger.Interval = MyInvocation.BoundParameters.ContainsKey(nameof(WeeksInterval)) ? _weeksInterval : interval; - trigger.DaysOfWeek = MyInvocation.BoundParameters.ContainsKey(nameof(DaysOfWeek)) ? new List(_daysOfWeek) : daysOfWeek; - } - - private void WriteValidationError(string msg) - { - Exception reason = new RuntimeException(msg); - ErrorRecord errorRecord = new ErrorRecord(reason, "SetJobTriggerParameterValidationError", ErrorCategory.InvalidArgument, null); - WriteError(errorRecord); - } - - #endregion - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/SetScheduledJobOption.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/SetScheduledJobOption.cs deleted file mode 100644 index bc1e07b1473..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/SetScheduledJobOption.cs +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Management.Automation; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This cmdlet sets the provided scheduled job options to the provided ScheduledJobOptions objects. - /// - [Cmdlet(VerbsCommon.Set, "ScheduledJobOption", DefaultParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet, - HelpUri = "https://go.microsoft.com/fwlink/?LinkID=223921")] - [OutputType(typeof(ScheduledJobOptions))] - public class SetScheduledJobOptionCommand : ScheduledJobOptionCmdletBase - { - #region Parameters - - /// - /// ScheduledJobOptions object. - /// - [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true, - ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)] - [ValidateNotNull] - public ScheduledJobOptions InputObject - { - get { return _jobOptions; } - - set { _jobOptions = value; } - } - - private ScheduledJobOptions _jobOptions; - - /// - /// Pas the ScheduledJobOptions object through to output. - /// - [Parameter(ParameterSetName = ScheduledJobOptionCmdletBase.OptionsParameterSet)] - public SwitchParameter PassThru - { - get { return _passThru; } - - set { _passThru = value; } - } - - private SwitchParameter _passThru; - - #endregion - - #region Cmdlet Overrides - - /// - /// Process input. - /// - protected override void ProcessRecord() - { - // Update ScheduledJobOptions object with current parameters. - // Update switch parameters only if they were selected. - // Also update the ScheduledJobDefinition object associated with this options object. - if (MyInvocation.BoundParameters.ContainsKey(nameof(StartIfOnBattery))) - { - _jobOptions.StartIfOnBatteries = StartIfOnBattery; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(ContinueIfGoingOnBattery))) - { - _jobOptions.StopIfGoingOnBatteries = !ContinueIfGoingOnBattery; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(WakeToRun))) - { - _jobOptions.WakeToRun = WakeToRun; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(StartIfIdle))) - { - _jobOptions.StartIfNotIdle = !StartIfIdle; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(StopIfGoingOffIdle))) - { - _jobOptions.StopIfGoingOffIdle = StopIfGoingOffIdle; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(RestartOnIdleResume))) - { - _jobOptions.RestartOnIdleResume = RestartOnIdleResume; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(HideInTaskScheduler))) - { - _jobOptions.ShowInTaskScheduler = !HideInTaskScheduler; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(RunElevated))) - { - _jobOptions.RunElevated = RunElevated; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(RequireNetwork))) - { - _jobOptions.RunWithoutNetwork = !RequireNetwork; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(DoNotAllowDemandStart))) - { - _jobOptions.DoNotAllowDemandStart = DoNotAllowDemandStart; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(IdleDuration))) - { - _jobOptions.IdleDuration = IdleDuration; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(IdleTimeout))) - { - _jobOptions.IdleTimeout = IdleTimeout; - } - - if (MyInvocation.BoundParameters.ContainsKey(nameof(MultipleInstancePolicy))) - { - _jobOptions.MultipleInstancePolicy = MultipleInstancePolicy; - } - - // Update ScheduledJobDefinition with changes. - if (_jobOptions.JobDefinition != null) - { - _jobOptions.UpdateJobDefinition(); - } - - if (_passThru) - { - WriteObject(_jobOptions); - } - } - - #endregion - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/UnregisterJobDefinition.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/UnregisterJobDefinition.cs deleted file mode 100644 index c6c3885fb90..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/UnregisterJobDefinition.cs +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Management.Automation; - -namespace Microsoft.PowerShell.ScheduledJob -{ - /// - /// This cmdlet removes the specified ScheduledJobDefinition objects from the - /// Task Scheduler, job store, and local repository. - /// - [Cmdlet(VerbsLifecycle.Unregister, "ScheduledJob", SupportsShouldProcess = true, DefaultParameterSetName = UnregisterScheduledJobCommand.DefinitionParameterSet, - HelpUri = "https://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"; - - /// - /// ScheduledJobDefinition Id. - /// - [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; - - /// - /// ScheduledJobDefinition Name. - /// - [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; - - /// - /// ScheduledJobDefinition. - /// - [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; - - /// - /// When true this will stop any running instances of this job definition before - /// removing the definition. - /// - [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 - - /// - /// Process input. - /// - protected override void ProcessRecord() - { - List definitions = null; - switch (ParameterSetName) - { - case DefinitionParameterSet: - definitions = new List(_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 ScheduledJobDefinition 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 definition 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 - } -} diff --git a/src/Microsoft.PowerShell.ScheduledJob/resources/ScheduledJobErrorStrings.resx b/src/Microsoft.PowerShell.ScheduledJob/resources/ScheduledJobErrorStrings.resx deleted file mode 100644 index 047abfee829..00000000000 --- a/src/Microsoft.PowerShell.ScheduledJob/resources/ScheduledJobErrorStrings.resx +++ /dev/null @@ -1,387 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Cannot find scheduled job {0}. - {0} is the scheduled job definition name that cannot be found. - - - Cannot find scheduled job definition {0} in the Task Scheduler. - - - 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. - - - An error occurred while adding triggers to the scheduled job {0}. - - - 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. - - - Cannot get the {0} scheduled job because it is corrupted or in an irresolvable state. Because it cannot run, 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. - {0} is the name of the scheduled job definition. - - - An error occurred while loading job run results for scheduled job {0} with job run date {1}. - - - An error occurred while registering the scheduled job {0}. - - - An error occurred while removing job triggers from scheduled job {0}. - - - One or more scheduled job runs could not be retrieved {0}. - - - Job {0} cannot be saved because no file path was specified. - - - Job {0} has not been run and cannot be saved. Run the job first, and then save results. - - - An error occurred while enabling or disabling the scheduled job {0}. - - - An error occurred while setting properties on the scheduled job {0}. - - - Cannot start a job from the {0} scheduled job definition. - - - An error occurred while unregistering the scheduled job {0}. - - - An error occurred while updating the scheduled job definition {0} with this trigger {1}. See exception details for more information. - - - Only one JobTrigger type can be specified: AtStartup, AtLogon, Once, Daily, or Weekly. - - - A scheduled job definition object {0} already exists in the local scheduled job repository having this Global ID {1}. - - - A scheduled job definition object with Global ID {0} could not be found. - - - A scheduled job definition with ID {0} could not be found. - - - A scheduled job definition with Name {0} could not be found. - - - This scheduled job definition object {0} has been disposed. - - - Scheduled job definition {0}. - - - A directory not found error occurred while registering scheduled job definition {0}. Make sure you are running PowerShell with elevated privileges. - - - An error occurred while registering scheduled job definition {0}. Cannot add this definition object to the job store. - - - An error occurred while registering scheduled job definition {0} to the Windows Task Scheduler. The Task Scheduler error is: {1}. - - - An error occurred while unregistering scheduled job definition {0}. - - - An error occurred while setting file access permissions for job definition {0} and user {1}. - - - An error occurred while updating scheduled job definition {0}. Cannot update this definition in the job store. - - - An error occurred while updating scheduled job definition {0}. Cannot update this definition with the Windows Task Scheduler. - - - An error has occurred within the Task Scheduler. - - - The At parameter is not valid for the {0} job trigger type. - - - The DaysInterval parameter is not valid for the {0} job trigger type. - - - The DaysInterval parameter value must be greater than zero. - - - The DaysOfWeek parameter is not valid for the {0} job trigger type. - - - The FilePath parameter is not valid. - - - Only PowerShell script files are allowed for FilePath parameter. Specify a file with .ps1 extension. - - - The IdleDuration parameter cannot have a negative value. - - - The IdleTimeout parameter cannot have a negative value. - - - The scheduled job definition name {0} contains characters that are not valid. - - - The MaxResultCount parameter cannot have a negative or zero value. - - - The User parameter is not valid for the {0} job trigger type. - - - The WeeksInterval parameter is not valid for the {0} job trigger type. - - - The WeeksInterval parameter value must be greater than zero. - - - 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 PowerShell scheduled job store. You might need to create the scheduled job definition again. - {0} is the scheduled job definition name - - - Job {0} is currently running. - - - The scheduled job definition {0} already exists in the job definition store. - - - The scheduled job results {0} already exist in the job results store. - - - The At parameter is required for the {0} job trigger type. - - - The DaysOfWeek parameter is required for the {0} job trigger type. - - - The job trigger {0} requires the DaysOfWeek parameter to be defined. - - - The Job trigger {0} requires the At parameter to be defined. - - - 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. - - - An access denied error occurred while updating the scheduled job definition {0}. Try running PowerShell with elevated user rights; that is, Run as Administrator. - {0} is the scheduled job definition name - - - There is no scheduled job definition object associated with this options object. - - - There is no scheduled job definition object associated with this trigger {0}. - - - The scheduled job {0} already exists in the local repository. - - - The scheduled job {0} is not in the local job repository. - - - The scheduled job definition {0} already exists in Task Scheduler. - - - Daily - - - AtLogon - - - A scheduled job trigger with ID {0} was not found for the scheduled job definition {1}. - - - Once - - - AtStartup - - - Weekly - - - An access denied error occurred when registering scheduled job definition {0}. Try running PowerShell with elevated user rights; that is, Run As Administrator. - - - Cannot convert a ScheduledJobTrigger object with TriggerFrequency value of {0}. - - - An unknown trigger type was returned from Task Scheduler for scheduled job definition {0} with trigger ID {1}. - - - 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} - {0} is the name of the scheduled job definition that cannot be registered -{1} is the inner exception message from .Net serialization, or empty if no exception message. - - - Commands that interact with the host program, such as Write-Host, cannot be included in 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. - - - The RepetitionInterval parameter value must be less than or equal to the RepetitionDuration parameter value. - - - The RepetitionInterval parameter value must be greater than 1 minute. - - - The RepetitionInterval and RepetitionDuration Job trigger parameters must be specified together. - - - The Repetition parameters cannot have negative values. - - - The Repetition parameters are not valid for the {0} job trigger type. - - - 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. - - - An error occurred while attempting to rename scheduled job from {0} to {1}. - - - An error occurred while attempting to rename scheduled job from {0} to {1} with error message: {2}. - - - An unrecoverable error occurred while renaming the scheduled job from {0} to {1}. The scheduled job will be removed. - - - An unrecoverable error occurred while renaming the scheduled job from {0} to {1} with message {2}. The scheduled job will be removed. - - - An error occurred while running scheduled job definition {0} from the Task Scheduler. - - - An error occurred while running scheduled job definition {0} from the Task Scheduler because {1}. - - - You cannot specify the RepetitionDuration and RepeatIndefinitely parameters in the same command. - - - When you use the RepeatIndefinitely parameter, the RepetitionInterval parameter is required. - - - the scheduled job definition could not be found - - - the scheduled job definition is disabled - -