Posts Tagged ‘array’

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.