Думаю, вам, як і мені, неодноразово доводилося бачити шляхи виду !!! Важливе____Нове____!!! Не видаляти!!! Наказ №98819-649-Б від 30 лютого 1985р. про призначення Козлова Івана Олександровича тимчасово виконуючим обов'язки керівника направлення щодо супроводу корпоративних VIP-клієнтів та організації ділових зустрічей у кулуарах.doc.
І часто відкрити такий документ у Windows відразу не вийде. Хтось практикує workaround у вигляді мапірування дисків, хтось використовує файлові менеджери, які вміють працювати з довгими шляхами: Far Manager, Total Commander та подібні до них. А ще багато хто з сумом спостерігав, як створений ними PS-скрипт, в який було вкладено чимало праці і який у тестовому оточенні працював на ура, у бойовому середовищі безпорадно скаржився на непосильне завдання: Вказаний шлях, ім’я файлу або обидва надто довгі. Повна назва файлу має містити менше 260 символів, а назва каталогу - менше 248 символів.
Як виявилося, 260 знаків вистачить «не тільки всім». Якщо вам цікаво вийти за межі дозволеного – прошу під кат.
Ось лише деякі з сумних наслідків обмеження довжини файлового шляху:
на сервері є папка, наприклад D:DataSharedAccounting, яка розшарована по SMB і монтується користувачам як мережевий диск S; користувачі створюють файли, які зможуть прочитати адміни/скрипти при локальному доступі з сервера, т.к. абсолютний шлях виходить довшим за мережевий;
при міграції даних з інших систем, у яких менш жорсткі обмеження до довжини шляху, у новому оточенні частина з них стане недоступною без танців з бубном;
Трохи відхиляючись від теми, зауважу, що для DFS Replication проблема, що розглядається в статті, не страшна і файли з довгими іменами успішно подорожують з сервера на сервер (якщо, звичайно, в іншому ви все зробили правильно).
Ще хотілося б звернути увагу на дуже корисну і не раз мене рятувала утиліту робокопія. Їй теж не страшні довгі шляхи, та й вона вміє багато. Тому, якщо завдання зводиться до копіювання/перенесення файлових даних, можна зупинитися на ній. Якщо потрібно пошаманити зі списками контролю доступу у файловій системі (DACL), подивіться убік субінакл. Незважаючи на солідний вік, чудово себе показала на Windows 2012 R2. Тут розглянуто способи застосування.
Мені було цікаво навчити працювати з довгими шляхами PowerShell. З ним майже як у бородатому анекдоті про Івана-Царевича та Василису Прекрасну.
Швидкий спосіб
Перейти на Linux і не паритися Windows 10/2016/2019 і ввімкнути відповідний параметр групової політики/натиснути реєстр. Докладно цьому способі зупинятися не буду, т.к. у мережі вже багато статей на цю тему, наприклад, ця.
Враховуючи, що в більшості компаній багато не свіжих версій операційних систем, цей спосіб швидкий тільки для написання на папері, якщо, звичайно, ви не з тих щасливчиків, у яких мало legacy-систем і панують Windows 10/2016/2019 .
Довгий спосіб
Тут відразу обмовимося, що зміни не торкнуться поведінки провідника Windows, а дадуть можливість використовувати довгі шляхи в командлетах PowerShell, таких як Get-Item, Get-ChildItem, Remove-Item та ін.
Для початку оновимо PowerShell. Робиться на раз-два-три.
Оновлюємо .NET Framework до версії не нижче 4.5. Операційна система повинна бути не нижчою за Windows 7 SP1/2008 R2. Актуальну версію можна завантажити тут, додаткову інформацію почитати тут.
Викачуємо та встановлюємо Windows Management Framework 5.1
Перезавантажуємо машину.
Працьовиті можуть зробити описані вище кроки вручну, ліниві — за допомогою SCCM, політик, скриптів та енікеїв інших засобів автоматизації.
Поточну версію PowerShell можна дізнатися зі змінної $ PSVersionTable. Після оновлення має бути приблизно так:
Тепер при використанні командлетів Get-ChildItem і йому подібних замість звичного Шлях будем використовувати LiteralPath.
Для зручності перетворення шляхів із звичного формату у формат LiteralPath можна використовувати таку функцію:
Function ConvertTo-LiteralPath
Param([parameter(Mandatory=$true, Position=0)][String]$Path)
If ($Path.Substring(0,2) -eq "") {Return ("?UNC" + $Path.Remove(0,1))}
Else {Return "?$Path"}
}
Зверніть увагу, що при заданні параметра LiteralPath не можна використовувати символи підстановки (*, ? і т.д.).
Крім параметра LiteralPath, у оновленій версії PowerShell командлет Get-ChildItem отримав параметр ГлибинаЗа допомогою якого можна задавати глибину вкладеності для рекурсивного пошуку, я пару разів його використовував і залишився задоволений.
Тепер можна не боятися, що ваш PS-скрипт зіб'ється з довгого тернистого шляху і не розгляне далекі файли. Мене, наприклад, дуже врятував цей підхід при написанні скрипту для скидання атрибуту «тимчасовий» у файлів у папках DFSR. Але це вже інша історія, про яку я намагатимусь розповісти в іншій статті. Від вас чекаю цікавих коментарів і пропоную пройти опитування.