8

I have a root directory that consists of many folders and sub folders. I need to check whether a particular file like *.sln or *.designer.vb exists in the folders or subfolders and output the result in a text file.

For Eg:

$root = "C:\Root\"
$FileType = ".sln",".designer.vb"

the text file will have result somewhat like below:

.sln ---> 2 files
.sln files path ----> 
c:\Root\Application1\subfolder1\Test.sln
c:\Root\Application2\subfolder1\Test2.sln

Any help will be highly appreciated!

Regards, Ashish

3 Answers 3

6

Here's a one-liner to determine if at least one file with extension .txt or .ps1 exists in the directory $OutputPath:

(Get-ChildItem -Path $OutputPath -force | Where-Object Extension -in ('.txt','.ps1') | Measure-Object).Count

Explanation: the command tells you the number of files in the specified directory matching any of the listed extensions. You can append -ne 0 to the end, which returns true or false to be used in an if block.

Sign up to request clarification or add additional context in comments.

1 Comment

Best answer for me on here +1. In case anyone may want the regex version, here's that. (Get-ChildItem -Path $OutputPath -force | Where-Object Extension -match ('\.jpe?g') | Measure-Object).Count Which will match either jpeg or jpg.
5

Try this:

function Get-ExtensionCount {
    param(
        $Root = "C:\Root\",
        $FileType = @(".sln", ".designer.vb"),
        $Outfile = "C:\Root\rootext.txt"
    )

    $output = @()

    Foreach ($type in $FileType) {
        $files = Get-ChildItem $Root -Filter *$type -Recurse | ? { !$_.PSIsContainer }
        $output += "$type ---> $($files.Count) files"
        foreach ($file in $files) {
            $output += $file.FullName
        }
    }

    $output | Set-Content $Outfile
}

I turned it into a function with your values as default parameter-values. Call it by using

Get-ExtensionCount    #for default values

Or

Get-ExtensionCount -Root "d:\test" -FileType ".txt", ".bmp" -Outfile "D:\output.txt"

Output saved to the file ex:

.txt ---> 3 files
D:\Test\as.txt
D:\Test\ddddd.txt
D:\Test\sss.txt
.bmp ---> 2 files
D:\Test\dsadsa.bmp
D:\Test\New Bitmap Image.bmp

To get the all the filecounts at the start, try:

function Get-ExtensionCount {
    param(
        $Root = "C:\Root\",
        $FileType = @(".sln", ".designer.vb"),
        $Outfile = "C:\Root\rootext.txt"
    )
    #Filecount per type
    $header = @()
    #All the filepaths    
    $filelist = @()

    Foreach ($type in $FileType) {
        $files = Get-ChildItem $Root -Filter *$type -Recurse | ? { !$_.PSIsContainer }
        $header += "$type ---> $($files.Count) files"
        foreach ($file in $files) {
            $filelist += $file.FullName
        }
    }
    #Collect to single output
    $output = @($header, $filelist)    
    $output | Set-Content $Outfile
}

6 Comments

Hi Graimer, Thanks for your response. After I call this function through the command prompt I get: cmdlet set-content at command pipeline pos 1. supply values for the parameters.. and the parameters are endless :(
This happends when you call exactly Get-ExtensionCount ? Did you copy the function 100%? Especially the last line. $output | Set-Content $Outfile. I think you forgot to include $Outfile at the end. Script works on PS2.0 and PS3.0. You could also try to switch the line with $output | Set-Content -Path $Outfile but it shouldn't matter.
Yes.. I had missed that :-) But in the output I get .sln--->44 files , .suo ---> files.. but none show the files and file paths.
oh, sorry. forgot about one PS3.0 feature. see updated answer
is there a way I can print the output in the manner where all the types of files and their counts come in first and all the file paths come in the last.. .sln--->34 files .suo--->120 files then comes the filepaths
|
0

This will search the directory $root and its subdirectories for files of type $FileType, including hidden files and excluding directories:

$root = "C:\Root\";
$FileType = "*.sln", "*.designer.vb";
$results = Get-ChildItem -Path $root -Force -Recurse `
    | Where-Object {
        if ($_ -isnot [System.IO.DirectoryInfo])
        {
            foreach ($pattern in $FileType)
            {
                if ($_.Name -like $pattern)
                {
                    return $true;
                }
            }
        }

        return $false;
    }

Note that I've modified the strings in $FileType to be formatted as a wildcard pattern. Then group the files by extension:

$resultGroups = $results | Group-Object -Property 'Extension';

Then loop through each group and print the file count and paths:

foreach ($group in $resultGroups)
{
    # $group.Count: The number of files with that extension
    # $group.Group: A collection of FileInfo objects
    #  $group.Name: The file extension with leading period
    Write-Host "$($group.Name) ---> $($group.Count) files";
    Write-Host "$($group.Name) files path ---->";

    foreach ($file in $group.Group)
    {
        Write-Host $file.FullName;
    }
}

To write the results to a file instead of the console, use the Out-File cmdlet instead of the Write-Host cmdlet.

4 Comments

Filter doesn't support array input(multiple fileext.)
Yes, just realizing that now.
You could however modify it to use if ($FileType -contains $group.Name) { ... in you foreach loop instead of the Filter
That would work, but then Group-Object would end up processing files and creating groups that might ultimately end up being ignored. Instead, I changed the call to Get-ChildItem to retrieve all files and the filtering is now performed inside of Where-Object. I made a slight change to the format of $FileType to facilitate this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.