Tag Archives: tips

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.

Restore All SQL Transaction Logs using Powershell

I came across another opportunity for using Powershell when setting up mirroring for a large database at our DR site. The database was over 73Gig. The problem arose when it took a very long time to copy the backup and transaction logs and run the database restore. By the time the copy had finished another several transaction logs had been produced. While applying the *.bak  restore, yet another several transaction logs had been produced. Continue reading

Tips & Tricks Using Compare-Object – Copy New Files

This is a wonderful article which not only details the use of Compare-Object but also provides some very excellent examples on its use.

Tips & Tricks Using Compare-Object – Dreaming in PowerShell – PowerShell.com

I am very new to PowerShell but I am beginning to like using it considerably more each day. I recently had a need for a quick and easy way to script a process which would copy only new files from one location to another. after scouring the Internet for a good example, I stumbled upon the Compare-Object cmdlet and this excellent article.

The actual script I came up with is rather simple and serves my purpose exactly. As I  mentioned, I am new to PowerShell and there may very well be a better method. However, this one works for me.

The script code:

param(
    [string]$s = '\\serverx\c$\ProgramData\Polaris\3.5\SQLVS1\AuthorityUpdates',
    [string]$t = '\\servery\data03\shared\libraries\zmarc'
)

$target = Get-ChildItem $t
$source = get-childitem $s
Compare-Object $source $target -Property Name -PassThru |
    Where-Object { $_.SideIndicator -eq '<=' } |
    foreach-object -process{
        copy-item $_.FullName -destination $t
        }