Putting the Squeeze on Files with PowerShell

My December Mr. Roboto column is now online This month’s tool is a PowerShell WinForm script that uses WMI to compress files. I used PrimalForms 2009 to build the graphical interface. The interface is essentially a wizard that lets you build a WMI query to find files and compress them. 

captured_Image.png

Results can be logged to a CSV file or you can merely list the files that match the search criteria. Here’s a code excerpt.

$Compress={

    #initialize some variables

    $filters=@()

    $i=0

    $richtextbox1.Clear()

    $drive=$txtPath.Text.Substring(0,2)

    $filter="Drive='$drive' AND Compressed='False' AND Encrypted='FALSE'"

    $blnLog=$false

    

    $form1.Cursor="WaitCursor"

    

    if ($chkLogResults.checked) {

        #create a file for logging

        $timestamp=(get-date).toString('yyyMMddhhmmss')

        $logfile="Squeeze_$timestamp.log"

        $blnLog=$True

        #create the header

        "Server,Name,Extension,FileSize,LastModified,CreationDate,Drive,Path,Result" | out-file $logfile

    }

 

    #check other filter options

    if ($chkSize.Checked) {

        #add file size to filter

        [int]$FileSizeValue=$txtFileSize.Text

        $size=$FileSizeValue*1KB

        $filter+=" AND filesize >= $size"

    }

    

    

    if ($chkDate.Checked) {

         #convert datetime to a WMI datetime

        $datetime=[System.Management.ManagementDateTimeConverter]::ToDmtfDateTime($datetimepicker1.Value)

        $filter+=" AND LastModified >= '$datetime'"

    } #end if $chkDate.Checked

    

    if ($chkFileExtensions.Checked) {

        $arrExtensions=$txtExtensions.Text.split(",")

        $extensionFilter=" "

        for ($c=0;$c -lt $arrExtensions.Count;$c++) {

            $extensionFilter+="extension='$($arrExtensions[$c])'"

            if ($c -ne $arrExtensions.count-1) {

            $extensionFilter+=" OR "

            }

        }

                

        $filter+=" AND ($extensionFilter)"

    } #end if $chkFileExtensions.Checked

    

    #create a copy of the filter up to this point

    $basefilter=$filter

    

    #get base path

    if ($txtPath.Text.Length -eq 3) {

        #check if drive root

        $filepath="\\"

        $filter+=" AND path='$filepath'"

    }

    else {

           #parse out file path

           $filepath=$txtPath.Text.Substring(2)

           #replace \ with \\

           $filepath=$filepath.Replace("\","\\")

           $filter+=" AND path='$filepath\\'"

     }

    

    #add the base path to the set of filters

    $filters+=$filter

    

    if ($chkRecurse.Checked) {

 

       #process subfolders

       $p=$txtPath.Text

       dir $p  -rec | 

       where {$_.psIsContainer} | foreach {

           #replace \ with \\ and append the trailing \\

        $filepath="{0}\\" -f $_.fullname.substring(2).replace("\","\\")

        #append each filepath to a copy of the basefilter

        $tempFilter=$basefilter

        $tempfilter+=" AND path='$filepath'"

        

        #add each subfolder path to the collection of WMI query filters

        $filters+=$tempfilter

        } #end foreach

      

    } #end if $chkRecurse.checked

    

 

    foreach ($item in $filters) {

        #run a WMI query for each filter

        $cmd=("get-wmiobject -class CIM_DataFile -filter ""{0}""" -f "$item")

        

#        write-host $item -foregroundcolor CYAN

        

        $statusbar1.text="Running Query $item"

        $files=Invoke-Expression $cmd 

        

        if ($files) {

            foreach ($file in $files) {

                $i+=1

                $line="{0}`n" -f $file.name

                $richtextbox1.text+=$line

                $form1.Refresh()

                #compress the file if list only NOT checked

                if (! $chkListOnly.Checked) {

                    $rc=$file.Compress()

                    $result=$rc.returnValue

                }

                else {

                    $result="NA"

                }

                #log the results if checked

                if ($chkLogResults.checked) {

#                    "Server,Name,Extension,FileSize,LastModified,CreationDate,Drive,Path,Result"

                    $data="{0},{1},{2},{3},{4},{5},{6},{7},{8}" -f $file.CSName,$file.Name,$file.Extension,$file.FileSize,$file.ConvertToDateTime($file.LastModified),$file.ConvertToDateTime($file.CreationDate),$file.Drive,$file.path,$result

                    $data | out-file $logfile -append

                }

            } #end foreach $file in $files

        

        } #end if $files

        

        if ($i -gt 0) {

            $statusbar1.text="Found $i file(s) to compress"

        }

        else {

            $statusbar1.text="Failed to find any files to compress."

        }

            

    } #end foreach

    $form1.Cursor="Default"

    

    

    if ($blnLog) {notepad $logfile}

} #end Compress

The script has (I think) a nice example of providing popup help. You can download a zip file with the script and PrimalForms 2009 source file from the Mr. Roboto article.

Thanks to Wes Stahler for being such a willing lab rat.

Post to Twitter Post to Plurk Post to Yahoo Buzz Post to Delicious Post to Digg Post to Facebook Post to FriendFeed Post to Google Buzz Post to Ping.fm Post to Reddit Post to Slashdot Post to StumbleUpon Post to Technorati

This entry was posted in Mr. Roboto, PowerShell, PrimalForms, SAPIEN and tagged , , , , . Bookmark the permalink.

Comments are closed.