Ведение журнала Powershell из invoke-command
У меня есть скрипт, который включает в себя функцию для ведения журнала. Функция записывает журнал в переменную $msg, а затем записывает сообщение на экран. я могу перенаправить этот вывод на a .txt-файл для ведения журнала.
Мне нужно запустить скрипт на несколько серверов с помощью invoke-command и запишите выходные данные журнала в txt-файл на компьютере, на котором выполняется сценарий.
Я пытаюсь выяснить, как вывести $msg в функции write-log из PSSession и вернуть его, чтобы я мог создать главный журнал файл для всех серверов. Следует ли создавать и заполнять пользовательский объект? Не знаю, как это сделать и получить результаты из удаленного сеанса.
Можно ли это вообще сделать?
Вот пример кода, который я использую, и как должен выглядеть вывод файла журнала:
$servers = 'Server1','Server2'
$logfile = 'c:scriptslogsReg-DLL-log.txt'
foreach($server in $servers){
invoke-command -cn $server -sb{
Param($server)
Function write-log{
[cmdletbinding()]
Param(
[Parameter(ValueFromPipeline=$true,Mandatory=$true)] [ValidateNotNullOrEmpty()]
[string] $Message,
[Parameter()] [ValidateSet(“Error”, “Warn”, “Info”)]
[string] $Level = “Info”,
[Parameter()] [ValidateRange(1,30)]
[Int16] $Indent = 0
)
$msg = "{0} {1}{2}:{3}" -f (Get-Date -Format "yyyy-MM-dd HH:mm:ss"), $Level.ToUpper(), (" " * $Indent), $Message
#This is output to screen
switch ($Level) {
'Error' { Write-Host ('{0}{1}' -f (" " * $Indent), $Message) -ForegroundColor 'Red'}
'Warn' { Write-Host ('{0}{1}' -f (" " * $Indent), $Message) -ForegroundColor 'Yellow'}
'Info' { Write-Host ('{0}{1}' -f (" " * $Indent), $Message) -ForegroundColor 'white'}
}}
write-log -message 'Begin DLL registration for $server' -level Info
$RegFile = "cimwin32.dll"
regsvr32 $RegFile /s
write-log -message 'registered $RegFile' -level Info
write-log -message 'End DLL registration for $server' -level Info
} -ArgumentList $server
}
Вывод журнала в Reg-DLL-log.txt должен выглядеть так:
2013-06-19 11:25:12 INFO:Begin DLL registration for Server1
2013-06-19 11:25:12 INFO:registered cimwin32.dll
2013-06-19 11:25:12 INFO:End DLL registration for Server1
2013-06-19 11:25:12 INFO:Begin DLL registration for Server2
2013-06-19 11:25:12 INFO:registered cimwin32.dll
2013-06-19 11:25:12 INFO:End DLL registration for Server2
2 ответа:
Как документировано,
Invoke-Command
возвращает все выходные данные команды, поэтому вы можете использоватьWrite-Output
вместоWrite-Host
и передать возвращенный вывод в файл. Хотя нет никакой причудливой раскраски сWrite-Output
. Однако вы можете написать сообщения уровня "информация", "предупреждение" и "ошибка" в правильные потоки, используяWrite-Output
,Write-Warning
иWrite-Error
. Кроме того, вы можете отключить вывод изregsvr32
.foreach ($server in $servers) { Invoke-Command -Computer $server -ScriptBlock { Param($server) Function write-log { ... switch ($Level) { 'Error' { Write-Error $msg } 'Warn' { Write-Warning $msg } 'Info' { Write-Output $msg } } } write-log -message 'Begin DLL registration for $server' -level Info $RegFile = "cimwin32.dll" regsvr32 $RegFile /s | Out-Null write-log -message 'registered $RegFile' -level Info write-log -message 'End DLL registration for $server' -level Info } -ArgumentList $server | Out-File -Append $masterLog }
Я закончил тем, что сделал весь foreach переменной, начав сценарий с: $выход = цикле foreach{.......}. Затем я передал переменную в конце
$out | Out-File $logfile
Вот пример:
$out = foreach($server in $servers){ invoke-command -cn $server -scriptblock { Param($server) "{0} :Begin DLL registration for {1}" -f (Get-Date -Format "yyyy-MM-dd HH:mm:ss"),$server } -ArgumentList $server } $out | Out-File $logfile