Dan Craciun
asked on
Send output to file only when logging is enabled
In powershell, how can I redirect the output of the echo statements to a file only if logging is enabled (I have a parameter called $log that can be "yes").
I know I can repeat the echos:
echo "something"
if ($log -eq "yes") {echo "something" >> $file}
But it's ugly. Is there a way so that if $log is yes then all the output is sent to a file?
Thank you.
Dan
I know I can repeat the echos:
echo "something"
if ($log -eq "yes") {echo "something" >> $file}
But it's ugly. Is there a way so that if $log is yes then all the output is sent to a file?
Thank you.
Dan
ASKER
It doesn't really make sense to write a csv in this case. The script processes some files and it outputs the file name being processed, then at the end a summary line with "x files were processed in y seconds".
I'm looking for a general way to specify at the beginning of a script that I want to output the 1 and 2 streams (success and error) to a file.
I'm looking for a general way to specify at the beginning of a script that I want to output the 1 and 2 streams (success and error) to a file.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Probably you can use a string array to write the log details and in the end if the $Log -eq "Yes" then dump the data in log var to a log file.. Does it make sense?
#define log var
[String[]]$Logdata = $null
#script
$file = $_
#Process something
$Logdata += "Successfully Processed $file"
#something fails
$Logdata += "Error in processing file $file"
If ($Log -eq "Yes"){$Logdata | Out-File C:\Temp\log.txt}
ASKER
I see I'm not the only one looking for this: https://connect.microsoft.com/PowerShell/feedbackdetail/view/297055/capture-warning-verbose-debug-and-host-output-via-alternate-streams
What I'm exploring now is something in the line of:
echo "something" | tee $logFile -Append
The idea is to send the output to the console and an external file, with the possibility that the external file is null. It's way better looking than constantly testing for $log -eq "yes"
This would be perfect if tee wouldn't complain if $logFile is null. Even with -ErrorAction SilentlyContinue it throws an error.
What I'm exploring now is something in the line of:
echo "something" | tee $logFile -Append
The idea is to send the output to the console and an external file, with the possibility that the external file is null. It's way better looking than constantly testing for $log -eq "yes"
This would be perfect if tee wouldn't complain if $logFile is null. Even with -ErrorAction SilentlyContinue it throws an error.
-FilePath is a mandatory parameter for tee do it will fail if it value of $logFile is null. Setting $ErrorActionPreference to "SilentlyContinue" will suppress the error however the command will still fail to out put the pipeline object to host. You always need to use a condition to check $logFile is $null or not.
BTB, Did you try suggested options from previous comments?
BTB, Did you try suggested options from previous comments?
ASKER
Keeping a separate variable to be output in case of logging is not much prettier than the original version:
footech's last option looks interesting:
echo "something"
$Logdata += "something"
---- some more echoes
if ($log -eq "yes") {$Logdata | Out-File $logFile}
And since the script has some exit points, I would have to check for logging before each exit.footech's last option looks interesting:
if ($log -eq "yes") {$output = "out-file $logFile"}
else {$output = "out-host"}
invoke-expression "echo 'something' | $output"
I think I'll go with that if I don't find an option that will allow me to specify at the beginning of the script that I want to redirect output to a file.
You don't have to use echo if you are using the string array. You can either decide to output the result to host or to file based on the $log value..
and, since there is no there is no conventional method to achieve your goal, I am not sure how we can call a method as perfect or near perfect!!.. but beauty is in the eye of the beholder.. :-)
$Logdata += "something"
if ($log -eq "yes") {$Logdata | Out-File $logFile} Else{$Logdata}
and, since there is no there is no conventional method to achieve your goal, I am not sure how we can call a method as perfect or near perfect!!.. but beauty is in the eye of the beholder.. :-)
ASKER
I know I can just list the variable and it will be echoed... and I still don't like it :)
I need to see an echo or print, or my brain has trouble processing the fact that that variable will be posted.
And yes, it's a matter of taste. For me
echo "something"
$Logdata += "something"
is uglier than
invoke-expression "echo 'something' | $output"
Not by much, but still.
The ideal would be
echo "something"
I still think there should be an automatic variable that can be set so the output is redirected to a file. Well, maybe in PS 8.
I need to see an echo or print, or my brain has trouble processing the fact that that variable will be posted.
And yes, it's a matter of taste. For me
echo "something"
$Logdata += "something"
is uglier than
invoke-expression "echo 'something' | $output"
Not by much, but still.
The ideal would be
echo "something"
I still think there should be an automatic variable that can be set so the output is redirected to a file. Well, maybe in PS 8.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Subsun, this is brilliant! Thanks!
I should of thought I can override the default behavior of PS cmdlets, but I did not.
I changed it slightly. The idea is to let the script write to stdout, but use logging without changing the initial code. Like this I never touch the echo statements.
Seems like a good idea now to use echo and not just the variable, doesn't it? :)
@footech: thank you also. The invoke-expression idea is good. I could of changed all the echos to
invoke-expression "echo 'something' | $output"
but Subsun solution allows me to never touch those echos.
I should of thought I can override the default behavior of PS cmdlets, but I did not.
I changed it slightly. The idea is to let the script write to stdout, but use logging without changing the initial code. Like this I never touch the echo statements.
Seems like a good idea now to use echo and not just the variable, doesn't it? :)
If ($log -eq "Yes"){
function Global:Write-Output { $args[0] | tee -FilePath $logFile -Append }
}Else{
function Global:Write-Output { $args[0]}
}
echo "Something"
@footech: thank you also. The invoke-expression idea is good. I could of changed all the echos to
invoke-expression "echo 'something' | $output"
but Subsun solution allows me to never touch those echos.
Yes, a wrapper function is a good idea. I've seen them used in other cases, don't know why it didn't occur to me here.
Nice work, Subsun.
Nice work, Subsun.
Ref : http://technet.microsoft.com/en-us/library/hh849687.aspx