Subscribe to Windows IT Pro
December 15, 2009 12:00 AM

Find Files on Local Drives with Whereis.ps1

This PowerShell script supercharges the search capabilities of Get-ChildItem
Windows IT Pro
InstantDoc ID #103096
Rating: (1)
Downloads
103096.zip



Listing 1: Whereis.ps1's main Function

function main {
  # If -help is present or the -name parameter is missing, output
  # the usage message.
  if (($Help) -or (-not $Name)) {
    usage
  }

  # Convert $Name to an array. If any array element contains *,
  # change the array to $NULL. This is because
  #   get-childitem c:\* -include *
  # recurses to one level even if you don't use -recurse.
  $Name = @($Name)
  for ($i = 0; $i -lt $Name.Length; $i++) {
    if ($Name\[$i] -eq "*") {
      $Name = $NULL
      break
    }
  }

 
#CALLOUT A
  # If no -path parameter, use WMI to collect a list of fixed drives.
  if (-not $Path) {
    $Path = get-wmiobject Win32_LogicalDisk -filter DriveType=3 | foreach-

object {
      $_.DeviceID
    }
  }
  #END CALLOUT A

  # Convert $Path into an array so we can iterate it.
  $Path = @($Path)

  
#CALLOUT B
  # If a path ends with "\", append "*". Then, if it doesn't end with
  # "\*", append "\*" so each path in the array ends with "\*".
  for ($i = 0; $i -lt $Path.Length; $i++) {
    if ($Path\[$i].EndsWith("\")) {
      $Path\[$i] += "*"
    }
    if (-not $Path\[$i].EndsWith("\*")) {
      $Path\[$i] += "\*"
    }
  }
  #END CALLOUT B

  # If no -LastWriteTimeRange parameter, assume all dates.
  if (-not $LastWriteTimeRange) {
    $LastWriteTimeRange = @([DateTime]::MinValue, [DateTime]::MaxValue)
  }
  else {
    # Convert $LastWriteTimeRange to an array (if it's not already).
    $LastWriteTimeRange = @($LastWriteTimeRange)
    # If only one element, add max date as second element.
    if ($LastWriteTimeRange.Length -eq 1) {
      $LastWriteTimeRange += [DateTime]::MaxValue
    }
    # Zero for first element means [DateTime]::MinValue.
    if ($LastWriteTimeRange\[0] -eq 0) {
      $LastWriteTimeRange\[0] = [DateTime]::MinValue
    }
    
#CALLOUT C
    # Throw an error if [DateTime]::Parse() fails.
    trap [System.Management.Automation.MethodException] {
      throw "Error parsing date range. String not recognized as a valid 

DateTime."
    }
    # Parse the first two array elements as DateTimes.
    for ($i = 0; $i -lt 2; $i++) {
      $LastWriteTimeRange\[$i] = [DateTime]::Parse($LastWriteTimeRange\[$i])
    }
    #END CALLOUT C
  }

  # Throw an error if the date range is invalid.
  if ($LastWriteTimeRange\[0] -gt $LastWriteTimeRange\[1]) {
    throw "Invalid date range. The first date is greater than the second."
  }

  # If no -sizerange parameter, assume all sizes.
  if (-not $SizeRange) {
    $SizeRange = @(0, [UInt64]::MaxValue)
  }
  else {
    # Convert $SizeRange to an array (if it's not already).
    $SizeRange = @($SizeRange)
    # If no second element, add max value as second element.
    if ($SizeRange.Length -eq 1) {
      $SizeRange += [UInt64]::MaxValue
    }
  }

  
#CALLOUT D
  # Ensure the elements in the size range are numeric.
  for ($i = 0; $i -lt 2; $i++) {
    if (-not (isNumeric $SizeRange\[$i])) {
      throw "Size range must contain numeric value(s)."
    }
  }
  #END CALLOUT D

  # Throw an error if the size range is invalid.
  if ($SizeRange\[0] -gt $SizeRange\[1]) {
    throw "Invalid size range. The first size is greater than the second."
  }

  # If both -files and -dirs are missing, assume -files.
  if ((-not $Files) -and (-not $Dirs)) {
    $Files = $TRUE
  }

  # Keep track of the number of files and their sizes.
  $count = $sizes = 0

  # Use the get-childitem cmdlet to search the file system, and use
  # the writeItem function to output matching items. For files, check
  # the date and size ranges. For directories, only the date range is
  # meaningful.
  get-childitem $Path -include $Name -force: $Force -recurse: (-not 

$OneLevel) | foreach-object {
    if ($Files -and (-not $_.PsIsContainer)) {
      if (($_.LastWriteTime -ge $LastWriteTimeRange\[0]) -and 

($_.LastWriteTime -le $LastWriteTimeRange\[1]) -and
          ($_.Length -ge $SizeRange\[0]) -and ($_.Length -le $SizeRange\[1])) {
        $count++
        $sizes += $_.Length
        writeItem $_
      }
    }
    if ($Dirs -and ($_.PsIsContainer)) {
      if (($_.LastWriteTime -ge $LastWriteTimeRange\[0]) -and 

($_.LastWriteTime -le $LastWriteTimeRange\[1])) {
        $count++
        writeItem $_
      }
    }
  }

  # Output statistics if not using -defaultformat.
  if (-not $DefaultFormat) {
    "Found {0:N0} item(s), {1:N0} byte(s)" -f $count, $sizes
  }
}

Related Content:

ARTICLE TOOLS

Comments
    There are no comments to display. Be the first one!
You must log on before posting a comment.

Are you a new visitor? Register Here

advertisement

advertisement

Windows is a trademark of the Microsoft group of companies. Windows IT Pro is used by Penton Media Inc. under license from owner.