Powershell - захват вывода из Invoke-Command, запущенного exe на удаленном компьютере

Мне нужно настроить политику аудита для набора удаленных серверов. Я пытаюсь использовать командлет Invoke-Command для запуска auditpol.exe на каждом сервере. Проблема в том, что я не могу захватить какой-либо вывод команды auditpol.

Я попробовал очевидное (присвоение результата Invoke-Command строке):

> $command =  "Start-Process -FilePath `"auditpol.exe`" -ArgumentList `"/set`", `"/subcategory`", `"```"File System```"`", `"/success:enable`""
> $command
"auditpol.exe" -ArgumentList "/set", "/subcategory", "`"File System`"", "/success:enable"

> $out = Invoke-Command -ComputerName MyServer -ScriptBlock {$command}
> $out
>

Но $ out пуст.

Я также попробовал метод, описанный в этот блог MSDN с использованием Wait-Job и Receive-Job. Результаты несколько обнадеживают, но неубедительны:

> $command =  "Start-Process -FilePath `"auditpol.exe`" -ArgumentList `"/set`", `"/subcategory`", `"```"File System```"`", `"/success:enable`""
> $command
"auditpol.exe" -ArgumentList "/set", "/subcategory", "`"File System`"", "/success:enable"
> $job = Invoke-Command -ComputerName MyServer -ScriptBlock {$command} -AsJob
> Wait-Job $job

Id              Name            State      HasMoreData     Location             Command                  
--              ----            -----      -----------     --------             -------                  
3               Job3            Completed  True            MyServer  $command

> $output = Receive-Job $job
> $output
>

Я надеялся, что смогу захватить фактический вывод auditpol.exe с помощью Receive-Job, но, как указано выше, похоже, что это не так.

Я получаю некоторую информацию от Wait-Job. Согласно Microsoft документация по Wait-Job State = Completed должна указывать, что операция прошла успешно, но я не совсем уверен, что она действительно дает представление о том, была ли операция auditpol успешной или нет . Любой совет будет очень признателен!


person Mike Bruno    schedule 22.06.2018    source источник
comment
если вы используете PowerShell 5.x, вы можете попробовать Start-transcript и получить содержимое журнала, когда это будет сделано.   -  person thom schumacher    schedule 23.06.2018
comment
Спасибо, но Start-Transcript фиксирует только ваши команды и ответы, которые отображает Powershell (в основном то, что я отправил в своем вопросе). Я надеялся каким-то образом извлечь актуальный стандарт из auditpol.exe   -  person Mike Bruno    schedule 23.06.2018


Ответы (1)


Чтобы запустить консольную программу синхронно и с ее stdout и stderr выходом, доступным для захвата, вызывать ее напрямую - не используйте Start-Process (независимо от того, запускаете ли вы это программировать локально или удаленно через Invoke-Command):

$out = Invoke-Command -ComputerName MyServer -ScriptBlock {
  auditpol.exe /set /subcategory 'File System' /success:enable
}

Если вы также хотите захватить вывод stderr, добавьте 2>&1 к вызову auditpol.exe.


Если ваш блок скрипта хранится в локальной переменной $command (как экземпляр [scriptblock], а не как строка), просто передайте его прямо в -ScriptBlock:

# Create a script block (a piece of code that can be executed on demand later)
# and store it in a (local) variable.
# Note that if you were to use any variable references inside the block,
# they would refer to variables on the remote machine if the block were to be
# executed remotely.
$command = { auditpol.exe /set /subcategory 'File System' /success:enable }

# Pass the script block to Invoke-Command for remote execution.
$out = Invoke-Command -ComputerName MyServer -ScriptBlock $command

Что касается того, что вы пробовали:

$out = Invoke-Command -ComputerName MyServer -ScriptBlock {$command}

Вы передаете литерал блока сценария ({ ... }), который при выполнении на целевом компьютере ссылается на переменную с именем $command.

Как правило, простая ссылка на переменную выводит ее значение - ничего не выполняет.

Но что еще более важно, $command - это локальная переменная, которую блок сценария удаленного выполнения не может видеть, поэтому ссылка на неинициализированную там переменную $command фактически даст $null.

Вкратце: ваш Invoke-Command вызов ничего не делает и возвращает $null.


person mklement0    schedule 23.06.2018