如何在执行前预览 PowerShell 命令?

问题描述

假设我有以下 PowerShell source

PowerShell shell = PowerShell.Create().AddCommand("Get-NetAdapter")
                                      .AddParameter("name","Ethernet*")
                                      .AddParameter("ThrottleLimit",5);

现在,在调用 shell.Invoke() 之前,为了记录目的,我想检查最终的命令行。在这种情况下,我希望像

Get-NetAdapter -name Ethernet* -ThrottleLimit 5

我测试了这些,但没有任何效果

shell.Commands.ToString()
shell.Commands.Commands.ToString()
shell.Commands.Commands.First().CommandText
shell.Commands.Commands.First().ToString()

是否有一些内置的方法来检查最终的命令行?

解决方法

怎么样:

namespace SomeProject.Extensions
{
    using System;
    using System.Management.Automation;
    using System.Management.Automation.Runspaces;
    using System.Text;

    public static class PowerShellExtensions
    {
        public static void LogCommandLine(this PowerShell commandToLog)
        {
            foreach (Command command in commandToLog.Commands.Commands)
            {
                StringBuilder commandLine = new StringBuilder(command.ToString());

                foreach (CommandParameter parameter in command.Parameters)
                {
                    commandLine.Append($" --{parameter.Name} {parameter.Value}");
                }

                Console.WriteLine(commandLine.ToString());
            }
        }
    }
}

哪个给定

namespace SomeProject.Extensions.UnitTests
{
    using System.Management.Automation;
    using NUnit.Framework;

    [TestFixture]
    [Parallelizable(ParallelScope.All)]
    [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
    public class PowerShellExtensionsTests
    {
        [Test]
        [Category(nameof(PowerShellExtensions))]
        public void TestCommandLine()
        {
            PowerShell shell = PowerShell.Create().AddCommand("Get-NetAdapter")
                                                  .AddParameter("name","Ethernet*")
                                                  .AddParameter("ThrottleLimit",5);

            shell.LogCommandLine();
        }
    }
}

输出你想要的:

Get-NetAdapter --name Ethernet* --ThrottleLimit 5

给定更复杂的参数,您可能需要更花哨,因为它只会输出参数的类型,而不一定是一个很好的字符串表示形式。

,

如果您特别需要在从参数构造对象时记录对象的创建,您可能需要考虑创建一个扩展方法,在构造过程中记录参数。

class Program
    {
        static void Main()
        {
            PowerShell shell = PowerShell.Create().Setup("Get-NetAdapter",("name","Ethernet"),("ThrottleLimit",5));
        }
    }
    public static class Logger
    {
        public static void Log(in string message)
        {
            Console.WriteLine(message);
        }
    }
    public static class PowershellExtenstions
    {
        public static PowerShell Setup(this PowerShell powerShell,in string command,params (string Name,object Value)[] parameters)
        {
            string message = command ?? string.Empty;

            powerShell.AddCommand(command);

            foreach (var parameter in parameters)
            {
                message += $" -{ parameter.Name } { parameter.Value }";

                powerShell.AddParameter(parameter.Name,parameter.Value);
            }

            Logger.Log(message);

            return powerShell;
        }
    }