Tag Archives: schedule

How To: Capture PowerShell Output in Windows Scheduled Tasks

In a previous blog Capture PowerShell Output in Windows Scheduled Tasks I stated the only reliable way I found to capture PS output is by using a CMD or Bat to execute the PS script. After stumbling upon the correct  way to call PowerShell using a –Command variable, I changed my mind. I found the correct way by reading the PowerShell help in PS v3 (imagine that) which says under –Command:

To write a string that runs a Windows PowerShell command, use the format:
“& {<command>}”
where the quotation marks indicate a string and the invoke operator (&)
causes the command to be executed.

So now, I can call PowerShell from Windows Task Scheduler with the correct syntax while still supplying various parms and send the whole command to an output file. The command would look like this:

Powershell.exe -NonInteractive -NoLogo -NoProfile -Command “& {D:\Scripts\SQL-Servers\Backup-SqlServer.ps1 –Server SQLSERVER -Verbose; Return $LASTEXITCODE}” 2>&1> D:\logs\SQL-Servers\Backup_SQLServer.txt”

This will execute my script, return whatever code I emit from the script, and write any output to a file.

Capture Powershell Output in Windows Scheduled Task

This post is outdated after discovering new information –
See my updated blog at How To: Capture PowerShell Output in Windows Scheduled Tasks

Ever see the Geico commercial where the guy says it took three months to teach a guinea pig to say “Row”? “Such a simple word”!

Well, I’ve hunted around, tried all kinds of methods, and spent hours on what should have been a simple task! Finally, I think I’ve found the only reliable method for capturing PowerShell output when it is run as a Windows Scheduled Task.

The long and short of it is: Use a CMD or BAT program to call the PowerShell script. You may not have to use a CMD program but in some cases you will. A lot of it depends on the parameters being passed and if those parameters contain a “List” item or whether there are single quotes or double quotes and who knows what else. I tried many variations of supplying PowerShell parms in task scheduler. Some worked in some cases and not in others. The only consistent method which worked in every case was to use a CMD program.

With this method you can not only capture all the PowerShell output (stderr, error, verbose, etc.) to a file using redirection but you can also capture any return code and thereby have the Windows Task “know” the script succeeded or failed.

There are no changes necessary to your PowerShell script unless you want to capture an Exit code.  What you do need to do is create a CMD program which calls your Posh using a format such as:

Echo off
::Execute a Powershell script from a CMD
If (%1)==() GOTO Missing
Powershell.exe -NonInteractive -NoLogo -NoProfile -Command ""D:\Scripts\MyPosh.ps1"" -Server %1 -Warehouse ""%2"" 2>&1> ""D:\logs\PoshLog_%1.txt"";Return $LASTEXITCODE"

:Missing
Echo "Parms are missing"
Exit 4

The key here is the –Command syntax. I have found this does not work properly when using –File. You must use –Command and enter the entire command (including script parms, redirection and the Return $LASTEXITCODE) within double quotes. You must also double double-quote any parms containing spaces. My example Command can be broken down as:

      1. The complete path and name of the PowerShell script to run
      2. Three parms I am supplying to the script as indicated by %1-%3. These parms are entered in the Windows Scheduled Task which calls this cmd script.
      3. The redirection of stderr to stdout and all redirected to a file using 2>&1> “C:\MyPath\log.txt”
      4. Command separator “;” the semicolon
      5. Capture the $LASTEXITCODE for the previous command (the Posh script) and throw it out to Windows Scheduler

 The Task Scheduler would look something like this  WinTaskSched.png The arguments portions is like this:

LCFSQLT04 "W:\SQL Backups" "'DOTProperty','Property'"

It has three arguments of which the last is a “list”

Emitting an Error

In order to capture an error from your Powershell script, you have to emit that error by using an EXIT statement. A RETURN statement will not work.

Cycle Those SQL Server Logs

Don’t you just hate it when you open one of your server logs in Management Studio and then you have to wait forever to review it because it never stops reading? I’ve done it enough times and decided to put an end to it or at least greatly reduce the incidence.

Using Powershell and a simple script to execute Sp_Cycle_Errorlog, I now have a weekly, Windows scheduled task which executes the sproc to cycle the logs for all my SQL Servers.

foreach ($svr in get-content D:\Scripts\Servers.TXT ){
    $svr
    Invoke-Expression 'SQLCMD -E -S $svr -Q "Exec Sp_Cycle_Errorlog"' | Out-Null
	}