Saturday, August 8, 2009

Unix / Linux find equivalent in Powershell Find-ChildItem Cmdlet

Find is one of the most often used commands in day to day work life. Unix find command provides lot of features and options that enable users to find files/directories more effectively

In Powershell, we can use Get-ChildItem cmdlet to search for files. But it doesn't give you all the fun. So I have developed Find-ChildItem Powershell cmdlet which is equivalent to Unix find command.

Download Find-ChildItem for both 32 bits and 64 bits

Note: For 64 bit operating system, you will have to use different InstallUtil.exe. See below for details

Syntax:
Find-ChildItem [-Name <String>] [-Type <String>] [-MaxDepth <Int32>] [-MinDepth <Int32>] [-CMin <String>]
[-AMin <String>] [-WMin <String>] [-CTime <String>] [-ATime <String>] [-WTime <String>] [-Size <String>]
[-Empty] [-Exec <String>] [-Delete] [-OutObject] [[-Path] <String>] [<CommonParameters>]

ParameterDescription
NameAccepts .Net regular expression to match FileName
Typed - directory, f - file
MaxDepthDescend at most levels (a non-negative integer) levels of directories below the command line arguments
MinDepthDo not apply any tests or actions at levels less than specified mindepth level (a non-negative integer)
CMinFile was created n minutes ago
CTimeFile was created n*24 hours ago
AMinFile was last accessed n minutes ago
ATimeFile was last accessed n*24 hours ago
WMinFile was last changed/written n minutes ago
WTimeFile was last changed/written n*24 hours ago
SizeFile uses n units of space
EmptyFile is empty
ExecExecute Cmdlets in the given argument.
DeleteDelete file or directory
OutObjectWrite Objects in output instead of just Directory/File Names


Find-ChildItem Cmdlet Installation Instructions:
  1. Extract Find-ChildItem.zip files to C:\Windows\Microsoft.NET\Framework\ Directory
  2. Open Powershell with Administrator Privileges
  3. Now, lets install the cmdlet using InstallUtil.exe utility which is available as part of Microsoft Windows SDK.

    For 32 Bit Operating System:
    C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe "C:\Windows\Microsoft.NET\
    Framework\Find-ChildItem.dll"
    For 64 Bit Operating System:
    C:\Windows\Microsoft.NET\Framework64\v2.0.50727\InstallUtil.exe "C:\Windows\Microsoft.NET\
    Framework\Find-ChildItem.dll"
  4. Type Get-PSSnapin -Registered and press enter. If it displays FindChildItemPSSnapIn01 SnapIn, then our installation is successful
  5. Now, before we can use Find-ChildItem Cmdlet, we need to add FindChildItemPSSnapIn01 using Add-PSSnapin FindChildItemPSSnapIn01
  6. To permanently add the Snapin, Add-PSSnapin FindChildItemPSSnapIn01 Cmdlet need to be added to Windows Powershell Profile file
  7. See the below window, to get clear picture on Cmdlet Installation on Windows 7 32 Bits


PS C:\Users\Jagadish\> cd "C:\Windows\Microsoft.NET\Framework"
PS C:\Windows\Microsoft.NET\Framework> Get-ChildItem .\Find-ChildItem*

Directory: C:\Windows\Microsoft.NET\Framework

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 6/8/2009 1:13 PM 12288 Find-ChildItem.dll
-a--- 6/8/2009 1:14 PM 21298 Find-ChildItem.dll-Help.xml

PS C:\Windows\Microsoft.NET\Framework> C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe .\Find-ChildItem.dll
Microsoft (R) .NET Framework Installation utility Version 2.0.50727.3521
Copyright (c) Microsoft Corporation. All rights reserved.

Running a transacted installation.
.
.
.
The Commit phase completed successfully.

The transacted install has completed.

PS C:\Windows\Microsoft.NET\Framework> Get-PSSnapin -Registered

Name : FindChildItemPSSnapIn01
PSVersion : 2.0
Description : This is Powershell SnapIn that includes Find-ChildItem Cmdlet, developed by Jagadish <http://windows-powershell-scripts.blogspot.com/>

PS C:\Windows\Microsoft.NET\Framework> Add-PSSnapin FindChildItemPSSnapIn01

PS C:\Windows\Microsoft.NET\Framework> Find-ChildItem G:\Jagadish\Cmdlets
G:\Jagadish\Cmdlets\Test
G:\Jagadish\Cmdlets\Test\1
G:\Jagadish\Cmdlets\Test\1\2
G:\Jagadish\Cmdlets\Test\1\file2

If you don't have windows powershell profile file, follow the below steps to create a new one and add "Add-PSSnapin FindChildItemPSSnapIn01" entry to it


PS C:\Users\Jagadish\Desktop\Find-ChildItem> New-Item $profile -ItemType file -Force ; Write-Output "Add-PSSnapin FindChildItemPSSnapIn01" > $profile

Directory: C:\Users\Jagadish\Documents\WindowsPowerShell

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 6/8/2009 6:28 PM 0 Microsoft.PowerShell_profile.ps1


That's it. You added the Add-Snapin entry permanently. Now, Lets have some fun with new Find-ChildItem Cmdlet

List all the files and directories in the current directory


PS G:\Jagadish\Test> Find-ChildItem
G:\Jagadish\Test\Docs
G:\Jagadish\Test\Docs\101_Popular_Interview_Questions.doc
G:\Jagadish\Test\Docs\echosend_1500.c
G:\Jagadish\Test\Downloads
G:\Jagadish\Test\Downloads\VLC
G:\Jagadish\Test\Downloads\VLC\vlc-0.8.6-win32.exe
G:\Jagadish\Test\Downloads\VLC\vlc_src-0.8.5.tar.gz
G:\Jagadish\Test\Downloads\ethereal-setup-0.10.13.exe
G:\Jagadish\Test\Downloads\TeamViewer_Setup.exe
G:\Jagadish\Test\Songs
G:\Jagadish\Test\Songs\Green Day
G:\Jagadish\Test\Songs\Green Day\American Idiot- Boulevard Of Broken Dreams.mp3
G:\Jagadish\Test\Songs\akon-sorry.mp3
G:\Jagadish\Test\msvcp71.dll
PS G:\Jagadish\Test>

List ".exe" files only


PS G:\Jagadish\Test> Find-ChildItem -Type f -Name ".*.exe"
G:\Jagadish\Test\Downloads\VLC\vlc-0.8.6-win32.exe
G:\Jagadish\Test\Downloads\ethereal-setup-0.10.13.exe
G:\Jagadish\Test\Downloads\TeamViewer_Setup.exe
PS G:\Jagadish\Test>

Search for ".c" files only and display no of lines, words, characters in that file


PS G:\Jagadish\Test> Find-ChildItem -Type f -Name "\.c$" -Exec "Get-Content {} | Measure-Object -Line -Character -Word"

Lines Words Characters Property
----- ----- ---------- --------
162 500 3703

PS G:\Jagadish\Test>

You can use the below command to find Empty files in a directory and its sub directories


PS E:\Jagadish\Test> Find-ChildItem -Type f -Empty
E:\Jagadish\Test\Docs\Attachment
E:\Jagadish\Test\Docs\Report.txt
E:\Jagadish\Test\Docs\sample_logs
E:\Jagadish\Test\testing

Use -OutObject parameter to write file objects to powershell


PS E:\Jagadish\Test> Find-ChildItem -Type f -Empty -OutObject

Directory: Microsoft.PowerShell.Core\FileSystem::E:\Jagadish\Test\Docs

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 8/11/2009 10:16 PM 0 Attachment
-a--- 8/11/2009 10:16 PM 0 Report.txt
-a--- 8/11/2009 10:16 PM 0 sample_logs

Directory: Microsoft.PowerShell.Core\FileSystem::E:\Jagadish\Test

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 8/11/2009 10:16 PM 0 testing

Now, If we want to delete all the empty files, we can easily do that with the help of Find-ChildItem cmdlet
Find-ChildItem -Type f -Empty -Delete


PS E:\Jagadish\Test> Find-ChildItem -Type f -Empty -Delete
PS E:\Jagadish\Test> Find-ChildItem -Type f -Empty -OutObject
PS E:\Jagadish\Test>

Now, list all the files with size greater than 9 MB


PS E:\Jagadish\Test> Find-ChildItem -Type f -Size +9M -OutObject

Directory: Microsoft.PowerShell.Core\FileSystem::E:\Jagadish\Test\Downloads\VLC

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 12/13/2006 3:26 PM 9451515 vlc-0.8.6-win32.exe
-a--- 1/25/2007 3:00 PM 81510400 vlc-binary-fc4.tar.gz
-a--- 7/7/2006 5:46 PM 15680081 vlc-binary.tar.gz
-a--- 11/8/2006 5:45 PM 12461262 vlc_src-0.8.5.tar.gz

Directory: Microsoft.PowerShell.Core\FileSystem::E:\Jagadish\Test\Downloads

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 11/9/2006 7:24 PM 11348769 ethereal-setup-0.10.13.exe

If you want more details and usage information on this Find-ChildItem Cmdlet, type Get-Help Find-ChildItem -Full in your Powershell

Let me know if you need any other information or if you encounter any bugs/issues with Find-ChildItem Cmdlet

10 comments:

  1. Incredible tutorial..You explained everything in very detailed with good examples. This is what I was searching. There are lot of doubts that I cleared through this blog..Thank you very much !

    ReplyDelete
  2. I think i am here by chance, but it is a good luck to me. I was trying to find some latest stuff from google and by chance I am here.

    ReplyDelete
  3. Hi Jagadish, would i be able to use this command to find files from remote systems as well ? or would this work only on a single system?

    Would love to hear back form you asap.

    ReplyDelete
  4. Jay,

    Yep, it works with remote systems as well!

    ReplyDelete
  5. I stumbled upon this and really like it. I have added it to my computer and will continue to use it as long as I use PowerShell. I like it so much that I posted a link to this page on my blog!

    Thanks so much!

    ReplyDelete
  6. Nice tool, and really good documentation. I do however frequently stumble upon this error quite often :

    At line:1 char:15
    + Find-ChildItem <<<< -Name "putty.exe"
    + CategoryInfo : NotSpecified: (:) [Find-ChildItem], PathTooLongException
    + FullyQualifiedErrorId : System.IO.PathTooLongException,Microsoft.Powershell.Commands.FindChildItemCommand

    ReplyDelete
  7. Hello,

    I have this error during my commandline : $results = (Find-ChildItem $LetterMap -Type f -size +9M -outobject )

    Find-ChildItem : The specified network name is no longer available.

    But the directory stay online.

    ReplyDelete
  8. Do you have this for PS version 3.0?

    ReplyDelete
  9. It looks like the dll is compiled for win8, as it loads api-ms-win-appmodel-runtime-L1-1-0.dll, which is not present on windows 7. No luck for us, win7 users.

    ReplyDelete
  10. Hello,

    i have 2 problems with this very good add-on.

    First:
    I have a script with more than 400lines like this
    "
    Find-ChildItem \\NUFS011\MIPS\Nutrac\n_vera4\result2 -Name 0102617* -Exec "mv -path {} -destination \\NUFS010\MIPSARCH\Nutrac\saved_Tags\0102\010261\0102617";
    Find-ChildItem \\NUFS011\MIPS\Nutrac\n_vera4\result2 -Name 0102618* -Exec "mv -path {} -destination \\NUFS010\MIPSARCH\Nutrac\saved_Tags\0102\010261\0102618";
    Find-ChildItem \\NUFS011\MIPS\Nutrac\n_vera4\result2 -Name 0102619* -Exec "mv -path {} -destination \\NUFS010\MIPSARCH\Nutrac\saved_Tags\0102\010261\0102619";
    Find-ChildItem \\NUFS011\MIPS\Nutrac\n_vera4\result2 -Name 0102620* -Exec "mv -path {} -destination \\NUFS010\MIPSARCH\Nutrac\saved_Tags\0102\010262\0102620";
    "
    the script works but the destination after moving Files are wrong. All Files are moved into one Directory.

    Second:
    If the Destination File are exist, it was replaced with the new File. I need all File the old and the new one. Have you any Idea about this ?


    Best Regards
    Richard

    ReplyDelete