Windows, PowerShell та довгі шляхи

Windows, PowerShell та довгі шляхи

Думаю, вам, як і мені, неодноразово доводилося бачити шляхи виду !!! Важливе____Нове____!!! Не видаляти!!! Наказ №98819-649-Б від 30 лютого 1985р. про призначення Козлова Івана Олександровича тимчасово виконуючим обов'язки керівника направлення щодо супроводу корпоративних VIP-клієнтів та організації ділових зустрічей у кулуарах.doc.

І часто відкрити такий документ у Windows відразу не вийде. Хтось практикує workaround у вигляді мапірування дисків, хтось використовує файлові менеджери, які вміють працювати з довгими шляхами: Far Manager, Total Commander та подібні до них. А ще багато хто з сумом спостерігав, як створений ними PS-скрипт, в який було вкладено чимало праці і який у тестовому оточенні працював на ура, у бойовому середовищі безпорадно скаржився на непосильне завдання: Вказаний шлях, ім’я файлу або обидва надто довгі. Повна назва файлу має містити менше 260 символів, а назва каталогу - менше 248 символів.
Як виявилося, 260 знаків вистачить «не тільки всім». Якщо вам цікаво вийти за межі дозволеного – прошу під кат.

Ось лише деякі з сумних наслідків обмеження довжини файлового шляху:

Трохи відхиляючись від теми, зауважу, що для 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. Робиться на раз-два-три.

  1. Оновлюємо .NET Framework до версії не нижче 4.5. Операційна система повинна бути не нижчою за Windows 7 SP1/2008 R2. Актуальну версію можна завантажити тут, додаткову інформацію почитати тут.
  2. Викачуємо та встановлюємо Windows Management Framework 5.1
  3. Перезавантажуємо машину.

Працьовиті можуть зробити описані вище кроки вручну, ліниві — за допомогою SCCM, політик, скриптів та енікеїв інших засобів автоматизації.

Поточну версію PowerShell можна дізнатися зі змінної $ PSVersionTable. Після оновлення має бути приблизно так:

Windows, PowerShell та довгі шляхи

Тепер при використанні командлетів Get-ChildItem і йому подібних замість звичного Шлях будем використовувати LiteralPath.

Формат шляхів при цьому буде трохи іншим:

Get-ChildItem -LiteralPath "?C:Folder"
Get-ChildItem -LiteralPath "?UNCServerNameShare"
Get-ChildItem -LiteralPath "?UNC192.168.0.10Share"

Для зручності перетворення шляхів із звичного формату у формат 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. Але це вже інша історія, про яку я намагатимусь розповісти в іншій статті. Від вас чекаю цікавих коментарів і пропоную пройти опитування.

Корисні посилання:
docs.microsoft.com/ru-ua/dotnet/api/microsoft.powershell.commands.contentcommandbase.literalpath?view=powershellsdk-1.1.0
docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-5.1
stackoverflow.com/questions/46308030/handling-path-too-long-exception-with-new-psdrive/46309524
luisabreu.wordpress.com/2013/02/15/theliteralpath-parameter

Тільки зареєстровані користувачі можуть брати участь в опитуванні. Увійдіть, будь ласка.

Чи актуальна для вас проблема довгих шляхів?

  • Так

  • Була актуальною, але вже вирішив

  • Заважає, але не сильно

  • Не думав про це, начебто все працює

  • Ні

  • Інше (вкажіть у коментарях)

Проголосували 155 користувачів. Утрималися 25 користувачів.

Джерело: habr.com

Додати коментар або відгук