Windows, PowerShell и дълги пътища

Windows, PowerShell и дълги пътища

Мисля, че и вам, както и на мен, не веднъж се е случвало да видите пътища от вида !!! Важно____Ново____!!! Не изтривайте!!! Заповед №98819-649-Б от 30 февруари 1985г. за назначаване на Козлов Иван Александрович временно изпълняващ длъжността ръководител на направление за поддръжка на корпоративни VIP-клиенти и организиране на бизнес срещи в кулуарите.doc.

И често отворите такъв документ в Windows веднага не става. Някои практикуват workaround под формата на мапиране на дискове, други използват файлови мениджъри, които умеят да работят с дълги пътища: Far Manager, Total Commander и подобни. А много от тях с тъга наблюдаваха как създаденият от тях PS-скрипт, в който беше вложен немалко труд и който в тестова среда работи безупречно, в продуктивна среда безпомощно се оплакваше от непосилната задача: Посоченият път, име на файл или и двете са твърде дълги. Пълното име на файла трябва да бъде по-малко от 260 символа, а името на директорията трябва да бъде по-малко от 248 символа.
Както се оказа, 260 символа не са "не само за всички“. Ако искате да преминете границите на позволеното – моля, под кат.

Ето само някои от тъжните последици от ограничението на дължината на файловия път:

С малко отклонение от темата, искам да подчертая, че за DFS Replication разглежданият в статията проблем не е страшен и файловете с дълги имена успешно пътуват от сървър на сървър (ако, разбира се, всичко останало е направено правилно) направихте правилно).

Искам да обърна внимание на много полезния инструмент robocopy. Той също не се плаши от дълги пътища и може да прави много. Затова, ако задачата е свързана с копиране/пренасяне на файлови данни, можете да се спрете на него. Ако трябва да се мятате със списъците за контрол на достъпа в файловата система (DACL), погледнете към subinacl. Въпреки солидната си възраст, показва отличен резултат на Windows 2012 R2. Тук разгледани са методи за приложение.

Мен беше интересно да науча как да работя с дълги пътища в PowerShell. С него е почти като в онзи стар анекдот за Иван-Царевича и Василиса Прекрасна.

Бърз метод

Да преминем на Linux и да не се притесняваме за Windows 10/2016/2019 и да включим съответния параметър в груповата политика/да променим регистъра. Няма да задълбавам в този метод, защото в интернет вече има много статии по темата, например, това.

Като се има предвид, че в повечето компании има много, меко казано, остарели версии на операционни системи, този метод е бърз само на хартия, освен ако не сте от щастливците, при които малко наследствени системи и цари Windows 10/2016/2019.

Дълъг метод

Тук веднага уточняваме, че измененията няма да засегнат поведението на Windows Explorer, а ще позволят използването на дълги пътища в командлети на 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 и подобни на него вместо познатото Path ще използваме 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 получи параметър Depth, с помощта на който може да се зададе дълбочината на вложеност за рекурсивно търсене, използвал съм го няколко пъти и останах доволен.

Сега можете да не се притеснявате, че вашият PS-скрипт ще се отклони от дългия трънлив път и няма да види далечните файлове. Например, този подход ми помогна много при написването на скрипт за премахване на атрибута „временен“ от файловете в DFSR папки. Но това е друга история, за която ще се постарая да разкажа в следваща статия. Очаквам интересни коментари от вас и предлагам да участвате в анкетата.

Полезни връзки:
docs.microsoft.com/bg-bg/dotnet/api/microsoft.powershell.commands.contentcommandbase.literalpath?view=powershellsdk-1.1.0
docs.microsoft.com/bg-bg/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

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster