Powershell logging from invoke-command
Solution 1
I ended up making the entire foreach a variable by begining the script with: $out = Foreach{.......}. I then piped the variable at the end
$out | Out-File $logfile
Here is a sample:
$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
Solution 2
As documented, Invoke-Command
returns all command output, so you could use Write-Output
instead of Write-Host
and pipe the returned output into a file. There's no fancy coloring with Write-Output
, though. You could, however, write 'Info', 'Warn' and 'Error' level messages to the correct streams using Write-Output
, Write-Warning
and Write-Error
. Also, you may want to suppress output from 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
}
GreetRufus
Updated on June 22, 2020Comments
-
GreetRufus almost 4 years
I have a script that includes a function for logging. The function writes log to $msg variable then writes the message to the screen. i can redirect this output to a .txt file for logging.
I need to run the script to multiple servers using invoke-command and write the log output to a txt file on the computer running the script.
I am trying to figure out how to output $msg in the write-log function from the PSSession and return it so I can create a master log file for all the servers. Should I create and populate a custom object? Not sure how to do that and get the results back from the remote session.
Can this even be done?
Here is an example of the code I am using and what the log file output should look like:
$servers = 'Server1','Server2' $logfile = 'c:\scripts\logs\Reg-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 }
Log output to Reg-DLL-log.txt should look like this:
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
-
Bjørn van Dommelen over 9 yearsYour answer is conceptually identical to Ansgar so why add it and accept your own answer as the solution? I.m.o. this denies Ansgar's answer the credit it deserves...