Solved

Send output to file only when logging is enabled

Posted on 2014-09-04
12
274 Views
Last Modified: 2014-09-06
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
0
Comment
Question by:Dan Craciun
  • 5
  • 5
  • 2
12 Comments
 
LVL 40

Expert Comment

by:Subsun
ID: 40303845
Did you consider enabling Start-Transcript if $log -eq "yes" ? Start-Transcript will print all output to a transcript file however it may not be clean. IMO, it depends on your script how we can write a log. I generally use Add-Content or try to create a PS custom object and then print it in to a csv file (easy to read and filter).

Ref : http://technet.microsoft.com/en-us/library/hh849687.aspx
0
 
LVL 34

Author Comment

by:Dan Craciun
ID: 40304053
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.
0
 
LVL 39

Assisted Solution

by:footech
footech earned 100 total points
ID: 40304232
The most flexible way to handle this (that I know of) is to have your script output objects, so that you can then pipe the results to Out-File, Out-Host, or whatever.
.\somescript | Out-File file.txt

Open in new window

I've considered the same question in the past, or something similar.  I was trying to think of a way to redirect the pipeline depending on the value of a variable (i.e. pipe to these commands if $a -eq 1, but pipe to these other commands if $a -eq 2).  Didn't spend a lot of time on it and never came up with anything  that wasn't similar to what you posted in your original question.

The last concept that I've thought of, but haven't fully explored it to see how well it would work, is something like below (simplified scenario).
If ($log -eq $true)
{ $c = "out-file c:\test\log.txt" }
Else
{ $c = "out-host" }
Invoke-Expression "write-output 'chickenbutt' | $c"

Open in new window

0
 
LVL 40

Expert Comment

by:Subsun
ID: 40304240
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}

Open in new window

0
 
LVL 34

Author Comment

by:Dan Craciun
ID: 40305377
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.
0
 
LVL 40

Expert Comment

by:Subsun
ID: 40305433
-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?
0
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 
LVL 34

Author Comment

by:Dan Craciun
ID: 40305473
Keeping a separate variable to be output in case of logging is not much prettier than the original version:

echo "something"
$Logdata += "something"
---- some more echoes

if ($log -eq "yes") {$Logdata | Out-File $logFile}

Open in new window

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"

Open in new window

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.
0
 
LVL 40

Expert Comment

by:Subsun
ID: 40305812
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..

$Logdata += "something"

if ($log -eq "yes") {$Logdata | Out-File $logFile} Else{$Logdata}

Open in new window


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.. :-)
0
 
LVL 34

Author Comment

by:Dan Craciun
ID: 40305858
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.
0
 
LVL 40

Accepted Solution

by:
Subsun earned 400 total points
ID: 40306796
The ideal would be
echo "something"
If you want to change the default behavior of echo then you can try something like the following..
If ($log -eq "Yes"){
  function Global:Write-Output { $args[0] | tee -FilePath $args[1] -Append }
}Else{
  function Global:Write-Output { $args[0]}
}

Echo "Something" $logfile

Open in new window

0
 
LVL 34

Author Comment

by:Dan Craciun
ID: 40307717
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? :)
If ($log -eq "Yes"){
  function Global:Write-Output { $args[0] | tee -FilePath $logFile -Append }
}Else{
  function Global:Write-Output { $args[0]}
}

echo "Something"

Open in new window


@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.
0
 
LVL 39

Expert Comment

by:footech
ID: 40308141
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.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
exchange, scripts 30 77
PowerShell Regular Expression 2 40
Get group membership from a list of samaccountnames 8 77
will this script work on w2k3 server? 2 11
In this previous article (https://oddytee.wordpress.com/2016/05/05/provision-new-office-365-user-and-mailbox-from-exchange-hybrid-via-powershell/), we made basic license assignments to users in O365. When I say basic, the method is the simplest way …
A brief introduction to what I consider to be the best editor for PowerShell.
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now