none
Powershell v4: Удаление пустых каталогов. RRS feed

  • Вопрос

  • Доброго времени суток.

    Удаление пустых каталогов с игнорированием заданных каталогов $NoDelFolder (даже если они пустые):

    param(
        [parameter(Mandatory = $true)]
        $TargetFolder,
        [parameter(Mandatory = $true)]
        [string[]]$NoDelFolder
         )
    $EmptyFolders = Get-ChildItem $TargetFolder -Directory -Recurse | Where-Object {((Get-ChildItem -Path $_.FullName -Recurse) -eq $null) -and ($NoDelFolder -notcontains $_.FullName)}
    foreach ($EmptyFolder in $EmptyFolders)
        {
        "Удаляю пустой каталог $($EmptyFolder.FullName)" | Out-File $ReportName -Append
        Remove-Item $EmptyFolder.FullName | Out-Null
        }

    Вывод в файл - чтобы я знал какие каталоги были удалены, т.к. скрипт запускается в планировщике задач.

    Проблема в том, что каталоги верхнего уровня не добавляются в $EmptyFolders, т.к. содержат другие папки, хоть и пустые, и при первом проходе не удаляются. Если использовать условие

    {((Get-ChildItem -Path $_.FullName -Recurse -File) -eq $null) -and ($NoDelFolder -notcontains $_.FullName)}

    То удалять начинает даже те каталоги, которые входят в $NoDelFolder.

    Какое условие задать циклу, чтобы он совершал проходы до тех пор, пока не будут удалены все пустые каталоги, кроме входящих в $NoDelFolders?

    18 декабря 2014 г. 5:53

Ответы

  • [string[]]$NoDelFolder = "E:\Startx\3","E:\Startx\stat\6"
    $Folders = Get-ChildItem "E:\Startx" -Directory -Recurse | Sort {$_.FullName.Length} -Descending 
    
    Function IsExclude($Folder) {
    	!($NoDelFolder | Where {$_.Contains($folder)})
    }
    
    foreach ($Folder in $Folders)
    {
    	if ((Get-ChildItem -Path $Folder.FullName -Recurse) -eq $null -and (IsExclude $Folder.FullName))
        {
    		"Удаляю пустой каталог $($Folder.FullName)" | Out-File "G:\Utilization\Reports\DelCycleFolder.txt" -Append
    		Remove-Item $Folder.FullName | Out-Null
    	}
    }


    18 декабря 2014 г. 13:44
    Отвечающий

Все ответы

  • Get-ChildItem $TargetFolder -Directory -Recurse | Sort {$_.FullName.Length} -Descending | Where ......
    18 декабря 2014 г. 6:02
    Отвечающий
  • Спасибо за ответ.

    Результат тот же самый. Независимо от сортировки по длине, старшие каталоги не помещаются в $EmptyFolders, а цикл работает только для $EmptyFolder из $EmptyFolders.

    18 декабря 2014 г. 6:23
  • Единственным выходом вижу написание своей рекурсивно вызываемой функции.


    Microsoft Certified Doing Nothing Expert

    18 декабря 2014 г. 7:04
  • Спасибо за ответ. Ссылку еще не смотрел, но сделал так:

    [string[]]$NoDelFolder = "E:\Startx\3","E:\Startx\stat\6"
    $EmptyFolders = Get-ChildItem "E:\Startx" -Directory -Recurse | Sort {$_.FullName.Length} -Descending # | Where-Object {((Get-ChildItem -Path $_.FullName -Recurse <#-File#>) -eq $null) -and ($NoDelFolder -notcontains $_.FullName)}
    foreach ($EmptyFolder in $EmptyFolders)
        {
        if (((Get-ChildItem -Path $EmptyFolder.FullName -Recurse <#-File#>) -eq $null) -and ($NoDelFolder -notcontains $EmptyFolder.FullName))
            {
            "Удаляю пустой каталог $($EmptyFolder.FullName)" | Out-File "G:\Utilization\Reports\DelCycleFolder.txt" -Append
            Remove-Item $EmptyFolder.FullName | Out-Null
            }
        else 
            {
            "do nothing" | Out-File "G:\Utilization\Reports\DelCycleFolder.txt" -Append
            }
        }
    
    Удаляет все. Может я чего-то не учел и будут подводные камни?

    18 декабря 2014 г. 7:38
  • -File параметр стоит включить, т.к. если файлы есть, то оставить папку и тем самым исключить пустые подпапки.


    • Изменено KazunEditor 18 декабря 2014 г. 7:58
    18 декабря 2014 г. 7:57
    Отвечающий
  • Не понял, зачем параметр -File, я же ищу только каталоги?

    (Get-ChildItem -Path $EmptyFolder.FullName -Recurse) -eq $null
    Ведь уже предполагает что файлов нет.

    18 декабря 2014 г. 8:52
  • Не понял, зачем параметр -File, я же ищу только каталоги?

    (Get-ChildItem -Path $EmptyFolder.FullName -Recurse) -eq $null
    Ведь уже предполагает что файлов нет.

    Если папка, содержит пустые подпапки, то она уже не считается пустой, а вот если указать файлы, то она попадет под условие.
    18 декабря 2014 г. 9:37
    Отвечающий
  • Если указать -File, то выдается сообщение: E:\startx\stat имеет дочерние объекты и параметр Recurse не указан. При продолжении все дочерние объекты будут удалены вместе с элементом.

    И при продолжении удаляются все каталоги, даже если они заданы в $NoDelFolder.

    18 декабря 2014 г. 11:16
  • [string[]]$NoDelFolder = "E:\Startx\3","E:\Startx\stat\6"
    $Folders = Get-ChildItem "E:\Startx" -Directory -Recurse | Sort {$_.FullName.Length} -Descending 
    
    Function IsExclude($Folder) {
    	!($NoDelFolder | Where {$_.Contains($folder)})
    }
    
    foreach ($Folder in $Folders)
    {
    	if ((Get-ChildItem -Path $Folder.FullName -Recurse) -eq $null -and (IsExclude $Folder.FullName))
        {
    		"Удаляю пустой каталог $($Folder.FullName)" | Out-File "G:\Utilization\Reports\DelCycleFolder.txt" -Append
    		Remove-Item $Folder.FullName | Out-Null
    	}
    }


    18 декабря 2014 г. 13:44
    Отвечающий