Подтвердить что ты не робот

Удалить каталог независимо от 260 char limit

Я пишу простой script для удаления папок миграции USMT через определенное количество дней:

## Server List ##
$servers = "Delorean","Adelaide","Brisbane","Melbourne","Newcastle","Perth"

## Number of days (-3 is over three days ago) ##
$days = -3

$timelimit = (Get-Date).AddDays($days)

foreach ($server in $servers)
{
    $deletedusers = @()
    $folders = Get-ChildItem \\$server\USMT$ | where {$_.psiscontainer}
    write-host "Checking server : " $server
    foreach ($folder in $folders) 
    {
        If ($folder.LastWriteTime -lt $timelimit -And $folder -ne $null)
        {
            $deletedusers += $folder
            Remove-Item -recurse -force $folder.fullname
        }
    }
        write-host "Users deleted : " $deletedusers
        write-host
}

Однако я продолжаю сталкиваться с ужасным Remove-Item : The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.

Я искал обходные пути и альтернативы, но все они вращаются вокруг меня, заботясь о том, что находится в папке.

Я надеялся на более простое решение, так как мне действительно не нравится содержимое папки, если оно помечено для удаления.

Есть ли какой-либо родной командлет Powershell, отличный от Remove-Item -recurse, который может выполнить то, что мне нужно?

4b9b3361

Ответ 2

У меня часто возникает проблема с проектами node. Они закладывают свои зависимости, а после клонирования git их трудно удалить. Хорошая утилита node, с которой я столкнулся, - rimraf.

npm install rimraf -g
rimraf <dir>

Ответ 3

Так же, как CADII сказал в другом ответе: Robocopy может создавать пути длиной до 260 символов. Robocopy также может удалять такие пути. Вы можете просто отразить пустую папку по вашему пути, содержащую слишком длинные имена, если вы хотите ее удалить.

Например:

robocopy C:\temp\some_empty_dir E:\temp\dir_containing_very_deep_structures /MIR

Вот ссылку Robocopy, чтобы узнать параметры и различные параметры.

Ответ 5

Если у вас установлен рубин, вы можете использовать Fileman:

gem install fileman

После установки вы можете просто запустить в командной строке следующее:

fm rm your_folder_path

Эта проблема представляет собой настоящую боль в шее, когда вы развиваетесь в node.js в Windows, поэтому fileman становится очень удобным для удаления всего мусора один раз в то время

Ответ 6

Я создал функцию PowerShell, способную удалить длинный путь ( > 260) с использованием упомянутого метода robocopy:

function Remove-PathToLongDirectory 
{
    Param(
        [string]$directory
    )

    # create a temporary (empty) directory
    $parent = [System.IO.Path]::GetTempPath()
    [string] $name = [System.Guid]::NewGuid()
    $tempDirectory = New-Item -ItemType Directory -Path (Join-Path $parent $name)

    robocopy /MIR $tempDirectory.FullName $directory | out-null
    Remove-Item $directory -Force | out-null
    Remove-Item $tempDirectory -Force | out-null
}

Пример использования:

Remove-PathToLongDirectory c:\yourlongPath

Ответ 7

Недавно я узнал об уловке, который часто работает, чтобы обойти проблемы с длинными файловыми путями. По-видимому, при использовании некоторых API Windows определенные функции будут проходить через устаревший код, который не может обрабатывать длинные имена файлов. Однако, если вы форматируете свои пути определенным образом, унаследованный код избегается. Трюк, который решает эту проблему, - это ссылки на пути с использованием префикса "\\? \". Следует отметить, что не все API поддерживают это, но в этом конкретном случае это сработало для меня, см. Мой пример ниже:

Следующий пример не выполняется:

PS D:\> get-childitem -path "D:\System Volume Information\dfsr" -hidden


Directory: D:\System Volume Information\dfsr


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a-hs        10/09/2014  11:10 PM     834424 FileIDTable_2
-a-hs        10/09/2014   8:43 PM    3211264 SimilarityTable_2

PS D:\> Remove-Item -Path "D:\System Volume Information\dfsr" -recurse -force
Remove-Item : The specified path, file name, or both are too long. The fully qualified file name must be less than 260
characters, and the directory name must be less than 248 characters.
At line:1 char:1
+ Remove-Item -Path "D:\System Volume Information\dfsr" -recurse -force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : WriteError: (D:\System Volume Information\dfsr:String) [Remove-Item], PathTooLongExcepti
on
+ FullyQualifiedErrorId : RemoveItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand

PS D:\>

Однако префикс пути с "\\? \" делает команду успешной:

PS D:\> Remove-Item -Path "\\?\D:\System Volume Information\dfsr" -recurse -force
PS D:\> get-childitem -path "D:\System Volume Information\dfsr" -hidden
PS D:\>

Ответ 8

Если все, что вы делаете, это удаление файлов, я использую функцию для сокращения имен, а затем я удаляю.

    function ConvertTo-ShortNames{
    param ([string]$folder)
    $name = 1
    $items = Get-ChildItem -path $folder
    foreach ($item in $items){
        Rename-Item -Path $item.FullName -NewName "$name"
        if ($item.PSIsContainer){
            $parts = $item.FullName.Split("\")
            $folderPath = $parts[0]
            for ($i = 1; $i -lt $parts.Count - 1; $i++){
                $folderPath = $folderPath + "\" + $parts[$i]
            }
            $folderPath = $folderPath + "\$name"
            ConvertTo-ShortNames $folderPath
        }
        $name++
    }
}

Я знаю, что это старый вопрос, но я подумал, что поставил бы это на случай, если кому-то это понадобится.

Ответ 9

Существует одно обходное решение, в котором используется Experimental.IO из Project Base Libraries. Вы можете найти его на poshcode или загрузить с блог автора. 260 происходит из . NET, так это либо это, либо с помощью инструментов, которые не зависят от .NET(например, cmd /c dir, как @Билл предложил).

Ответ 10

Это стареет, но мне недавно пришлось снова обойти это. Я закончил использование "subst", поскольку для ПК, на котором он работал, не было никаких других модулей или функций. Немного более портативный.

В основном найти букву запасного диска, "подставить" длинный путь к этой букве, а затем использовать ее как базу для GCI.

Только ограничение состоит в том, что $_. fullname и другие свойства будут сообщать букву диска как корневой путь.

Кажется, работает нормально:

$location = \\path\to\long\
$driveLetter = ls function:[d-z]: -n | ?{ !(test-path $_) } | random

subst $driveLetter $location
sleep 1
Push-Location $driveLetter -ErrorAction SilentlyContinue
Get-ChildItem -Recurse

subst $driveLetter /D

Эта команда, очевидно, не удаляет файлы, но может быть заменена.

Ответ 11

Комбинация инструментов может работать лучше всего, попробуйте сделать dir/x, чтобы вместо этого получить имя файла 8.3. Затем вы можете разобрать этот вывод в текстовый файл, а затем создать файл powershell script, чтобы удалить пути, из которых вы вышли. Возьми тебя на минутку. В качестве альтернативы вы можете просто переименовать имя файла 8.3 в нечто более короткое, чем удалить.

Ответ 12

Добавление к решению Даниэля Ли, Когда $myDir имеет пробелы в середине, он дает FILE NOT FOUND ошибки, учитывая набор файлов, разделенных из космоса. Чтобы преодолеть это, используйте котировки вокруг переменной и поместите символ escape-последовательности powershell, чтобы пропустить quatations.

PS>cmd.exe /C "rmdir /s /q <grave-accent>"$myDir<grave-accent>""

Пожалуйста, замените символ серьезного акцента вместо <grave-accent>
SO играет со мной, и я не могу добавить его:). Надеюсь, что кто-то обновит его, чтобы другие могли легко понять.

Ответ 13

Просто для полноты, я столкнулся с этим еще несколько раз и использовал комбинацию "subst" и "New-PSDrive", чтобы обойти ее в различных ситуациях.

Не совсем решение, но если кто-то ищет альтернативы, это может помочь.

Subst кажется очень чувствительной к тому типу программы, которую вы используете для доступа к файлам, иногда она работает, а иногда и нет, похоже, с New-PSDrive.

Ответ 14

PowerShell можно легко использовать с AlphaFS.dll для работы с файлами ввода-вывода без проблем с PATH TOO LONG.

Например:

Import-Module <path-to-AlphaFS.dll>

[Alphaleonis.Win32.Filesystem.Directory]::Delete($path, $True)

Пожалуйста, смотрите в Codeplex: https://alphafs.codeplex.com/ для этого проекта .NET.

Ответ 15

Любая вещь, разработанная с использованием .NET из коробки, терпит неудачу с слишком длинными путями. Вам нужно будет переместить их в 8.3 имена, вызовы PInVoke (Win32), или используйте robocopy

Ответ 16

У меня была такая же проблема при попытке удалить папки на удаленной машине.

Ничего не помогло, но... Я нашел один трюк:

'---------------------------------------------- -

'# 1: создать пустую папку

md ".\Empty" -erroraction silentlycontinue

'# 2: пусть MIR в папку для удаления: это полностью освободит папку.

robocopy ".\Empty" $foldertodelete/MIR/LOG +: $logname

'# 3: теперь удалите пустую папку:

remove-item $foldertodelete -force

'# 4: мы можем удалить пустую папку

remove-item ".\Empty" -force

'------------------------------

Работает как очарование локальных или удаленных папок (с использованием UNC-пути)

Ответ 17

Для моей Robocopy работал в 1, 2 и 3

  • Сначала создайте пустой каталог, скажем c:\emptydir
  • ROBOCOPY c:\emptydir c:\directorytodelete/purge
  • rmdir c:\directorytodelete