Posts Tagged ‘powershell’

How to redirect output of console program to a file in PowerShell

Friday, March 5th, 2010

At some stage I decided I need backup plan for my virtual server. After some intensive web surfing I found brilliant command line tool – s3.exe. The next step was to schedule to run it periodically, every night, when everybody is sleeping.

Night

I decided to use PowerShell. It’s new, it’s powerful, it comes pre-installed with Windows Server 2008. PowerShell is very popular among system administrators.

Also, I got an idea to save output of backup application to log file so that I could see results later. And this is where things didn’t work as I expected. Here’s how to redirect console program output to a file:

s3.exe > log.txt

If you run this you will be surprised to find that log.txt is empty. As it turns out s3.exe, being a good Windows citizen, writes errors to STDERR stream. To redirect error output to the same file you need to add magic string 2>&1:

s3.exe 2>&1 > log.txt

Two new problems appear. First, errors appear as exceptions in log file:

s3.exe : s3.exe version 1.6 - check for updates at http://s3.codeplex.com
At PS Logging.ps1:4 char:43
+ s3.exe <<<<  2>&1 > log.txt
    + CategoryInfo          : NotSpecified: (s3.exe version ...s3.codeplex.com
   :String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

PowerShell helpfully wraps STDERR output into exceptions. This is nice but I don’t need it! All I want is to see how a program worked by examining log file. Do this to unwrap exceptions and show plain text:

s3.exe 2>&1 | foreach-object {$_.ToString()} | Out-File log.txt

And second, errors are out of order with normal output. They could appear before or after normal lines emitted by a program, making it hard to diagnose problem. To confirm that, I created a simple console program:

static void Main(string[] args)
{
   for (int i = 0; i < 10; i++)
   {
      Console.WriteLine("Hello");
   }
   Console.Error.WriteLine("Bah bah");
   for (int i = 0; i < 10; i++)
   {
      Console.WriteLine("2");
   }
}

If you run this program from PowerShell and redirect output to a file, error message (bah bah) could appear anywhere in the log file:

Hello
Bah bah
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
2
2
2
2
2
2
2
2
2
2

The solution I came up with is to let old reliable cmd.exe to do the work:

cmd /c s3.exe `>log.txt 2`>`&1

Note backsticks – I use them to prevent PowerShell from parsing redirect operators.

Links

PowerShell ABC's - O is for Output
How to capture exe output to a PowerShell variable
Another approach to unwrap exceptions: use add-content cmdlet.

How to run PowerShell scripts from Far Manager

Wednesday, August 5th, 2009

Let’s say you use Far Manager and want to launch PowerShell script. With default installation pressing Enter on PowerShell script in Far Manager will open the script in Notepad. Not very helpful.

Here’s how to configure Far Manager to launch PowerShell script by pressing Enter key:

  1. Open Commands menu, select File associations.
  2. Press Ins key to add new association.
  3. Enter *.ps1 as file mask.
  4. Enter the following as execute command:
    powershell.exe "&'.\!.!'"

Bonus: how to change colour of PowerShell scripts to green:

  1. Open Options menu, select Files highlighting.
  2. Locate *.exe,*.com,*.bat entry, press Enter to edit.
  3. Add *.ps1 to the list, select Ok to save.

See also: Running Windows PowerShell Scripts