Jak usunąć puste podfoldery za pomocą PowerShell?

Mam udział, który jest "szufladą śmieci" dla użytkowników końcowych. Mogą tworzyć foldery i podfoldery według własnego uznania. Muszę wdrożyć skrypt, aby usunąć pliki utworzone więcej niż 31 dni.

Zacząłem od Powershell. Muszę śledzić skrypt usuwania plików, usuwając podfoldery, które są teraz puste. Z powodu zagnieżdżania podfolderów, muszę unikać usuwania podfolderu, który jest pusty z plikami, ale ma podfolder pod nim, który zawiera plik.

Na przykład:

  • FILE3a mA 10 dni. Ma 45 dni.
  • chcę wyczyścić strukturę usuwając pliki starsze niż 30 dni i usunąć puste podfoldery.
C:\Junk\subfolder1a\subfolder2a\FILE3a

C:\Junk\subfolder1a\subfolder2a\subfolder3a

C:\Junk\subfolder1a\subfolder2B\FILE3b

Pożądany wynik:

  • Usuń: FILE3b, subfolder2B & subfolder3a.
  • zostawić: subfolder1a, subfolder2a, i FILE3a.

Mogę rekurencyjnie wyczyścić pliki. Jak wyczyścić podfoldery bez usuwania subfolder1a? (Folder "śmieci" będzie zawsze / align = "left" / )

Author: Tshepang, 2009-10-16

7 answers

Zrobiłbym to w dwóch przebiegach-najpierw kasowanie starych plików, a potem pustych dirs:

Get-ChildItem -recurse | Where {!$_.PSIsContainer -and `
$_.LastWriteTime -lt (get-date).AddDays(-31)} | Remove-Item -whatif

Get-ChildItem -recurse | Where {$_.PSIsContainer -and `
@(Get-ChildItem -Lit $_.Fullname -r | Where {!$_.PSIsContainer}).Length -eq 0} |
Remove-Item -recurse -whatif

Ten typ operacji demonstruje moc zagnieżdżonych potoków w PowerShell, którą demonstruje drugi zestaw poleceń. Używa zagnieżdżonego potoku do rekurencyjnego określenia, czy jakikolwiek katalog ma zerowe pliki pod nim.

 42
Author: Keith Hill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-22 15:13:29

W duchu pierwszej odpowiedzi, oto najkrótszy sposób na usunięcie pustych katalogów:

ls -recurse | where {!@(ls -force $_.fullname)} | rm -whatif

Flaga-force jest potrzebna w przypadku, gdy katalogi mają ukryte foldery, np.svn

 9
Author: Bogdan Calmac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-20 18:29:46

Spowoduje sortowanie podkatalogów przed katalogami nadrzędnymi pracującymi wokół problemu pustego zagnieżdżonego katalogu.

dir -Directory -Recurse |
    %{ $_.FullName} |
    sort -Descending |
    where { !@(ls -force $_) } |
    rm -WhatIf
 4
Author: Doug Coburn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-17 16:23:25

Dodanie do ostatniego:

while (Get-ChildItem $StartingPoint -recurse | where {!@(Get-ChildItem -force $_.fullname)} | Test-Path) {
    Get-ChildItem $StartingPoint -recurse | where {!@(Get-ChildItem -force $_.fullname)} | Remove-Item
}

To sprawi, że będzie on kompletny, gdzie będzie kontynuował wyszukiwanie, aby usunąć puste foldery pod $StartingPoint

 3
Author: bbo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-15 14:47:38

Potrzebowałem pewnych funkcji przyjaznych dla przedsiębiorstw. Oto moje ujęcie.

Zacząłem od kodu z innych odpowiedzi, a następnie dodałem plik JSON z oryginalną listą folderów (łącznie z liczbą plików na folder). Usunąłem puste katalogi i zapisałem je.

Https://gist.github.com/yzorg/e92c5eb60e97b1d6381b

param (
    [switch]$Clear
)

# if you want to reload a previous file list
#$stat = ConvertFrom-Json (gc dir-cleanup-filecount-by-directory.json -join "`n")

if ($Clear) { 
    $stat = @() 
} elseif ($stat.Count -ne 0 -and (-not "$($stat[0].DirPath)".StartsWith($PWD.ProviderPath))) {
    Write-Warning "Path changed, clearing cached file list."
    Read-Host -Prompt 'Press -Enter-'
    $stat = @() 
}

$lineCount = 0
if ($stat.Count -eq 0) {
    $stat = gci -Recurse -Directory | %{  # -Exclude 'Visual Studio 2013' # test in 'Documents' folder

        if (++$lineCount % 100 -eq 0) { Write-Warning "file count $lineCount" }

        New-Object psobject -Property @{ 
            DirPath=$_.FullName; 
            DirPathLength=$_.FullName.Length;
            FileCount=($_ | gci -Force -File).Count; 
            DirCount=($_ | gci -Force -Directory).Count
        }
    }
    $stat | ConvertTo-Json | Out-File dir-cleanup-filecount-by-directory.json -Verbose
}

$delelteListTxt = 'dir-cleanup-emptydirs-{0}-{1}.txt' -f ((date -f s) -replace '[-:]','' -replace 'T','_'),$env:USERNAME

$stat | 
    ? FileCount -eq 0 | 
    sort -property @{Expression="DirPathLength";Descending=$true}, @{Expression="DirPath";Descending=$false} |
    select -ExpandProperty DirPath | #-First 10 | 
    ?{ @(gci $_ -Force).Count -eq 0 } | %{
        Remove-Item $_ -Verbose # -WhatIf  # uncomment to see the first pass of folders to be cleaned**
        $_ | Out-File -Append -Encoding utf8 $delelteListTxt
        sleep 0.1
    }

# ** - The list you'll see from -WhatIf isn't a complete list because parent folders
#      might also qualify after the first level is cleaned.  The -WhatIf list will 
#      show correct breath, which is what I want to see before running the command.
 2
Author: yzorg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-14 16:59:18

Aby usunąć Pliki starsze niż 30 dni:

get-childitem -recurse |
    ? {$_.GetType() -match "FileInfo"} |
    ?{ $_.LastWriteTime -lt [datetime]::now.adddays(-30) }  |
    rm -whatif

(po prostu usuń -whatif, aby rzeczywiście wykonać.)

Kontynuuj z:

 get-childitem -recurse |
     ? {$_.GetType() -match "DirectoryInfo"} |
     ?{ $_.GetFiles().Count -eq 0 -and $_.GetDirectories().Count -eq 0 } |
     rm -whatif
 2
Author: John Weldon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-14 19:01:55

To mi pomogło.

$limit = (Get-Date).AddDays(-15) 

$path = "C:\Some\Path"

Usuń pliki starsze niż $limit:

Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force

Usuń wszystkie puste katalogi pozostawione po usunięciu starych plików:

Get-ChildItem -Path $path -Recurse -Force | Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer }) -eq $null } | Remove-Item -Force -Recurse
 1
Author: ritikaadit2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-17 14:10:32