简体   繁体   English

PowerShell c# 中的脚本块

[英]PowerShell Scriptblck in c#

I am trying to run a powershell script in c# that contains among other the command: Get-Credential我正在尝试在 c# 中运行一个 powershell 脚本,其中包含以下命令:Get-Credential

I can run the file with the Process Command:我可以使用 Process Command 运行该文件:

 public static void RunFile(string ps1File)
        {
            
            var startInfo = new ProcessStartInfo()
            {
                FileName = "powershell.exe",
                Arguments = $"-NoProfile -ExecutionPolicy unrestricted -file \"{ps1File}\"",
                UseShellExecute = false,
                CreateNoWindow = true
            };
            try
            {
                Process P = Process.Start(startInfo);
                P.WaitForExit();
                var result = P.ExitCode;
                System.Diagnostics.Debug.WriteLine("Error: " + result);
            }
            catch (Exception e)
            {
                throw;
            }
        }

but with that I dont get the PS return value.但是我没有得到 PS 返回值。 So I am trying the System.Management.Automation but now I have the issue that the PS windows does not come up and I get straight my error code:所以我正在尝试 System.Management.Automation 但现在我遇到了 PS windows 没有出现的问题,我直接得到了我的错误代码:

public async static void RunFileTest(string ps1File) {

    PowerShell ps = PowerShell.Create();

    //PowerShell ps = PowerShell.Create();
    if (File.Exists(ps1File)) {

        ScriptBlock sb = ScriptBlock.Create(System.IO.File.ReadAllText(ps1File));
        System.Diagnostics.Debug.WriteLine("SB: " + sb.ToString());


        // execute the script and await the result.
        //var results = await ps.InvokeAsync().ConfigureAwait(false);

        //var results = ps.Invoke();

        PSCommand new1 = new PSCommand();
        
        
        ps.Commands = new1;

        var results = ps.Invoke();

        foreach (var result in results)
        {
            Console.WriteLine(result); //<-- result NOT results
            System.Diagnostics.Debug.WriteLine("Error: " + result.ToString());
        }

        System.Diagnostics.Debug.WriteLine("Errors: " + results);
    } else
    {
        System.Diagnostics.Debug.WriteLine("Error: " + "No File");
    }
}

Is there a way to run a PS file and get the windows like from get-credential but without the PowerShell Window?有没有办法运行 PS 文件并从 get-credential 获取 windows 但没有 PowerShell Window?

Thanks Stephan谢谢斯蒂芬


Edit: It seems, that I have to use exit instead of return to set a correct exit code when I use the first function RunFile, but nevertheless, the inbuild powershell function would be prefered编辑:看来,当我使用第一个 function RunFile 时,我必须使用 exit 而不是 return 来设置正确的退出代码,但是,inbuild powershell function 将是首选

As far as I know, if you calling PowerShell from C# in a way that PowerShell window is not visible, there is no way to display any prompts from that window.据我所知,如果您以 PowerShell window 不可见的方式从 C# 呼叫 882730794441488,则无法显示来自该 window 的任何提示。

The way we solved this is to ask user for credentials beforehand and pass them as arguments to PS script.我们解决这个问题的方法是事先询问用户凭据并将它们作为 arguments 传递给 PS 脚本。 You can even pass sensitive data (like password) as SecureString .您甚至可以将敏感数据(如密码)作为SecureString传递。

using System;
using System.Security;

public static class ConsoleHelper
{
    /// <summary>
    /// Replaces user input with '*' characters
    /// </summary>
    /// <returns>User input as SecureString</returns>
    public static SecureString GetPassword(string message) =>
        GetString(message, GetPasswordReader);

    public static string GetNotEmptyString(string message) =>
        GetString(message, (str) => !string.IsNullOrWhiteSpace(str));

    public static string GetString(string message, Func<string, bool> validator = null) =>
        GetString(message, Console.ReadLine, validator);

    private static T GetString<T>(string message, Func<T> reader, Func<T, bool> validator = null)
    {
        T value;
        while (true)
        {
            Console.Write(message + ": ");
            value = reader();
            if (validator?.Invoke(value) != false)
            {
                break;
            }
        }

        return value;
    }

    private static SecureString GetPasswordReader()
    {
        var pass = new SecureString();
        ConsoleKey key;
        do
        {
            var keyInfo = Console.ReadKey(intercept: true);
            key = keyInfo.Key;

            if (key == ConsoleKey.Backspace && pass.Length > 0)
            {
                Console.Write("\b \b");
                pass.RemoveAt(pass.Length - 1);
            }
            else if (!char.IsControl(keyInfo.KeyChar))
            {
                Console.Write("*");
                pass.AppendChar(keyInfo.KeyChar);
            }
        } 
        while (key != ConsoleKey.Enter);
        Console.WriteLine();

        return pass;
    }
}

Usage example:使用示例:

var scriptCommand = new Command(formExporterScriptPath)
{
    Parameters =
    {
        { "User", ConsoleHelper.GetNotEmptyString("Enter username") },
        { "Password", ConsoleHelper.GetPassword("Enter password") },
    }
};

using (var powershell = PowerShell.Create())
{
    powershell.Commands.AddCommand(scriptCommand);
    powershell.Invoke();

    Console.ForegroundColor = ConsoleColor.DarkGray;
    foreach (var result in powershell.Streams.Information)
    {
        Console.WriteLine(result.MessageData.ToString());
    }

    if (powershell.Streams.Error.Any())
    {
        Console.ForegroundColor = ConsoleColor.DarkRed;
        foreach (var result in powershell.Streams.Error)
        {
            Console.WriteLine(result.Exception.Message);
        }
    }

    Console.ResetColor();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM