【问题标题】:Any faster solution for Powershell.Invoke?Powershell.Invoke 有更快的解决方案吗?
【发布时间】:2013-11-19 04:51:23
【问题描述】:

我正在用 C# 编写 CmdLet 并使用 Powershell-Class 并调用不同的命令。这是我的代码:

PowerShell poswershell;
public Construcor()
{
     powershell = PowerShell.Create()
}
public Collection<PSObject> InvokeRestMethod(string uri)
{
    return InvokePSCommand("Invoke-RestMethod", new[] { uri });
}

public Collection<PSObject> InvokePSCommand(string command, string[] args)
{
    var execute = command;
    execute = GetExecuteCommand(args, execute);
    powershell.Commands.AddScript(execute);
    return powershell.Invoke();

}

private static string GetExecuteCommand(string[] args, string execute)
{
    if (args == null) return execute;
    for (var i = 0; i < args.Count(); i++)
    {
        execute += " " + args[i];
    }
    return execute;
}

它像我想要的那样工作,但真的很慢。我想要同样的功能,这给了我一个Collection&lt;PSObject&gt; 回来。但是当我多次拨打InvokeRestMehtod 时,需要很长时间才能解决这个问题。 为什么我只将它用于一个简单的WebRequest 你问? 答案是,我必须从 uri(返回 json)中读取一些信息。事实上,json 结构总是不同的。因此,Invoke-RestMehtod 正是我所需要的,一个动态对象 (PSObject)。我必须拥有这种对象,因为在该过程之后,我需要将其返回给 powershell 用户,以便他可以通过管道传输对象并进一步使用它。 我现在的问题是,如何从返回 json 的 uri 中获得相同的结果,并将其传递到 powershell?

编辑

我找到了这个 dll=>Microsoft.PowerShell.Commands.Utility.dll,它在C# 代码中包含了InvokeRestMethod-CmdLet 所调用的powershell。如果我能很好地阅读这段代码,我可以(会)在我的代码中使用它。然后我不会创建一个 PowerShell 实例并从我的 powershell-CmdLet 调用另一个 CmdLet,我不太喜欢它并且花费的时间太长。有人知道这个dll,可以帮我为我的项目定制这个代码吗?

我找到了dottrace 并分析了过程,这里是screenshot 我无法从中获得任何有用的信息,也许你们中的某个人?但我很确定Powershell.Invoke() 在执行时会占用大部分时间。

【问题讨论】:

  • 它不会加快速度,但是您不需要在示例中使用 GetExecuteCommandFunction,而是编写 powershell.AddCommand(command); foreach (var args in args) { powershell.AddArgument(arg);这避免了生成脚本,也避免了 PowerShell 对命令的任何解析。
  • 感谢您的评论,我将进行此更改。但这不是我问题的解决方案。我搜索了另一种方法来获得相同的结果,因为powershell.Invoke(); 行的执行时间太长。

标签: c# json powershell


【解决方案1】:

为什么不重复使用同一个 PowerShell 对象而不是每次都创建一个新对象?每次实例化都会导致 PowerShell 必须再次初始化。请务必在 Invoke() 调用之间调用 powershell.Commands.Clear()。

【讨论】:

  • 感谢您的回答!我做了这个有用的改变,谢谢伙计。但是在速度上没有任何变化,在调试中我在powershell.Invoke(); 上看到过需要很长时间。每个Invoke 大约需要 2 秒。
【解决方案2】:

我现在解决了这个问题,这里是读取uri(返回JSON)并返回object的基本代码:

  private object InvokeRest(string uri)
    {
        return InvokeRest(uri, null);
    }
    private object InvokeRest(string uri, NetworkCredential networkCredential)
    {
        var webRequest = WebRequest.Create(uri);
        if (networkCredential!=null)
            webRequest.Credentials = networkCredential;
        _webResponse = webRequest.GetResponse();
        var streamReader = new StreamReader(_webResponse.GetResponseStream());
        var str = streamReader.ReadToEnd();
        ErrorRecord exRef;
        var doc = JsonObject.ConvertFromJson(str, out exRef);
        return doc;
    }

因为我发现你在 powershell 中输出的每个object,都会转换成PSObject 并格式化。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-29
  • 1970-01-01
  • 2021-05-06
  • 1970-01-01
  • 2016-03-27
  • 1970-01-01
  • 2013-09-20
相关资源
最近更新 更多