Share via


Cannot redirect Powershell output using Task Scheduler

Question

Tuesday, August 21, 2012 1:52 PM | 2 votes

I'm running Windows Server 2008 Enterprise x64 R2.

Sample script x.ps1:

(Get-Date).DateTime
Write-Output "output"
Write-Warning "warning"
Write-Error "error"

Run this in the cmd console:

powershell -command ".\x.ps1" *> x.log.  Works like a charm, I've got a log.

Now delete x.log.  Create a scheduled task with the exact same command:  powershell -command ".\x.ps1" *> x.log.  Run the scheduled task.  No log.

WTF?  How hard should this be?  I've spent hours Googling, I know this problem comes up a lot.  Why is a scheduled task so different than running from a cmd console?

I also tried powershell -file, as well as Start-Transcript, which looked promising, but I don't like the line wrapping in the scheduled task output.

All replies (31)

Tuesday, August 21, 2012 1:54 PM

P.S.:  Is this the best way to create a log file in the same directory as the running script, with the same basename but different extension?

$log=Join-Path (Get-ChildItem $MyInvocation.MyCommand.Definition).Directory (Get-ChildItem $MyInvocation.MyCommand.Definition).Basename
Start-Transcript "$log.log"


Tuesday, August 21, 2012 2:09 PM

One workaround is to crate a .bat file for your powershell command, then in your scheduled task command use:

runscript.bat > logfile.txt

[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "


Tuesday, August 21, 2012 9:22 PM

One workaround is to crate a .bat file for your powershell command, then in your scheduled task command use:

runscript.bat > logfile.txt

[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

the location of the logfile would still be somewhat ambiguous. I'd have the runscript.bat do the redirecting of the powershell.exe command it contains along these lines:

    (powershell -file "%~dpn0.ps1") > "%~dpn0.log"

this assumes that the bat, ps1, and log files have the same base name and are in the same directory.

Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.


Tuesday, August 21, 2012 9:24 PM

I'm running Windows Server 2008 Enterprise x64 R2.

Sample script x.ps1:

(Get-Date).DateTime
Write-Output "output"
Write-Warning "warning"
Write-Error "error"

Run this in the cmd console:

powershell -command ".\x.ps1" *> x.log.  Works like a charm, I've got a log.

Now delete x.log.  Create a scheduled task with the exact same command:  powershell -command ".\x.ps1" *> x.log.  Run the scheduled task.  No log.

WTF?  How hard should this be?  I've spent hours Googling, I know this problem comes up a lot.  Why is a scheduled task so different than running from a cmd console?

I also tried powershell -file, as well as Start-Transcript, which looked promising, but I don't like the line wrapping in the scheduled task output.

Just a thought... you say no log. Did the scheduled task run? what was the return code? Did the powershell script actually run and just fail to generate a log file where you expected it to be?

Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.


Wednesday, August 22, 2012 1:36 PM

What does %~ mean?

 

Where is it documented?

  - Larry

.

 

On 8/21/2012 4:22 PM, Al Dunbar wrote:

> the location of the logfile would still be somewhat ambiguous. I'd have the runscript.bat do the

> redirecting of the powershell.exe command it contains along these lines:

>

> (powershell -file "%~dpn0.ps1") > "%~dpn0.log"

>

> this assumes that the bat, ps1, and log files have the same base name and are in the same directory.

>

 


Wednesday, August 22, 2012 4:21 PM | 1 vote

LOL, it is "documented" in the help for the "for" command:

- Open a command prompt window and type "for /?"

  • press space bar 5 times

this should display the following:

In addition, substitution of FOR variable references has been enhanced.
You can now use the following optional syntax:

    %~I         - expands %I removing any surrounding quotes (")
    %~fI        - expands %I to a fully qualified path name
    %~dI        - expands %I to a drive letter only
    %~pI        - expands %I to a path only
    %~nI        - expands %I to a file name only
    %~xI        - expands %I to a file extension only
    %~sI        - expanded path contains short names only
    %~aI        - expands %I to file attributes of file
    %~tI        - expands %I to date/time of file
    %~zI        - expands %I to size of file
    %~$PATH:I   - searches the directories listed in the PATH
                   environment variable and expands %I to the
                   fully qualified name of the first one found.
                   If the environment variable name is not
                   defined or the file is not found by the
                   search, then this modifier expands to the
                   empty string

Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.


Wednesday, August 22, 2012 4:24 PM

Are you perhaps just getting back at me for my questions about documentation for an even more obscure powershell feature in this thread: http://social.technet.microsoft.com/Forums/en-US/winserverpowershell/thread/84374acb-6164-4f55-b280-0b30f24cc787

If so, that's a good one. Powershell is still undergoing improvements and new versions are coming out. Batch is pretty much, and likely always will be, the way it is, warts and all. So there! ;-)

Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.


Wednesday, August 22, 2012 4:25 PM | 1 vote

oops, should have included the next page of help text:

    %~zI        - expands %I to size of file
    %~$PATH:I   - searches the directories listed in the PATH
                   environment variable and expands %I to the
                   fully qualified name of the first one found.
                   If the environment variable name is not
                   defined or the file is not found by the
                   search, then this modifier expands to the
                   empty string

The modifiers can be combined to get compound results:

    %~dpI       - expands %I to a drive letter and path only
    %~nxI       - expands %I to a file name and extension only
    %~fsI       - expands %I to a full path name with short names only
    %~dp$PATH:I - searches the directories listed in the PATH
                   environment variable for %I and expands to the
                   drive letter and path of the first one found.
    %~ftzaI     - expands %I to a DIR like output line

Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.


Wednesday, August 22, 2012 4:49 PM

At least (as you say) this batch file issue is more easily documented than that obscure PowerShell

tab expansion issue.   At this point in time, I find I need to learn everything about both batch

files and PowerShell scripts to have a complete working knowledge of automation on a Windows OS.

 On 8/22/2012 11:24 AM, Al Dunbar wrote:

> Are you perhaps just getting back at me for my questions about documentation for an even more

> obscure powershell feature in this thread:

> http://social.technet.microsoft.com/Forums/en-US/winserverpowershell/thread/84374acb-6164-4f55-b280-0b30f24cc787

>

> If so, that's a good one. Powershell is still undergoing improvements and new versions are coming

> out. Batch is pretty much, aInd likely always will be, the way it is, warts and all. So there! ;-)

>

 


Wednesday, August 22, 2012 10:06 PM

While it might be true that you "need to learn everything about both batch pts to have a complete working knowledge of automation on a Windows OS*",* it is not true that any of the above is an actual requirement in any kind of real world situation.

Ask those here who have very significant knowledge of batch, powershell, and even vbscript, and they will likely tell you that they do not know everything about their subject. I know even less than these guys, but I certainly know enough to get by with.

I am less interested in knowing absolutely all of the possible programming constructs in any of these languages than I am in being able to apply what I do know to be productive. In the process I am sure to learn more, and be better for the increased knowledge. But I am not anticipating ever being able to say that I know everything about anything.

Further to that, there is a point at which striving to learn everything can be counterproductive. Unless that is one of the requirements of your job. If, on the other hand, there are operational aspects to your job that must be done, well, your boss might have some ideas about the best use of your time.

Imagine if the explorers of old tried to discover everything about where they explored, for example, mapping out all of the trails they ran across. If they had all done that, Lewis and Clarke might never have found the Pacific coast.

</rant>

Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.


Thursday, August 23, 2012 1:06 AM | 2 votes

Hi All,

I appreciate the replies.  But, why do I have to create a separate, one line batch file wrapper just to get sysout/syserr redirection to work from Task Scheduler?  Why can't Task Scheduler just...not...suck?  I'm dumbfounded how one command works fine in a cmd window, but the exact same command fails in Task Scheduler?  Is there anyone from M$ lurking here who knows the details of Task Scheduler - does it just launch a cmd process, then run the configured command?

Anyway, based on other posts in these groups (clearly others have this issue as well), I've changed my test script to:

x.ps1:

$DebugPreference = 2
$VerbosePreference = 2
$WarningPreference = 2

hostname.exe
Write-Host "host"
Write-Output "output"
Write-Error "error"
Write-Verbose "verbose"
Write-Warning "warning"
Write-Debug "debug"

From a cmd window:

del .\x_command.log
powershell -command ".\x.ps1" > ".\x_command.log"
works as expected, here is the output:

MYMACHINENAME
host
output
E:\SAS\Config\Utilities\x.ps1 : error
At line:1 char:8

  • .\x.ps1 <<<< 
        + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
        + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,x.ps1

VERBOSE: verbose
WARNING: warning
DEBUG: debug

del .\x_file.log
powershell -file ".\x.ps1" > ".\x_file.log"
works as expected, here is the output:

MYMACHINENAME
host
output
E:\SAS\Config\Utilities\x.ps1 : error
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,x.ps1

VERBOSE: verbose
WARNING: warning
DEBUG: debug

As you can see, the outputs are slightly different between the -command and -file invocation parameters.  Why...who knows?  Poor quality control and testing in Remond?

Using Task Scheduler:  I ran the task under my login userid credentials to replicate the environment of the cmd window.

(manually delete .\x_command.log)
powershell -command ".\x.ps1" > ".\x_command.log"
Does not work, but at least it created a file, here is the output:

MYMACHINENAME
output
<end of file>

(manually delete .\x_file.log)
powershell -file ".\x.ps1" > ".\x_file.log"
Does not work, does not create a file

I've spent hours just trying to get Task Scheduler to do simple redirection to a file!!!

Next on the agenda is seeing if something like cmd /c "powershell -file .\x.ps1 > .\x.log" will work, without having to create the separate batch file wrapper.  But what a convoluted mess just to get Task Scheduler to work in a way that makes sense.

(I admit this is tangentially related to Powershell, I'll also cross post this to a Task Scheduler group if there is one...)


Thursday, August 23, 2012 1:09 AM

Just a thought... you say no log. Did the scheduled task run? what was the return code? Did the powershell script actually run and just fail to generate a log file where you expected it to be?

Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.

Yes

0

Yes...my "actual" script was restarting services.  I could see them restarting, so I know the script ran (in addition to the 0 return code).  Just no log file.


Thursday, August 23, 2012 4:52 AM

I am less surprised than you to see that how one executes a script can have an effect on the result. There is obviously a reason for this. I agree it would be nice for someone to explain this.

But when it comes to your problem with scheduled tasks, I don't think this is a powershell issue at all. When you type a command at the command prompt, the command is processed by cmd.exe. When you create a task to run the same command, a different command processor is involved. IMHO, CMD.exe is the only one of the two that recognizes the redirection operators.

I suspect adding cmd /c as you suggest will resolve the issue. But if it does, this says nothing about any inconsistency within powershell. The exact same issue exists when one tries to execute a command with redirection from vbscript using something like:

    objshell.run("cscript.exe C:\myscript.vbs > C:\logfile.log")

in order for this to work, you have to change to something like:

    objshell.run("cmd /c C:\cscript.exe myscript.vbs > C:\logfile.log")

for exactly the same reason: cscript.exe does not process the redirection operators - only cmd.exe does.

Although a common misperception, executables do not need cmd.exe to run. If they did, imagine how ugly it would be when you double-click on a windows application...

You can complain about how all methods used to run an executable should support the same command line options. But they don't, never have, and never will. If that is a limitation, it is a limitation of windows, not of the various executables that do not support redirection in their command lines.

Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.


Thursday, August 23, 2012 7:47 AM

cmd /c ... didn't work.

yes, i know executables don't need cmd.exe.  but what does task scheduler do?  does it first launch a cmd process to run powershell?

i'm not saying the problem is in powershell...the problem is in task scheduler.

here is the documentation on redirection in powershell:

Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

PS C:\Documents and Settings\sbass> help about_redirection
TOPIC
    about_Redirection

SHORT DESCRIPTION
    Describes how to redirect output from Windows PowerShell to text files.

LONG DESCRIPTION
    By default, Windows PowerShell sends its command output to the Windows
    PowerShell console. However, you can direct the output to a text
    file, and you can redirect error output to the regular output stream.

    You can use the following methods to redirect output:

        - Use the Out-File cmdlet, which sends command output to a text file.
          Typically, you use the Out-File cmdlet when you need to use its
          parameters, such as the Encoding, Force, Width, or NoClobber
          parameters.

        - Use the Tee-Object cmdlet, which sends command output to a text file
          and then sends it to the pipeline.

        - Use the Windows PowerShell redirection operators.

      The Windows PowerShell redirection operators are as follows.

      Operator  Description                Example
           
      >         Sends output to the        get-process > process.txt
                specified file.

      >>        Appends the output to      dir *.ps1 >> scripts.txt
                the contents of the
                specified file.

      2>        Sends errors to the        get-process none 2> errors.txt
                specified file.

      2>>       Appends the errors to      get-process none 2>> save-errors.txt
                the contents of the
                specified file.

      2>&1      Sends errors to the        get-process none, powershell 2>&1
                success output stream.

    The syntax of the redirection operators is as follows:

       <input> <operator> [<path>\<file>

    If the specified file already exists, the redirection operators that do not
    append data (> and 2>) overwrite the current contents of the file without
    warning. However, if the file is a read-only, hidden, or system file, the
    redirection fails. The append redirection operators (>> and 2>>) do not
    write to a read-only file, but they append content to a system or hidden
    file.

    To force the redirection of content to a read-only, hidden, or system file,
    use the Out-File cmdlet with its Force parameter. When you are writing to
    files, the redirection operators use Unicode encoding. If the file has a
    different encoding, the output might not be formatted correctly. To
    redirect content to non-Unicode files, use the Out-File cmdlet with its
    Encoding parameter.

SEE ALSO
    Out-File
    Tee-Object
    about_Operators
    about_Command_Syntax
    about_Path_Syntax


Thursday, August 23, 2012 10:04 PM

The problem is only in task scheduler if it is failing to do what its developers intended it to do. What it does do is execute executables. Without calling on another executable (cmd.exe) to help with the work. If it needed cmd.exe to run an executable, how would it run cmd.exe?

That powershell documentation you quoted is all about the redirection available to powershell scripts commands typed interactively in the powershell console. It is not about what you can type on the command line, whether that be the command line of cmd.exe, start-run, or the task scheduler. It might be possible for a powershell redirection operator to be passed in to powershell on the powershell.exe command as part of a command. If so, it would need to be contained within the "-command" parameter, not between arguments on the command line, and appropriately escaped to avoid any special status it has with whichever command line processor is being used.

powershell.exe /? typed at the cmd prompt gives this:

PowerShell[.exe] [-PSConsoleFile <file> | -Version <version>]
    [-NoLogo] [-NoExit] [-Sta] [-NoProfile] [-NonInteractive]
    [-InputFormat {Text | XML}] [-OutputFormat {Text | XML}]
    [-WindowStyle <style>] [-EncodedCommand <Base64EncodedCommand>]
    [-File <filePath> <args>] [-ExecutionPolicy <ExecutionPolicy>]
    [-Command { - | <script-block> [-args <arg-array>]
                  | <string> [<CommandParameters>] } ]

When you used this:

    powershell -file ".\x.ps1" > ".\x_file.log"

You seem to be assuming that the <args> part of the powershell command includes these two arguments:

    > ".\x_file.log"

I think that assumption is unlikely to prove true. In any case, cmd.exe will not pass that ">" without some kind of quoting. I don't know what the task scheduler will do with the angle brackets, but unless there is documentation to say what that might be, it seems foolhardy to me to assume anything.

Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.


Sunday, August 26, 2012 6:17 PM

Are you getting any closer to being able to redirect output when running a powershell script via task scheduler? If so, please advise on the method and indicate which, if any, of our comments here moved you in that direction.

I'd also be interested in hearing how your opinions on the nature of this "problem" might have changed since you first posted.

Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.


Tuesday, August 28, 2012 1:52 PM

I don't know if Windows Server 2008 is any different from Windows 7, but redirection works with the Win7 task scheduler. I used it daily. The trick is to output the file to a specific directory that allows writing.

If I remember correctly from when I debugged this originally, if PowerShell executes with the -noprofile option or without being logged in as a user, the task scheduler runs it out of c:\windows\system32. On my system it can create the log file there (for some reason), but it can't write to it so I end up creating an empty file. Try scheduling the following:

PowerShell.exe -noprofile -Command "$PWD" > c:\ps_test.log

You should find the log file afterwards displaying the working directory name, which in my case is C:\windows\system32. As long as you change the log file to be a directory that is known to exist and that the process will have permissions to write to, you should be fine.

Also I found that while Task Scheduler has a Start In: directory, I still needed to specify the path to the output file. The Start In option didn't seem to work.


Wednesday, August 29, 2012 4:08 AM | 1 vote

Are you getting any closer to being able to redirect output when running a powershell script via task scheduler? If so, please advise on the method and indicate which, if any, of our comments here moved you in that direction.

I'd also be interested in hearing how your opinions on the nature of this "problem" might have changed since you first posted.

Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.

No.

None.

I neither love nor hate Microsoft.  I'm not a fanboy, nor am I a hater.  I use Microsoft every day.  I've been a developer in the past, and know about software development.

My "problem" (think Austin Powers here) is, I want the software I use to make my life easier, not harder.  I want it to be consistent.  I want it to exhibit intuitive behaviour.  So, for now, let's ignore any bias we (ok, you) may have toward this software, and just analyse the issue objectively.

Given this test script:

x.ps1:

$DebugPreference = 2
$VerbosePreference = 2
$WarningPreference = 2

hostname.exe
Write-Host "host"
Write-Output "output"
Write-Error "error"
Write-Verbose "verbose"
Write-Warning "warning"
Write-Debug "debug"

Powershell:

I get different results whether I invoke the script with:

powershell -command ".\x.ps1"

vs.

powershell -file ".\x.ps1"

Why?  I know you may be able to tell me reasons for this occurrence.  But why?  Why the difference?

Cmd window and Redirection:

powershell -command ".\x.ps1" > ".\x.log"

powershell -file ".\x.ps1" > ".\x.log"

both give expected results - the same output that appears in the console window without redirection appears in the log file.

Task Scheduler and Redirection:

powershell -command "c:\temp\x.ps1" > "c:\temp\x_command.log"
Does not work, but at least it created a file, here is the output:

MYMACHINENAME
output
<end of file>

powershell -file "c:\temp\x.ps1" > "c:\temp\x_file.log"
Does not work, does not create a file.

Why?  Why should Task Scheduler implement redirection differently that 1) the cmd window, and 2) differently based on how the script was invoked?  I'm not interested in the technical reasons, I'm interested in WHY?

So, sorry, "Al", my opinion of the nature of this "problem" remains unchanged.  Using Task Scheduler and this test script, I cannot create a log file that captures the desired results.

Lastly, I'm incredibly busy, so this is likely my last post on this issue (I can hear the applause from here).  I'm not going to get into a philosophical debate on the reasons for the current behaviour.  I expect the software to be consistent, intuitive, and make my life easier.  With respect to Task Scheduler, it falls short of the mark.  

If you have a helpful response, where you take the sample script, run it via Task Scheduler, and create a valid log file, then please let me know how you coaxed Task Scheduler to do this, so that others who search this forum in the future can benefit from your insight.


Wednesday, August 29, 2012 3:44 PM | 2 votes

Sorry if you feel my attempts to help fell short of that mark. So, if not "helpful", I'll try to be "objective":

In the cmd window, these commands both do what you want:

    powershell -command ".\x.ps1" > ".\x.log"
    powershell -file ".\x.ps1" > ".\x.log"

I believe this is because cmd.exe is running the powershell executable with these commands:

    powershell -command ".\x.ps1"
    powershell -file ".\x.ps1"

and then redirecting the output it receives from stdout using its redirection operator ">"

The same commands fail to perform in exactly the same way when run from the task scheduler. I suspect this is because the task scheduler does not recognise ">" as a redirection operator, and just passes it on to the executable, in this case, powershell.

To see how powershell might handle redirection, we could try the same commands from the powershell prompt. The documentation you quoted above states that ">" sends output to the indicated file. But that is only normal output, not error output. To redirect error output to the same file you need "2>&1", so let's try with my copy of your script:

  PS C:\Documents and Settings\dunbarak\Desktop\scott> .\scott.ps1 > ./logps.log 2>&1
  WARNING: warning
  PS C:\Documents and Settings\dunbarak\Desktop\scott> type ./logps.log
  Wednesday, August 29, 2012 9:01:09 AM
  output
  C:\Documents and Settings\dunbarak\Desktop\scott\scott.ps1 : error
  At line:1 char:12
  + .\scott.ps1 <<<<  > ./logps.log 2>&1
      + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
      + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,scott.ps1

  PS C:\Documents and Settings\dunbarak\Desktop\scott>

Close, but I see that the warning message seems to be something other than normal or error output. Now let's determine what command we could give to the task scheduler to do the same thing, but typing this command from a cmd window:

  M:\powershell -command "./scott.ps1 > ./log-command.log 2>&1"
  WARNING: warning
  M:\type log-command.log
  Wednesday, August 29, 2012 8:51:21 AM
  output
  M:\scott.ps1 : error
  At line:1 char:12
  + ./scott.ps1 <<<<  > ./log-command.log 2>&1
      + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorExcep
     tion
      + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExceptio
     n,scott.ps1

  M:\

By embedding the entire command, with the redirection operators, into the command to be passed to powershell, we get the same results as above. Unfortunately, the warning output is still not redirected.

I ran the equivalent command:

    (C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe -command "C:\\scott.ps1 > C:\\scott.log  2>&1")

using the task scheduler and got the same result.

I found what appeared to be the solution here: http://connect.microsoft.com/PowerShell/feedback/details/297055/capture-warning-verbose-debug-and-host-output-via-alternate-streams. Unfortunately the "3>&1" syntax it did not seem to work for me, as it gave an error when I tried it interactively:

  PS C:\_> powershell.exe -command "C:\_\scott.ps1 1> 2>&1 3>&1 C:\_\scott.log"  Ampersand not allowed. The & operator is reserved for future use; use "&" to pass ampersand as a string.  At line:1 char:27  + C:\_\scott.ps1 1> 2>&1 3>& <<<< 1 C:\_\scott.log      + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException      + FullyQualifiedErrorId : AmpersandNotAllowed  PS C:\_> powershell.exe -command "C:\_\scott.ps1 1> 2>&1 3>`&1 C:\_\scott.log"

It appears from the MS response to Keith Hill's suggestion that this may require Powershell V3.

I hope you find this more helpful than my previous responses.

Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.


Friday, August 31, 2012 5:41 AM

I don't know if Windows Server 2008 is any different from Windows 7, but redirection works with the Win7 task scheduler. I used it daily. The trick is to output the file to a specific directory that allows writing.

If I remember correctly from when I debugged this originally, if PowerShell executes with the -noprofile option or without being logged in as a user, the task scheduler runs it out of c:\windows\system32. On my system it can create the log file there (for some reason), but it can't write to it so I end up creating an empty file. Try scheduling the following:

PowerShell.exe -noprofile -Command "$PWD" > c:\ps_test.log

You should find the log file afterwards displaying the working directory name, which in my case is C:\windows\system32. As long as you change the log file to be a directory that is known to exist and that the process will have permissions to write to, you should be fine.

Also I found that while Task Scheduler has a Start In: directory, I still needed to specify the path to the output file. The Start In option didn't seem to work.

See above reply...

BTW, why didn't the Start In option work (rhetorical question).

Microsoft, do you monitor these forums???


Friday, August 31, 2012 5:47 AM

Thanks Al.  Apologies for my tone before - a bad day I guess.  I took your double-quotes ... "problem" to be dismissive of my opinion that it is in fact a problem.  

I do appreciate the time you took to look into this issue and post your messages.


Friday, August 31, 2012 6:15 PM

It seems your experience actually shows powershell -command "c:\temp\x.ps1" > "c:\temp\x_command.log" works, but just not how you expected.

Using the basic redirect operator, >, only STDOUT should be redirected to the file and that's what happened.  Write-Error writes to STDERR. You would need to redirect STDERR to a file which you can do like this: 2>c:\temp\error.log.  To redirect it to the same file as STDOUT, you would need to do it like this: 2>&1. And in case it's not clear to you this redirection is not being done by PowerShell - it's the command interpreter, cmd, that's capturing the output. PowerShell never sees the > on the command line.

Write-host, write-debug, write-verbose and write-warning do not write to either STDERR or STDOUT, as documented, so it shouldn't come as a surprise that their output doesn't go to the file. While it might be nice if you *could* make their output go to one or the other, it's not really a bug or a fault.

Testing powershell -command c:\temp\x.ps1 >c:\temp\x_command.log 2>&1 via the task scheduler captures information written to both STDOUT and STDERR. I did find one surprise though: the message produced by "throw" doesn't go to STDERR and thus doesn't get redirected. It seems to write to the console directly, like write-host. I did find that it can be captured though, along with the output of write-host. To do so setup the following in the task scheduler: 

cmd.exe /c powershell.exe -command c:\temp\x.ps1 >c:\temp\x_command.log 2>&1

I hope that helps.


Friday, August 31, 2012 6:34 PM | 4 votes

Actually no sooner than I post the above, I realize there is a way to capture ALL output.  Take the command interpreter out of the equation and let PowerShell capture the output.  Run it like this:

powershell.exe -command "PowerShell c:\temp\x.ps1 >c:\temp\x_command.log"

It's a little funky-looking but works perfectly, capturing all output. It does of course start 2 instances of PowerShell but if you really need to capture all output, including the special warning, debug and verbose streams that PowerShell writes to, it kind of makes sense you have to have PowerShell do it.


Saturday, September 1, 2012 3:40 AM

Thanks Al.  Apologies for my tone before - a bad day I guess.  I took your double-quotes ... "problem" to be dismissive of my opinion that it is in fact a problem.  

I do appreciate the time you took to look into this issue and post your messages.

Apology accepted. but more than that, I'm glad you didn't leave the thread as you suggested you would. Also glad you realize I wasn't being dismissive. But I still disagree about the lack of redirection done by the task scheduler being a problem. It may be inconvenient. but since the task scheduler allows you to run any script, then whatever kind of logging one wants to do can be done - by the script. One reason is that tasks are in the general case run multiple times, one often wants to log to different files, perhaps based on the date or time. To build that logic into a generalized scheduled task redirection scheme would seem to me to be fairly complicated, and might not cover all scenarios.

Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.


Saturday, September 1, 2012 3:42 AM

Actually no sooner than I post the above, I realize there is a way to capture ALL output.  Take the command interpreter out of the equation and let PowerShell capture the output.  Run it like this:

powershell.exe -command "PowerShell c:\temp\x.ps1 >c:\temp\x_command.log"

It's a little funky-looking but works perfectly, capturing all output. It does of course start 2 instances of PowerShell but if you really need to capture all output, including the special warning, debug and verbose streams that PowerShell writes to, it kind of makes sense you have to have PowerShell do it.

Great idea, but are you sure that's right? I'd have thought more like this:

    powershell.exe -command "PowerShell c:\temp\x.ps1" >c:\temp\x_command.log

Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.


Saturday, September 1, 2012 1:56 PM

Yeah, because I ran it before posting it. :-) Your example will have the same incomplete logging because it relies on cmd to capture the output. That outermost redirection symbol will never be seen by PowerShell.


Wednesday, September 19, 2012 5:03 AM

which is the solution about your issue, @Scott Bass ?

I use this script cmd:

powershell.exe  -noninteractive -file "C:\Testing\PS\test1.ps1"  > "C:\Testing\Logs\logTest1.log"

works for me.

www.kiquenet.com/profesional

Did you run it via Windows Task Scheduler?


Monday, October 1, 2012 12:49 PM | 1 vote

Hi All,

         to me, the output file was generated when I select 'run only when the user is logged on'.

any thoughts why not when 'Run whether the user is logged on or not'?


Monday, October 1, 2012 3:58 PM

Hi All,

         to me, the output file was generated when I select 'run only when the user is logged on'.

any thoughts why not when 'Run whether the user is logged on or not'?

That seems to be a separate question. Since this is old already, you will probably get more responses by starting a new thread usnig the "ask a question" button. Also, it would be helpful to indicate specifically what code it was that you were trying to run.

Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.


Thursday, January 17, 2013 9:36 PM

@The Other Scott Bass

I too fought this thing like crazy and something happened to me that may make it work for you.  First off, just like you, my command line runs gave me everything I wanted.  When, however, I ran the exact same PS script from the TS  the thing just flat out would not return the bits I was interested in getting.  I was trying everything I could, in as many different ways as I could and had no success.  Just because I had tried everything else I decided to follow a hunch proposed by a post seeing if the results differ if the "only when user logged on" option was ticked.  ALL of my previous attempts have been with a user account with sufficient privileges and the "whether logged on or not" option selected.  This time, for fun, I tried with the "user logged on" option ticked.  As soon as I set that setting something new came up that had not come up before - the credential window asking for user name and password.  In ALL of my previous attempts that thing never came up but for the very first time I created the task those many days ago.  Well, whaddya know, its working.  So, yah, I said screw this, what if re-establishing the credentials was my issue?  That perhaps there is a bug in the TS GUI that - despite providing credentials initially - a change to the task whenever the "run whether user is logged in or not" never, I don't know, "refreshes" the credentials.  Sure enough it worked like a charm whereas before it didn't do squat.  Yikes.

So, if you were in a similar "run whether user is logged in or not" situation, try flipping that to "only when logged on", providing the credentials, and then flipping it back to "logged in or not" and I'll bet you get asked for credentials and I'll bet it starts working better for you.  Give it a shot!

Best Regards, Eric Norberg


Friday, December 20, 2013 11:53 AM

First, add to the beginning of the script two lines:

[CmdletBinding()]

Param ()

Use Write-Verbose within the script body.

Then create the scheduled task:

Register-ScheduledJob -Name Task -Credential $Cred -Trigger (New-JobTrigger -Daily -At '11:00 PM') -ScriptBlock { d:\script.ps1 -Verbose *> 'd:\log.log' }

This worked for me. You may also want to redirect only selected outputs. See http://technet.microsoft.com/en-us/library/hh847746.aspx