Posts Tagged ‘task scheduler’

Using Powershell to keep your Windows server/ws from cluttering

Friday, February 8th, 2013

This blog entry and the script will give you an example of how to use Powershell to:

-specify a ‘model’ file
-specify a directory search and fill an array with filenames you filtered out
-work on each entry of the array and to something with it e.g. delete the file
-writing every into a log file

I use the script to delete huge dp dumps and delete them if they are the same size as the original db. Yes, the logic is flawed but for the moment, it does its job. The script is run by task scheduler on a daily basis.

Basically, the script does what it says above. All the required variable can be, no, must be set within the script. The script does not accept any parameters. For you convenience, you can also download it from here:
dbbakcleanup.ps1

here goes:
*************************************************************

# automated bkp cleanup:
# scans a directory, deletes files of the same size as a provided model size
# and writes a summary in a specified log file
#
# ideas for improvements:
# 1) –dry parameter to prevent any action
# 2) write log to event viewer
# 3) ?
#
###########################
#
# variables
#
###########################
#
# General error code, used to quit (exit) the script if not 0
$GenErrCode = 0

# array keeping all log entries which will be dumped into $logfile
$log_lines = @()
# `n <– inserts a newline in the logfile
$log_lines += “`n”
$log_lines += “**********************************”
$log_lines += “`nINFO: Date: ”
$log_lines += Get-Date
$log_lines += “`nInitializing…”

# where to look for files
$mydir = “%windir%:\path\to\my\dir”
if( Test-Path $mydir ) {
$log_lines += “`nINFO: Dir $mydir found, continuing”
} else {
$log_lines += “`nERR: Dir $mydir not found, stopping…”
$GenErrCode = 1
}

# reference file for size
$modelFile = Get-Item ‘%windir%:\path\to\my\file’
if( Test-Path $modelFile ) {
$log_lines += “`nINFO: File $modelFile found, continuing”
} else {
$log_lines += “`nERR: File $modelFile not found, stopping…”
$GenErrCode = 1
}

# filter the files by part of their file name when filling $my_array
# as an example, i specify the file extension. it could also be part of the file name.
# the filter gets applied in 52. if the filter is not a file extension, try setting the * before $pattern
$pattern = “.mdf”

# using $pattern to filter files for filling the array…
$my_array = @(Get-ChildItem -path $mydir\$pattern* | Sort-Object Name -Descending)
if ( $my_array.length -gt 0 ) {
$log_lines += “`nINFO: Array my_array not empty, continuing…”
} else {
# array empty, should not happen so just in case…
# in the line below, the name of the array is hardcoded (my_array), improved could use a variable instead
$log_lines += “`nERR: Array my_arry empty, stopping…”
$GenErrCode = 1
}

# array containing names of deleted files
#$del_files = New-Object System.Collection.ArrayList
$del_files = @()

# specify the name and location of the log file
# could be in a different directory than $mydir
$logfile = “$mydir\my_log.txt”
if( Test-Path $logfile ) {
$log_lines += “`nINFO: Logfile $logfile found…”
} else {
$log_lines += “`nINFO: Logfile $logfile not found, creating new logfile…”
}

# exiting script if an error occurred during initialization…
if ($GenErrCode -eq 1) {
$log_lines += “`nERR: GenErrCode not 0, writing logs and exiting…”
# redirect @log_lines to $logfile
Add-Content $logfile $log_lines
exit
}

#########################
#
# end of initialization
#
#########################
#
# functions
#
#########################

function fileProcess($filejob)
{
# during testing, use the whatif line, a dry-run function within powershell
#Remove-Item $filejob -whatif
Remove-Item $filejob -whatif
}

#########################
#
# end of functions
#
#########################
#
# script
#
#########################

$log_lines += “`nINFO: Starting mainloop…”

$filecount = 0
ForEach ($objElement in $my_array)
{
# compare file size, if equal, call fileProcess to delete file
if ( $objElement.Length -eq $modelFile.Length ) {
fileProcess $objElement
$del_files += $objElement.Name
}
$filecount += 1
}

$log_lines += “`nINFO: Counted ” + $filecount + ” instance(s) to process…”

# all the lines starting with Write-Host were used for troubleshooting
# feel free to uncomment them to get some additional information during runtime
#Write-Host “filecount is” $filecount
#Write-Host “del_files is” $del_files

if ( $del_files.length -lt 1) {
$log_lines += “`nINFO: No files deleted!”
} else {
if ( $del_files.length -eq 1 ) {
$log_lines += “`nINFO: Deleted this file: $del_files”
} else {
$log_lines += “`nINFO: Deleted these file: $del_files”
}
}

#Write-Host $del_files
#Write-Host $log_lines

#
$log_lines += “`nScript finished, writing logs…”
Add-Content $logfile $log_lines

#########################
#
# end of script
#
#########################

*************************************************************

I’m sure there are suboptimal things in the script. Please take it as it is, improve on it, use it as you like.
I wanted the function to do more than just deleting the file – I also wanted it to write to the log file but I couldn’t get that to work.

Creating scheduled tasks with schtasks.exe on Windows 7

Tuesday, April 24th, 2012

In Windows 7, it’s easy to create scheduled tasks. You can either use Task Scheduler under Programs -> Accessories -> System Tools or you can use schtasks.exe in the cmd. schtasks.exe can be scripted and most of the commands and options that are available in Task Scheduler are also available in schtasks.exe

In my particular case, I wanted to create a task that runs EVERYDAY in a 5 MINUTE INTERVAL from 07:00 to 21:30. Although schtasks.exe provides some examples, I promptly chose the wrong example to edit and whatever I tried didn’t seem to work.

After a lot of fiddling and calling up a good friend’s advice, this command line did the trick (should all be on one line):

schtasks /create /ru “system” /sc daily  /tn “your task name” /tr “‘%programfiles%\path\to\your\executable.exe'” /st 07:05 /sd 01/01/2012 /du 14:30 /ri 10 /f

What does this do?

Start a cmd as administrator and the above command line will create a task called “your task name”.
The task will be created and run:
-in system context (ru = run as user)
-daily from 07:05 (sc = schedule, st = starting time) until 21:30 (du = duration – 14.5 hours)
-in a 10 minute interval (ri = run interval in minutes)
-using the provided executable (tr = taskrun). Note that you can use environment variables that have to be escaped using single quotes.
-forcing the task e.g. if a task with the same name already exists, it will be overwritten

Where did I go wrong:

The help in schtasks provides some examples. My mistake was the following though:
If you choose /sc minute, you’re stuck on one particular day because you have to provide a /st and an /et (end time). The end time will always default to the provided time and the day the task was created and only that day. E.g. if you create a task running from /st 07:00 to /et 14:00, schtasks.exe will translate this to “from 07:00 <today> to 14:00 <today>” and only run it on that particular day and then never again.

Notable absent option in schtasks.exe:
In the Task Scheduler gui, a task can be created/optimized for Vista/W2k8 or Win7/W2k8_R2.
This options changes the tag “Task version” from version=”1.2″ to version=”1.3″ in the XML file of that task. In schtasks.exe, this option is not available but it doesn’t seem to make a difference at all.

HTHS
m.