Tuesday, January 23, 2007

PowerShell output strangeness

When I run batch jobs, I normally use a stub (here simplified) like this –

Set name=%~n0
Set log=%temp%\%name%.log
Set recursive=%1
If not defined recursive %0 yes >”%log%” 2>&1
The-command-you-want-to-run


In this way, I can ensure that I capture all output, including stderr (stream #2) in stdout (stream #1).

So I adapted the same approach with PowerShell – and got into problems. Actually, at first, I thought that I had made a work-around and would simply stick to that, but as it resurfaced, I decided to narrow it down and find the real problem.

The problem appears like this error message –

The OS handle's position is not what FileStream expected. Do not use a handle simultaneously in one FileStream and in Win32 code or another FileStream. This may cause data loss.
out-lineoutput : The OS handle's position is not what FileStream expected. Do not use a handle simultaneously in one FileStream and in Win32 code or another FileStream. This may cause data loss.



So how do I generate this message? Simply run this script with the above batch wrapper –

"start"
copy-item fds fdsaf
"end"


The abstract from the log generated is -

C:\>powershell -command .\x.ps1
start
Copy-Item : Cannot find path 'C:\Documents and Settings\Administrator\fds' because it does not exist.
At C:\Documents and Settings\Administrator\x.ps1:2 char:10
+ copy-item <<<<
out-lineoutput : The OS handle's position is not what FileStream expected. Do not use a handle simultaneously in one FileStream and in Win32 code or another FileStream. This may cause data loss.



Note, that removing the start and/or the end line, makes the error *not* appear.

So, how should this wrapper work with PowerShell? Well, from what I can figure out, PowerShell never writes to stderr, so everything can be captured by redirection stdout with >. Even output from write-host get captured.

But, anyway - this seems a minor bug in PowerShell.

2 comments:

Anonymous said...

I think you can pipe the output from a command and bypass this problem:
your-command||foreach-object{write-host "Command Response>>:" $_}

NeilM said...

this seems to correct the problem

https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=297055&SiteID=99