Запускать только подписанные скрипты powershell из C#

У меня есть служба Windows, которая загружает скрипт, а затем запускает его.

Я пытался сделать мой сервис Windows более безопасным, чтобы он принимал только подписанные скрипты Power-Shell.

Я выполнил команду Set-ExecutionPolicy AllSigned на сервере, и это работает в командной строке Windows Power Shell.

Тем не менее, мой код по-прежнему запускает как подписанные, так и неподписанные сценарии, даже если для set-executepolicy задано ограничение.

Я попробовал два подхода:

RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create ();

        Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
        runspace.Open();

        RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
        Pipeline pipeline = runspace.CreatePipeline();         
        pipeline.Commands.AddScript(@"Set-ExecutionPolicy AllSigned");
        pipeline.Commands.AddScript(@"Get-ExecutionPolicy");
        pipeline.Commands.AddScript(script);
        Collection<PSObject> results = pipeline.Invoke();

И еще один подход:

using (PowerShell ps = PowerShell.Create())
                {
                    ps.AddCommand("Set-ExecutionPolicy").AddArgument("Restricted");
                    ps.AddScript("Set-ExecutionPolicy Restricted");
                    ps.AddScript(script);
                    Collection<PSObject> results = ps.Invoke();
                  }

В обеих ситуациях код также запускает неподписанные скрипты.

Я что-то пропустил?

1 ответ

Решение

Я нашел решение. Единственный способ ограничить выполнение кода неподписанными скриптами - это проверить сами скрипты с помощью Get-AuthenticodSignature:

 public bool checkSignature(string path)
    {

        Runspace runspace = RunspaceFactory.CreateRunspace();
        runspace.Open();
        RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
        Pipeline pipeline = runspace.CreatePipeline();
        pipeline.Commands.AddScript(String.Format("Get-AuthenticodeSignature \"{0}\"", path));
        Collection<PSObject> results = pipeline.Invoke();
        Signature check = (Signature)results[0].BaseObject;
        runspace.Close();
        if (check.Status == SignatureStatus.Valid)
        {
            return true;
        }
        return false;
    }

Спасибо,

Дэн

Другие вопросы по тегам