none
Remove Empty Folders by name RRS feed

  • Question

  • Hi guys!

    i must remove all empty folders in my PC.

    Each folder can be removed only if folder start-name is not 0 or 1 or scan.

    Examples:

    C:\Scan --> keep

    C:\Scan\Try -->delete try and subfolders, keep scan

    C:\Scan\0-Try --> keep all

    C:\Try -->delete all

    C:\Try\1-This\2-That -->delete only 2-that 

    i made this code:

    function Move-EmptyDir{
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $true)][string]$Source,
            [Parameter(Mandatory = $true)][string]$Destination,
            [ValidateNotNullOrEmpty()][regex]$NoMatch
        )
    
        $EmptyFolders=@()
        $AllFolders= (Dir $Source -Force -Recurse) | Where-Object{$_.Attributes -match "Directory"}
        $ExistFolders= $AllFolders | Group-Object -Property Exists | Where-Object{$_.Name -match "True"}
        Foreach($Item in $ExistFolders.Group){
            $MeltinCount= $Item.GetFileSystemInfos().count #se 0 non ha elementi
            $SimCount= (($ExistFolders.Group | Group-Object -Property Parent) | Where-Object{$_.Name -eq $Item.Name}).Count #0=no subfolders
            if($MeltinCount -eq $SimCount){
                $EmptyFolders+= $Item
            }
        }
    
        $Moved= @()
        $Moving= $EmptyFolders.Length -1
        
        While($Moving -ne -1){
            $OneFolder= $EmptyFolders[$Moving]
            if($OneFolder.GetFileSystemInfos().count -gt 0){
                Write-Warning "This Folder $OneFolder is not empty"
                $Moving--
            }
            elseif($OneFolder.Name -match $NoMatch){
                Write-Warning "The Folder $OneFolder Match the Exceptions"
                $Moving--
            }
            elseif($OneFolder.Parent.Name -match $NoMatch){
                Write-Host "The Parent Folder of $OneFolder Match the Exceptions" -BackgroundColor Green
                $Moved += $OneFolder
                $Place = $OneFolder.FullName -replace "^$([regex]::Escape($Source))", $Destination
                if((Test-Path $Place) -eq $false){
                    New-Item -Path $Place -ItemType Directory
                    Remove-Item -Path $OneFolder.fullname -Force -ErrorAction SilentlyContinue
                    Write-Verbose ('Moved folder "{0}" to "{1}"' -f $OneFolder.FullName, $Place)
                    $Moving --
                }
                else{
                    Remove-Item -Path $OneFolder.FullName -Force -ErrorAction SilentlyContinue
                    $Moving --
                }
            }
            else{
                $Moved += $OneFolder
                $Place = $OneFolder.FullName -replace "^$([regex]::Escape($Source))", $Destination
                if((Test-Path $Place) -eq $false){
                    New-Item -Path $Place -ItemType Directory
                    Remove-Item -Path $OneFolder.fullname -Force -ErrorAction SilentlyContinue
                    Write-Verbose ('Moved folder "{0}" to "{1}"' -f $OneFolder.FullName, $Place)
                    $Moving --
                }
                else{
                    Remove-Item -Path $OneFolder.fullname -Force -ErrorAction SilentlyContinue
                }
                $Moving --
            }
            return $Moved
        }
    }
    
    $Where= 'C:\temp'
    $ToGo= 'C:\estinto'
    $MatchList= '0','1','8','9','Scansion'
    $Kind= 'Empty'
    if(Test-Path $Where){
        #$TheMatch = Select-Match -FullList $MatchList
        $Folders = Move-EmptyDir -Source $Where -Destination $ToGo -NoMatch 'F' -Verbose
        $Drives = ForEach($Item in $Folders){
            Select-Object -Property @(
                @{ Name = 'Name'; Expression = { $Item.Name } }
                @{ Name = 'Percorso'; Expression = { $Item.Parent.FullName } }
            )
        }
        #Get-Report $Drives $Kind
    }
    else{
        Write-Error 'Invalid Path' -Category ResourceUnavailable
    }

    with powershell v4 can you do somthing better?

    Thanks

    A

    Tuesday, July 8, 2014 11:29 AM

Answers

  • Gastone.  Works fine for me in Windows 7.  That has always worked.  The bit that most are missing is that we need to do what I did to make it work.

    dir c:\temp\* -exclude 1*,0*,scan* -directory

    Notice the * at the end of the folder path. Without that the exclude won't work.

    Only Windows XP cannot run  this code.


    ¯\_(ツ)_/¯


    • Edited by jrv Wednesday, July 9, 2014 9:32 PM
    • Marked as answer by Albiz Thursday, July 17, 2014 7:18 AM
    Wednesday, July 9, 2014 9:32 PM

All replies

  • There are many empty folders on a PC that are required for it to run.  You cannot remove them.  What you are attempting is very dangerous.

    Why do you think you need to do this?

    What is your question?  You have posted a lot of script but the question is not clear.

    It appears that you are asking for someone to write a better solution. Why?  If this works; why?

    What problem are you trying to solve?


    ¯\_(ツ)_/¯

    Tuesday, July 8, 2014 1:32 PM
  • As far as reducing the amount of code start with this:

    #return all folders that match name rules
    dir c:\temp\* -exclude 1*,0*,scan* -directory


    ¯\_(ツ)_/¯

    Tuesday, July 8, 2014 1:36 PM
  • $startDir= "c:\temp\t"
    #powershell 2.0
    # to do: remove the recursion and its elegance (iteractive more efficient) function is-empty ([string]$folder) { ([bool](dir $_.fullname -Force) -eq $false) } function del-emptydir ($root){ cd $root dir | ? { $_.PSIsContainer } |% { del-emptydir -root $_.fullname } if ( is-empty -Folder $_.fullname) { cd .. # use reg exp to exclude folders if ((is-empty -Folder $_.fullname) -and (-not ($_ -imatch "^scan.*|^0.*|^1.*"))) { #remove the echo if you want delete something echo del $_.fullname } } } cls del-emptydir -root $startDir
    try this

    Gastone Canali >http://www.armadillo.it

    Se alcuni post rispondono al tuo quesito(non necessariamente i miei), ricorda di contrassegnarli come risposta e non dimenticare di contrassegnare anche i post utili. GRAZIE! Ricorda di dare un occhio ai link Click Here andHere



    Tuesday, July 8, 2014 11:52 PM
  • Hi jrv!

    This problem is not dangerous for me because when i will run the code the parent of my folders will be D:\ while the system folders are C:\....
    The code is wrote with powershell v2/v3; now i've got v4 so maybe there are some new cmdlets that help me to improve the code.
    I hope that someone like you tell me something new

    Thanks

    A

    Wednesday, July 9, 2014 8:18 AM
  • Hi Gastone!

    Even if both of us speak italian it's better if i reply you in english.

    I try your code in this way:

    i've created some folders that are matching conditions and same that are not matching conditions;  your code clear the right folders!

    Thanks

    A

    P.S.:I need to create a report of all deleted folders with the function get-report but i don't know how to create a variable with all deleted folders in a recursive function; any suggestion?
    • Edited by Albiz Wednesday, July 9, 2014 8:42 AM
    Wednesday, July 9, 2014 8:37 AM
  • As far as reducing the amount of code start with this:

    #return all folders that match name rules
    dir c:\temp\* -exclude 1*,0*,scan* -directory


    ¯\_(ツ)_/¯

    $Folders=Get-ChildItemD:\-Recurse-Directory-Exclude0*,1*,2*,8*,9*,scan*-ErrorActionSilentlyContinue


    $EmptyFolders

    =$Folders|Where-Object{$_.GetFileSystemInfos().Count -eq0} -ErrorActionSilentlyContinue


    $EmptyFoldersFullname

    =$EmptyFolders|Group-Object-PropertyFullname


     


    Get-Report

    $EmptyFoldersFullname.Group "Empty"

    DONE!
    Wednesday, July 9, 2014 11:10 AM
  • As far as reducing the amount of code start with this:

    #return all folders that match name rules
    dir c:\temp\* -exclude 1*,0*,scan* -directory


    ¯\_(ツ)_/¯


    With this approach, the folder inside the excluded folder 1*,0*,scan*  will not checked... this is the reason why my code  not use the -exclude ...,  but a plain  dir | ? {$_.PSIsContainer } |% { ...
    ex.: c:\temp\scanner\willbeempty\onlyonedir\onlyonedir

    I don't use the -directory so the script will run with the "older" powershell version (example in window 7), I don't know all the new features, are too much for me, not for James, he is one step ahead!

    For the report change the line

    #remove the echo if you want delete something
    	   echo del $_.fullname

    adding something like

    #remove the echo if you want delete something echo del $_.fullname
    get-report
     $_.fullname 'Empty'


    Ciao Gas



    Gastone Canali >http://www.armadillo.it

    Se alcuni post rispondono al tuo quesito(non necessariamente i miei), ricorda di contrassegnarli come risposta e non dimenticare di contrassegnare anche i post utili. GRAZIE! Ricorda di dare un occhio ai link Click Here andHere

    Wednesday, July 9, 2014 9:17 PM
  • Gastone.  Works fine for me in Windows 7.  That has always worked.  The bit that most are missing is that we need to do what I did to make it work.

    dir c:\temp\* -exclude 1*,0*,scan* -directory

    Notice the * at the end of the folder path. Without that the exclude won't work.

    Only Windows XP cannot run  this code.


    ¯\_(ツ)_/¯


    • Edited by jrv Wednesday, July 9, 2014 9:32 PM
    • Marked as answer by Albiz Thursday, July 17, 2014 7:18 AM
    Wednesday, July 9, 2014 9:32 PM
  • Gastone.  Works fine for me in Windows 7.  That has always worked.  The bit that most are missing is that we need to do what I did to make it work.

    dir c:\temp\* -exclude 1*,0*,scan* -directory

    Notice the * at the end of the folder path. Without that the exclude won't work.

    Only Windows XP cannot run  this code.


    ¯\_(ツ)_/¯


    Sorry James, but the -directory options in gci cmdlet is available with powershell >= 3.0  !

    http://blogs.technet.com/b/heyscriptingguy/archive/2013/06/02/weekend-scripter-install-powershell-3-0-on-windows-7.aspx

    Probably J. Snower understood that POWERshell wasn't able to do the simple sys admin tasks like dos/unix dir /ad or   ls -d */

    http://blogs.msdn.com/b/powershell/archive/2006/06/24/645000.aspx

    Bye Gas

    C:\Users\g>PowerShell.exe -Version 2.0
    Windows PowerShell
    Copyright (C) 2009 Microsoft Corporation. All rights reserved.

    PS C:\Users\g> $PSVersionTable.PSVersion

    Major  Minor  Build  Revision
    -----  -----  -----  --------
    2      0      -1     -1

    PS C:\Users\g> dir c:\temp\* -exclude 1*,0*,scan* -directory
    dir : A parameter cannot be found that matches parameter name 'directory'.
    At line:1 char:46
    + dir c:\temp\* -exclude 1*,0*,scan* -directory <<<<
        + CategoryInfo          : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException
        + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

    PS C:\Users\g> PowerShell.exe -Version 3.0
    Windows PowerShell
    Copyright (C) 2013 Microsoft Corporation. Tutti i diritti riservati.

    PS C:\Users\g> dir c:\temp\* -exclude 1*,0*,scan* -directory

        Directory: C:\temp\ata

    Mode                LastWriteTime     Length Name
    ----                -------------     ------ ----
    d----        01/03/2013     15:50            Nuova cartella


    Gastone Canali >http://www.armadillo.it

    Se alcuni post rispondono al tuo quesito(non necessariamente i miei), ricorda di contrassegnarli come risposta e non dimenticare di contrassegnare anche i post utili. GRAZIE! Ricorda di dare un occhio ai link Click Here andHere


    Thursday, July 10, 2014 10:27 PM
  • Windows 7 and later is PowerShell V3.

    Windows 7 upgraded PowerShell over two years ago.

    The OP asked this question: "with powershell v4 can you do somthing better?"

    The assumption is that we are using V4 so my solution 2was what was asked for.  It is at the bottom of the original post.  Use -Directory is very much easier and faster than using "PsIsCOntainer".

    So Gastone...can we use my code now please?


    ¯\_(ツ)_/¯

    • Marked as answer by Albiz Thursday, July 17, 2014 7:18 AM
    • Unmarked as answer by Albiz Thursday, July 17, 2014 7:18 AM
    Thursday, July 10, 2014 10:37 PM
  • #remove the echo if you want delete something echo del $_.fullname
    get-report  $_.fullname 'Empty'


    Hi gas!

    if i use get-report in that place as you wrote i'll not have a report of all empty folders because your script is recursive.

    Usually to use my get-report i do "Group-objects -property Fullname" as you can see in $emptyFoldersFullname

     

    Second Thing  as you can see the non recursive script works fine for me

    Ciao

    A


    • Edited by Albiz Friday, July 11, 2014 7:09 AM
    Friday, July 11, 2014 7:02 AM