Sometimes, the answer is "no". This turns out not to be a question, but more of a cri de coeur (OK, just complaining).
The Team Foundation Server 2010 PowerShell snap-in exports a cmdlet called Get-TfsPendingChange
, which does what it sounds like.
If there are no pending changes, Get-TfsPendingChange
echoes "There are no pending changes." on standard output. I never asked it to. The following attempts at suppressing that output all fail:
$pcs = $(Get-TfsPendingChange -Server $server "$/foo/bar" -User $env:USERNAME -r ) | out-null;
$($pcs = Get-TfsPendingChange -Server $server "$/foo/bar" -User $env:USERNAME -r ) | out-null;
$pcs = Get-TfsPendingChange -Server $server "$/foo/bar" -User $env:USERNAME -r | out-null;
I'm not getting errors, but the text output is not redirected. What IS redirected, is the normal successful output of the cmdlet, in the case where there are pending changes for it to return. The ONLY output you can suppress is the useful output. If there are zero pending changes, you get text garbage via stdout
. If there are any actual pending changes, that stream (of objects, not text) can be redirected to the null device, but that's worse than useless.
So it appears that text on stdout is a side effect from this cmdlet, not the cmdlet's output, and it cannot be redirected in PowerShell. The PowerShell redirect operators >
and |
, without the fileno specifiers (2 in PS2, 2, 3, 4, 5, and * in PS3/PS4), work on the object stream, which is not stdout
. This would be fine if stdout
had been replaced by this new object stream concept (or if some genius on the TFS team hadn't decided that cmdlets should spew random text noise in all directions as a side effect).
The garbage output definitely is on stdout
, not stderr
. I can redirect the standard output of the whole script to nul
when I run it from cmd.exe
, and that works as expected, because duh:
c:\>powershell .\tfstest.ps1 > nul
However, I do not want to suppress all the output from the entire script. Just the output from one snapin cmdlet. It's not the end of the world, but it's irritating to have random stuff that I call echoing garbage I have no control over. The script otherwise works correctly (see UPDATE).
One workaround would be to prefix everything I want to echo on stdout
with some arbitrary string (say "KLUDGEPREFIX"
), and run the whole mess from a batch file which pipes the PowerShell script's output through find /v KLUDGEPREFIX
and then through a PowerShell fragment that strips off the prefix from each line.
Instead, I'm going to write the rest of the script around the problem so it looks like what they get is what I intended, because, in fact, I was going to tell them they didn't have any pending changes anyhow. It's been a valuable exercise, however, in terms of getting my head inside PowerShell.
UPDATE: This script turned out to be fragile, unreliable, glacially slow, and impossible to run on any computer but the one where I originally wrote it.
I replaced it with a Perl script that took 1/10 the time to write, executed 10 times as fast, and does the same task better without any foolishness. PS and the TFS PS snap-in are great ideas but they both need a lot of work before they'll be ready for release.