How can I redirect PowerShell output when run from Task Scheduler?

PowershellScheduled TasksLine Endings

Powershell Problem Overview


When running a simple PowerShell script from Task Scheduler, I would like to redirect the output to a file.

There is a long thread about this very topic here, yet it's not clear if they reached the most appropriate solution in the end. I'm interested if anyone on Stack Overflow has also solved this problem, and how they did it?

Powershell Solutions


Solution 1 - Powershell

Here is the command that worked for me. I didn't like the idea of redirecting the output in the script, since it would make it difficult to run manually.

powershell -windowstyle minimized -c "powershell -c .\myscript.ps1 -verbose >> \\server\myscript.log 2>&1"

Solution 2 - Powershell

I use the transcript feature to help with this. Just include it in your code and it outputs all (would be) screen content to a log file.

Start-Transcript -path $LogFile -append

<Body of the script>

Stop-Transcript

Solution 3 - Powershell

The following works for me on Windows 7:

 powershell -command c:\temp\pscript.ps1 2>&1 > c:/temp/apickles.log

In the Windows 7 Task Scheduler GUI:

 program = "Powershell"
 arguments = "-command c:\temp\pscript.ps1 2>&1 > c:/temp/apickles.log"

Note that "-file" does not work because all parameters after the file name are interpreted as parameters to the file. Note that "2>&1" redirects the error output to the log file as well. Later versions of PowerShell do this in a slightly different way.

Solution 4 - Powershell

A combination of all the previous answers really helped me out...

My problem was that I needed to execute a PowerShell script over WinRM as part of a Packer provisioner, and it kept failing due to rights issues. The way around this is to execute as a scheduled task, but I needed to pass arguments to the script and get the output as well to confirm everything passed.

This snippet worked well for me:

# Generate a unique ID for this execution
$guid = [guid]::NewGuid()
$logFile = "C:\Windows\Temp\$guid.log"

$argument = "-NoProfile -ExecutionPolicy unrestricted -Command ""& {""$ScriptPath"" $ScriptArgs} 2>&1 > $logFile"""

$a = New-ScheduledTaskAction -Execute "powershell.exe" -Argument $argument
Register-ScheduledTask -TaskName $TaskName  -RunLevel Highest -User $username -Password $password -Action $a | Start-ScheduledTask
do {
    Start-Sleep -Seconds 30
    $task = Get-ScheduledTask -TaskName $TaskName
} while ($task.State -eq 4)

The full script can be found here:

https://gist.github.com/dev-rowbot/fa8b8dadf1b3731067a93065db3e1bba

Solution 5 - Powershell

I would do:
Create a function to call your script and redirect the output of this function like this:

.ps1:
function test{
    # Your simple script commands
    ls c:\temp -Filter *.JPG
    ls z:\ # Non-existent directory
}

test *> c:\temp\log.txt

Here is the log file:

    Répertoire : C:\temp


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        07/06/2008     11:06     176275 HPIM1427.JPG
-a---        07/06/2008     11:06      69091 HPIM1428.JPG
-a---        07/06/2008     11:06     174661 HPIM1429.JPG


ls : Lecteur introuvable. Il n'existe aucun lecteur nommé « z ».
Au caractère C:\temp\test.ps1:14 : 1
+ ls z:\ #non existent dir
+ ~~~~~~
    + CategoryInfo          : ObjectNotFound: (z:String) [Get-ChildItem], Driv
   eNotFoundException
    + FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.GetC
   hildItemCommand

You can control what do you want to output with the new V3 redirection operators:

Do-Something 3> warning.txt  # Writes warning output to warning.txt
Do-Something 4>> verbose.txt # Appends verbose.txt with the verbose output
Do-Something 5>&1            # Writes debug output to the output stream
Do-Something *> out.txt      # Redirects all streams (output, error, warning, verbose, and debug) to out.txt

Solution 6 - Powershell

It would be maybe easier to use Start-Transcript in order to log directly to a file:

# Get script name
$ScriptFullPath = $MyInvocation.MyCommand.Path
# Start logging stdout and stderr to file
Start-Transcript -Path "$ScriptFullPath.log" -Append

[Some PowerShell commands]

# Stop logging to file
Stop-Transcript

The log file will be in the same directory as the script.

Solution 7 - Powershell

I tested the following on Windows Server 2016, only call powershell once. This way you can have folder names with a space:

Powershell.exe -NoProfile -ExecutionPolicy Bypass -WindowStyle minimized "scriptName.ps1 *>> '\\servername\sharename\folder name with space\logfilename.log'"

Solution 8 - Powershell

PowerShell 3 onwards allows individual streams (out, verbose, and error) to be redirected. However, Task Scheduler does not understand them. It's PowerShell that does the redirection.

@cmcginty's solution halfway works, since PowerShell is invoking PowerShell. It only supports standard streams (error and out). If you want to use all streams you need to use:

Program or script: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

Argument: -windowstyle minimized –NonInteractive –NoProfile -c "powershell -c path_to_ps1.ps1 4>>verbose.log 5>>debug.log"

Start in: path_to_ps1

Solution 9 - Powershell

I'm inspired to write this answer by a comment-question from Anders (How do you add a timestamp?), and by the multiple replies that invoke PowerShell twice, which I would argue is not required. The task scheduler program is clearly "powershell.exe" and for the arguments I would suggest simply:

-noninteractive -c "scriptpath.ps1 *>>logpath.txt"

To keep a file per day, then:

-noninteractive -c "scriptpath.ps1 *>>logpath-$((get-date).ToString('yyyy-MM-dd')).txt"

And if you do want a log file with timestamp, you could remove the second ">" (two indicating append to any existing file) and expand the time format:

-noninteractive -c "scriptpath.ps1 *>logpath-$((get-date).ToString('yyyy-MM-dd_HH-mm-ss-fff')).txt"

Solution 10 - Powershell

The below sends verbose output to the screen as well as log it to a file.

something you're doing -Verbose 4>&1 | Tee-Object "C:\logs\verb.log" -Append

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncmcgintyView Question on Stackoverflow
Solution 1 - PowershellcmcgintyView Answer on Stackoverflow
Solution 2 - PowershellTACView Answer on Stackoverflow
Solution 3 - PowershellamtwisterView Answer on Stackoverflow
Solution 4 - Powershelldev-rowbotView Answer on Stackoverflow
Solution 5 - PowershellLoïc MICHELView Answer on Stackoverflow
Solution 6 - PowershellOrsiris de JongView Answer on Stackoverflow
Solution 7 - PowershellqzhxView Answer on Stackoverflow
Solution 8 - PowershellAdarshaView Answer on Stackoverflow
Solution 9 - PowershellJefferMCView Answer on Stackoverflow
Solution 10 - PowershellKelly DavisView Answer on Stackoverflow