Invoke-DosDir

[UPDATE 16.05.2015] Made the code more robust and simplified.

This is the function I mention in this post, which wraps the DOS dir command. 

Update: I fixed a small bug, and also added support for using regex to do further filtering.


function Invoke-DosDir {
<#
.SYNOPSIS
Wrapper for the dos command dir.
.DESCRIPTION
This function lets you search for files and folders using the dos command dir.
.EXAMPLE
Invoke-DosDir c:\
List files and folders on the root of the c-drive.
.EXAMPLE
Invoke-DosDir c:\ -GetInfo:$false
List files and folders on the root of the c-drive, returned as strings.
.EXAMPLE
Invoke-DosDir c:\*.log -Recurse
List all *.log files on the c-drive.
.EXAMPLE
Invoke-DosDir c:\ -Hidden
List all files and folders on the root of the c-drive, including hidden items.
.EXAMPLE
Invoke-DosDir c:\Windows\ -Directory
List only folders in the c:\Windows directory.
.NOTES
NOTE! Files and folders inside archives, don't have any attributes set, and since this function
uses attribute filtering these will probably not be included in the result.
Author: Øyvind Kallstad
Date: 14.05.2015
Version: 2.2
#>
[CmdletBinding(DefaultParameterSetName = 'File')]
param (
# Specify a path. Wildcards are supported.
[Parameter(Position = 0)]
[AllowNull()]
[string] $Path,
# Optionally you can use regex to do further filtering.
[Parameter(Position = 1)]
[string] $Regex,
# When GetInfo is True, FileSystemInfo objects are returned. If it's False, the full path of
# the files are returned as strings. This parameter defaults to true. To force return of strings,
# use -GetInfo:$false
[Parameter()]
[switch] $GetInfo = $true,
# Perform a recursive search.
[Parameter()]
[Alias('s')]
[switch] $Recurse,
# Show hidden items.
[Parameter()]
[switch] $Hidden,
# Show only files.
[Parameter(ParameterSetName = 'File')]
[switch] $File,
# Show only directories.
[Parameter(ParameterSetName = 'Directory')]
[Alias('d')]
[switch] $Directory
)
try {
if (-not([string]::IsNullOrWhiteSpace($Path))) {
# if the path given is not a folder, separate out the path portion and assume the remainder are the search pattern
# if no path is given at all (just a search pattern), get the current location and set that to the path string
if (-not(Test-Path Path $Path PathType Container)) {
try {
$pathString = Split-Path Path $Path ErrorAction Stop
if ([string]::IsNullOrWhiteSpace($pathString)) {$pathString = Split-Path Path Qualifier ErrorAction Stop}
$searchPattern = Split-Path Path $Path Leaf ErrorAction Stop
}
catch {
$pathString = (Get-Location).Path
$searchPattern = Split-Path Path $Path Leaf
}
}
# if the path input is a directory, use that as the path string with no search pattern
else {
$pathString = $Path
$searchPattern = ''
}
}
else {
# if path parameter is empty, use the current location with no search pattern
$pathString = (Get-Location).Path
$searchPattern = ''
}
# build the attribute filter string
$attributeFilter = ' /a:'
if ((-not($Hidden)) -and (-not($File)) -and (-not($Directory))) { $attributeFilter += '-h' }
if ((-not($Hidden)) -and $File) { $attributeFilter += 'a-h' }
if ((-not($Hidden)) -and $Directory) { $attributeFilter += 'd-h' }
if ($Hidden -and $File) { $attributeFilter += 'a' }
if ($Hidden -and $Directory) { $attributeFilter += 'd' }
# build the parameter string
$parameterString = "/O:gn /B$attributeFilter"
if ($Recurse) { $parameterString += ' /s' }
$parameterString += " ""$(Join-Path Path $pathString ChildPath $searchPattern)"""
# build the command string
$commandString = "cmd.exe /C dir $parameterString"
if ($Regex) { $commandString += ' | Where-Object {$_ -match "' + $Regex + '"}' }
if (-not($Recurse)) { $commandString += ' | ForEach-Object {Join-Path -Path "' + $pathString + '" -ChildPath $_}'}
if ($GetInfo) { $commandString += ' | ForEach-Object {Get-Item -LiteralPath $_ -Force:$Force -ErrorAction Stop}' }
# convert command string to script block
$command = [System.Management.Automation.ScriptBlock]::Create($commandString)
Write-Verbose "PathString: $pathString"
Write-Verbose "SearchPattern: $searchPattern"
Write-Verbose "AttributeFilter: $attributeFilter"
Write-Verbose "ParameterString: $parameterString"
Write-Verbose "CommandString: $commandString"
# run the command
Invoke-Command ScriptBlock $command
}
catch {
Write-Error "Oops! Something went wrong. [$($_.Exception.GetType().Name)]"
}
}
#Set-Alias -Name 'dir' -Value 'Invoke-DosDir' -Force -Option AllScope

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s