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

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

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

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

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

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

Също така бих искал да обърна внимание на много полезна и неведнъж спасяваща утилита 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/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

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