Лучший отвечающий
PowerShell Исключение нескольких папок с файлами из операции удаления файлов старше N дней

Вопрос
-
Всем здравствуйте!
Когда то на просторах интернета был найден скрипт для удаление старых фалов на файловой помойке, выглядит он так:
$TargetDelNt = "D:\1" #путь до папки шары $Del = "-3" #Количество хранимых дней $CurrentDay = Get-Date $ChDaysDel = $CurrentDay.AddDays($Del) #Удаление файлов, дата создания которых больше 3 дней GCI -Path $TargetDelNt -Recurse | Where-Object {$_.CreationTime -LT $ChDaysDel} | RI -Recurse -Force #Удаление пустых папок GCI -Path $TargetDelNt -Recurse | Where-Object { $_.PSIsContainer -and @(Get-ChildItem -Path $_.Fullname -Recurse | Where { -not $_.PSIsContainer }).Count -eq 0 } | RI -Recurse
Этот скрипт работает все отлично.
Но, появилась задача исключить несколько папок, так что бы скрипт не удалял конкретные папки и все что в них находиться.
Попробовал сделать следующим образом:$TargetDelNt = "D:\1" #путь до папки шары $Del = "-3" #Количество хранимых дней $CurrentDay = Get-Date $ChDaysDel = $CurrentDay.AddDays($Del) $Path1 = "D:\1\Не удалять" #Папка которую нужно исключить $Files1 = Get-ChildItem -Path $Path1 -Recurse #Собираю в переменную все что находиться в папке #Удаление файлов, дата создания которых больше 3 дней # Значением Exclude предотвращаю удаление нажных файлов GCI -Path $TargetDelNt -Recurse -Exclude $Files1 | Where-Object {$_.CreationTime -LT $ChDaysDel} | RI -Recurse -Force #Удаление пустых папок GCI -Path $TargetDelNt -Recurse | Where-Object { $_.PSIsContainer -and @(Get-ChildItem -Path $_.Fullname -Recurse | Where { -not $_.PSIsContainer }).Count -eq 0 } | RI -Recurse
проблема последнего скрипта в том, что если в другой папке попадется файл название которого совпадает с файлом лежащим в папке исключения, то скрипт его не удалит.
Вот в чем вопрос, как же сделать так, чтобы скрипт не трогал только конкретную папку и все что в ней находится?18 апреля 2016 г. 6:32
Ответы
-
$folders = "C:\Folder1\T1","C:\Folder2\T2" GCI -Path $TargetDelNt -Recurse | Where { $folder = $_.FullName !($folders | Where {$folder.Contains($_)}) } | Where-Object {$_.CreationTime -LT $ChDaysDel} | RI -Recurse -Force
- Предложено в качестве ответа KazunEditor 18 апреля 2016 г. 6:50
- Отменено предложение в качестве ответа KazunEditor 18 апреля 2016 г. 6:50
- Изменено KazunEditor 18 апреля 2016 г. 6:51
- Помечено в качестве ответа KazunEditor 18 апреля 2016 г. 8:56
18 апреля 2016 г. 6:43Отвечающий -
1 Попробуйте в Exclude запихнуть не файлы, а ваш путь только в конце добавьте слеш
$Path1 = "D:\1\Не удалять\" #Папка которую нужно исключить #Удаление файлов, дата создания которых больше 3 дней # Значением Exclude предотвращаю удаление нажных файлов GCI -Path $TargetDelNt -Recurse -Exclude $Path1 | Where-Object {$_.CreationTime -LT $ChDaysDel} | RI -Recurse -Force
2 можно любое количество фильтров впихнуть в Where
$Path1 = "D:\1\Не удалять" #Папка которую нужно исключить #Удаление файлов, дата создания которых больше 3 дней # Значением Exclude предотвращаю удаление нажных файлов GCI -Path $TargetDelNt -Recurse | Where-Object {($_.CreationTime -LT $ChDaysDel) -and ($_.Directory -ne $Path1)} | RI -Recurse -Force
The opinion expressed by me is not an official position of Microsoft
- Помечено в качестве ответа KazunEditor 18 апреля 2016 г. 8:56
18 апреля 2016 г. 6:47Модератор
Все ответы
-
$folders = "C:\Folder1\T1","C:\Folder2\T2" GCI -Path $TargetDelNt -Recurse | Where { $folder = $_.FullName !($folders | Where {$folder.Contains($_)}) } | Where-Object {$_.CreationTime -LT $ChDaysDel} | RI -Recurse -Force
- Предложено в качестве ответа KazunEditor 18 апреля 2016 г. 6:50
- Отменено предложение в качестве ответа KazunEditor 18 апреля 2016 г. 6:50
- Изменено KazunEditor 18 апреля 2016 г. 6:51
- Помечено в качестве ответа KazunEditor 18 апреля 2016 г. 8:56
18 апреля 2016 г. 6:43Отвечающий -
1 Попробуйте в Exclude запихнуть не файлы, а ваш путь только в конце добавьте слеш
$Path1 = "D:\1\Не удалять\" #Папка которую нужно исключить #Удаление файлов, дата создания которых больше 3 дней # Значением Exclude предотвращаю удаление нажных файлов GCI -Path $TargetDelNt -Recurse -Exclude $Path1 | Where-Object {$_.CreationTime -LT $ChDaysDel} | RI -Recurse -Force
2 можно любое количество фильтров впихнуть в Where
$Path1 = "D:\1\Не удалять" #Папка которую нужно исключить #Удаление файлов, дата создания которых больше 3 дней # Значением Exclude предотвращаю удаление нажных файлов GCI -Path $TargetDelNt -Recurse | Where-Object {($_.CreationTime -LT $ChDaysDel) -and ($_.Directory -ne $Path1)} | RI -Recurse -Force
The opinion expressed by me is not an official position of Microsoft
- Помечено в качестве ответа KazunEditor 18 апреля 2016 г. 8:56
18 апреля 2016 г. 6:47Модератор -
Не работает ни в одном случае. Файлы старше 3 дней удаляются(18 апреля 2016 г. 7:12
-
$folders = "C:\Folder1\T1","C:\Folder2\T2" GCI -Path $TargetDelNt -Recurse | Where { $folder = $_.FullName !($folders | Where {$folder.Contains($_)}) } | Where-Object {$_.CreationTime -LT $ChDaysDel} | RI -Recurse -Force
Не работает(
18 апреля 2016 г. 7:12 -
Показывайте вывод, где попадают папки, которые должны быть исключены:
$folders = "C:\Folder1\T1","C:\Folder2\T2" GCI -Path $TargetDelNt -Recurse | Where { $folder = $_.FullName !($folders | Where {$folder.Contains($_)}) } | Ft FullName -Auto
- Изменено KazunEditor 18 апреля 2016 г. 7:18
18 апреля 2016 г. 7:16Отвечающий -
Показывайте вывод, где попадают папки, которые должны быть исключены:
$folders = "C:\Folder1\T1","C:\Folder2\T2" GCI -Path $TargetDelNt -Recurse | Where { $folder = $_.FullName !($folders | Where {$folder.Contains($_)}) } | Ft FullName -Auto
Вывод такой
PS D:\1> $folders = "D:\1\Не удалять" GCI -Path $TargetDelNt -Recurse | Where { $folder = $_.FullName !($folders | Where {$folder.Contains($_)}) } | Ft FullName -Auto FullName -------- D:\1\Удалить1 D:\1\Удалить2 D:\1\clear.ps1
НО! Если вставить вместо вывода RI -Recurse -Force, то файлы удаляет и из папки "Не удалять"((
18 апреля 2016 г. 7:34 -
Теперь вывод с ключом -WhatIf, который только уведомляет, а не удаляет.
$folders = "D:\1\Не удалять" GCI -Path $TargetDelNt -Recurse | Where { $folder = $_.FullName !($folders | Where {$folder.Contains($_)}) } | Where-Object {$_.CreationTime -LT $ChDaysDel} | RI -Recurse -Force -WhatIf
18 апреля 2016 г. 7:39Отвечающий -
Теперь вывод с ключом -WhatIf, который только уведомляет, а не удаляет.
$folders = "D:\1\Не удалять" GCI -Path $TargetDelNt -Recurse | Where { $folder = $_.FullName !($folders | Where {$folder.Contains($_)}) } | Where-Object {$_.CreationTime -LT $ChDaysDel} | RI -Recurse -Force -WhatIf
PS D:\1> $TargetDelNt = "D:\1" $Del = "-3" $CurrentDay = Get-Date $folder = "D:\1\Не удалять" $ChDaysDel = $CurrentDay.AddDays($Del) GCI -Path $TargetDelNt -Recurse | Where { $folder = $_.FullName !($folders | Where {$folder.Contains($_)}) } | Where-Object {$_.CreationTime -LT $ChDaysDel} | RI -Recurse -Force -WhatIf WhatIf: Выполнение операции "Удаление файла" над целевым объектом "D:\1\Не удалять\Документ3.docx".
У файла "Документ3.docx" Дата создания больше 3 дней18 апреля 2016 г. 8:09 -
$folder = "D:\1\Не удалять" должно быть всегда $folders = "D:\1\Не удалять"
- Изменено KazunEditor 18 апреля 2016 г. 8:11
18 апреля 2016 г. 8:11Отвечающий -
Извиняюсь( проглядел.18 апреля 2016 г. 8:15
-
Интересно получается, вот код:
$TargetDelNt = "D:\1" $Del = "-3" $CurrentDay = Get-Date $folders = "D:\1\Не удалять" $ChDaysDel = $CurrentDay.AddDays($Del) GCI -Path $TargetDelNt -Recurse | Where { $folder = $_.FullName !($folders | Where {$folder.Contains($_)}) } | Where-Object {$_.CreationTime -LT $ChDaysDel} | RI -Recurse -Force -WhatIf
Если выполнять все писать руками в PowerShell то выводит:
$TargetDelNt = "D:\1" $Del = "-3" $CurrentDay = Get-Date $folders = "D:\1\Не удалять" $ChDaysDel = $CurrentDay.AddDays($Del) GCI -Path $TargetDelNt -Recurse | Where { $folder = $_.FullName !($folders | Where {$folder.Contains($_)}) } | Where-Object {$_.CreationTime -LT $ChDaysDel} | RI -Recurse -Force -WhatIf WhatIf: Выполнение операции "Удаление файла" над целевым объектом "D:\1\Удалить1\Документ2.docx".
То есть все правильно, папку "Не удалять" он не трогает, а файл "Документ2.docx" с датой создания больше 3 дней он удаляет.
А если этот скрипт сохранить в файл "clear.ps1" и запустить из PowerShell то совершенно другая ситуация
PS D:\1> .\clear.ps1 WhatIf: Выполнение операции "Удаление файла" над целевым объектом "D:\1\Не удалять\Документ3.docx". WhatIf: Выполнение операции "Удаление файла" над целевым объектом "D:\1\Удалить1\Документ2.docx".
Скрипт пытается удалить из всех папок.
теперь я вообще ничего не понимаю O_o
18 апреля 2016 г. 8:58 -
Скриншот приведите:
Get-Content .\clear.ps1
18 апреля 2016 г. 9:01Отвечающий -
Спасибо за наводку)
Дело было в кодировке. Notepad++ стояла кодировка UTF - 8 (Без BOM)
И PowerShell были крокозябры
Поменял кодировку на UTF-8 и все нормально заработало)
Спасибо большое
18 апреля 2016 г. 9:21