-AsJob
is a common switch in all the official PowerShell cmdlets that allow them to run in the background. But how do you implement it?
You’ll have to restructure your module a little bit. There’s probably another way in which you don’t have to, but I haven’t figured that out.
For the C# cmdlet module, do this - this is standard template code obtained from the official documentation (see resources below).
protected override void ProcessRecord() //or EndProcessing()
{
if (AsJob)
{
// Add the job definition to the job repository,
// return the job object, and then create the thread
// used to run the job.
JobRepository.Add(job); //the job instance comes later - scroll down to the last step to see how to instantiate it
WriteObject(job);
ThreadPool.QueueUserWorkItem(WorkItem);
}
else
{
//this is to process the 'job' synchronously (i.e. normally)
job.ProcessJob();
foreach (PSObject p in job.Output)
{
WriteObject(p);
}
}
}
I went and made my own JobImpl that’s different from the example in the offical docs. You have to make a new file PSJobImpl.cs:
public class PSJobImpl: Job
{
//this is what will be executed in the background
Action<PSDataCollection<PSObject>> _logicWithOutput;
public PSJobImpl(string command, Action<PSDataCollection<PSObject>> logicWOutput) : base(command)
{
SetJobState(JobState.NotStarted);
_logicWithOutput = logicWOutput;
}
public override string StatusMessage
{
get { return "Status"; }
}
public override bool HasMoreData
{
get
{
return hasMoreData;
}
}
private bool hasMoreData = true;
public override string Location
{
get { return "Location"; }
}
public override void StopJob()
{
throw new NotImplementedException();
}
public void ProcessJob()
{
SetJobState(JobState.Running);
DoProcessLogic();
SetJobState(JobState.Completed);
}
void DoProcessLogic()
{
if(_logicWithOutput != null)
{
_logicWithOutput(Output);
Output.Complete();
}
}
}
Here is how you instantiate the job that was used in the first step.
protected override void ProcessRecord() //or EndProcessing()
{
PSJobImpl job = new PSJobImpl("CmdletName", (outputCollection) =>
{
//code to actually do stuff goes here
//instead of calling WriteObject, call this:
outputCollection.Add("[PSObject goes here]");
//if other methods of your cmdlet need to add to the output collection, use a global variable
//_outputCollection = outputCollection;
});
if (AsJob)
...
}
Official docs: https://docs.microsoft.com/en-us/powershell/developer/cmdlet/how-to-support-jobs
get yourself on the email list
comments powered by Disqus