如何在自定义PowerShell函数和Cmdlet中支持-AsJob参数

时间:2019-03-07 23:50:29

标签: powershell

我已进行了尽可能广泛的搜索,但似乎找不到通过自定义PowerShell函数或cmdlet支持-AsJob参数的方法。理想情况下,我不会在代码中使用Start-Job包装。我想使用任何可用的本机解决方案(如果存在),就像[CmdletBinding()]-WhatIf-Confirm启用一样。

1 个答案:

答案 0 :(得分:1)

我在这里找到了一些文档: https://docs.microsoft.com/en-us/powershell/developer/cmdlet/how-to-support-jobs

对于C#cmdlet模块:

protected override void ProcessRecord()
{
  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);
    WriteObject(job);
    ThreadPool.QueueUserWorkItem(WorkItem);
  }
  else
  {
    job.ProcessJob();
    foreach (PSObject p in job.Output)
    {
      WriteObject(p);
    }
  }
}

我去制作了与示例不同的JobImpl。您必须创建一个新文件PSJobImpl.cs

public class PSJobImpl: Job
{
    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();
        }
    }
}

示例调用(来自C#cmdlet模块):

PSJobImpl j = new PSJobImpl("CmdletName", (outputCollection) =>
{
    outputCollection.Add("[PSObject goes here]");
});

(如果您对StatusMessage和Location和StopJob有更好的实现,请编辑我的答案)-我只是在这里共享我的代码,以便其他人可以开始使用。