Как выполнить сценарий PowerShell от C# как неподнятый пользователь

Я пытаюсь выполнить сценарий PowerShell из приложения C#, и мне нужен сценарий для выполнения, когда мое приложение C# работает как неадминистраторский пользователь (например, Сетевая служба или некоторая другая учетная запись домена).

Ранее, я использовал следующий код:

using (RunspaceInvoke invoker = new RunspaceInvoke())
{
    // load the powershell module
    invoker.Invoke("Import-Module MyModule");

    // run the cmdlet defined in the module 
    invoker.Invoke("MyCmdlet");
}

Я не знаю, является ли это лучшим подходом для выполнения cmdlets определенный в модуле (учите меня, если существует лучший путь!). В любом случае это работает отлично, если я работаю как административный пользователь. Я пытался выполнить это как Сетевую службу, однако, и я получил недружелюбную ошибку в конструкторе RunspaceInvoke:

Требуемый доступ к реестру не позволяется.

Существует ли способ, которым я могу выполнить свой PowerShell cmdlets как неподнятый пользователь, такой как Сетевая служба? Я не нуждаюсь или требую получить доступ к реестру. Сам cmdlet также не требует поднятых полномочий.

10
задан Chris Gillum 13 February 2010 в 03:58
поделиться

4 ответа

Я думаю, что эта запись ответит на ваш вопрос.

-1
ответ дан 4 December 2019 в 04:53
поделиться

Если вы уверены, что статус будет только одной строкой, вы можете сделать что-то подобное с sed:

status=$(echo "$status" | sed -e 's:^foo$:bar:' -e 's:^baz$:buh:')

Вы также можете получить что-то для работы со встроенной заменой bash. Это почти работает (я не знаю ни одного способа получить точное совпадение только):

status=${status/foo/bar}
status=${status/baz/buh}

Если ваша цель просто быть более "функциональным" (а не сделать ваш код более опечаткой), вы могли бы сделать это:

status=$(
  case "$status" in
    ("foo") echo "bar" ;;
    ("baz") echo "buh" ;;
    (*) echo "$status" ;;
  esac)

Хотя, честно говоря, bash, вероятно, один из худших языков, чтобы попытаться и быть функциональным в. Он действительно был разработан с более императивным мышлением, о чем свидетельствует тот факт, что вы не можете легко составить выражения. Видите во втором фрагменте кода, как мне пришлось разбить его на два отдельных оператора? Если бы баш был разработан, чтобы быть функциональным, вы бы могли написать что-то подобное:

status=${{status/baz/buh}/foo/bar}

Но это не работает.

Я бы предложил использовать bash только для более простых сценариев, а для более сложных вещей использовать что-то вроде Python или Ruby. Они позволят вам писать более функциональный код без необходимости постоянно бороться с языком.

-121--3147186-

/Приложения/MAMP/htdocs/hello.php

Появится на http ://localhost: 8888/hello.php

:)

-121--3430719-

больше на lkaso ответ

это показывает вам, как запустить его как кто-либо, а не только admin. YOu должны запустить его как кто-то, служба работает как сильно ограниченный счет, который не может ничего сделать.

или запустить саму службу как джо-пользователя

0
ответ дан 4 December 2019 в 04:53
поделиться

Мы используем версию ниже. Параметр "script" - это запускаемый сценарий PS. Мы используем это из настраиваемой командной строки, чтобы мы могли смешивать команды C # с некоторыми, написанными на PS. «результаты» можно использовать для получения оценки вашего сценария. Строка «out-default» означает, что вывод сценария PS записывается в консоль. Версия этого может вместо этого захватывать вывод в TextBox или аналогичный, если у вас есть приложение WinForm of WPF.

public void run(string script)
{
    IEnumerable<PSObject> results;
    var config = RunspaceConfiguration.Create();
    var host = new ScriptHost();
    using (var runspace = RunspaceFactory.CreateRunspace(host, config))
    {
        runspace.Open();
        runspace.SessionStateProxy.SetVariable("prog", this);

        using (var pipeline = runspace.CreatePipeline())
        {
            if (!string.IsNullOrEmpty(scriptPath))
                pipeline.Commands.AddScript(string.Format("$env:path = \"{0};\" + $env:path", scriptPath));

            pipeline.Commands.AddScript(script);

            var outDefault = new Command("out-default");
            outDefault.MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
            pipeline.Commands.Add(outDefault);

            results = pipeline.Invoke();
        }
    }
}
2
ответ дан 4 December 2019 в 04:53
поделиться

Можете ли вы использовать инструмент SysInternals procmon, чтобы посмотреть, какой доступ к реестру он пытается выполнить? Возможно, это даст вам некоторое представление о том, что можно сделать для решения проблемы.

0
ответ дан 4 December 2019 в 04:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: