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 i
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.
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
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
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
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"
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.