Windows, PowerShell i długie ścieżki

Windows, PowerShell i długie ścieżki

Myślę, że, podobnie jak ja, często widziałeś ścieżki w formacie !!! Ważne____Nowe____!!! Nie usuwać!!! Zlecenie nr 98819-649-B z 30 lutego 1985 r. o powołaniu Iwana Aleksandrowicza Kozłowa na czas pełniącego obowiązki kierownika działu obsługi korporacyjnych klientów VIP oraz organizacji spotkań biznesowych w kuluarach.doc.

I często otwarcie takiego dokumentu w systemie Windows od razu się nie udaje. Niektórzy stosują workaround w postaci mapowania dysków, inni używają menedżerów plików, które potrafią radzić sobie z długimi ścieżkami: Far Manager, Total Commander i tym podobne. A wielu smutno obserwowało, jak stworzony przez nich skrypt PS, w który włożono sporo pracy i który w środowisku testowym działał świetnie, w środowisku produkcyjnym bezradnie narzeka na przekraczenie granic możliwości: Podana ścieżka, nazwa pliku lub jedno i drugie są za długie. W pełnej nazwie pliku musi być mniej niż 260 znaków, a nazwa katalogu musi mieć mniej niż 248 znaków.
Okazało się, że 260 znaków wystarczy „nie wszystkim”. Jeśli jesteś ciekaw, jak wyjść poza dozwolone granice — zapraszam pod kat.

Oto niektóre z smutnych konsekwencji ograniczenia długości ścieżki pliku:

Odelgając nieco od tematu, zauważam, że dla DFS Replication omawiany w artykule problem nie jest groźny i pliki z długimi nazwami skutecznie podróżują z serwera na serwer (o ile, oczywiście, zrobiłeś wszystko) prawidłowo).

Chciałbym również zwrócić uwagę na bardzo przydatne i wielokrotnie ratujące mnie narzędzie robocopy. I ono też nie boi się długich ścieżek, a potrafi wiele. Dlatego jeśli zadanie sprowadza się do kopiowania/przenoszenia danych plikowych, warto się na niej zatrzymać. Jeśli trzeba majstrować przy listach kontroli dostępu w systemie plików (DACL), sprawdź subinacl. Mimo solidnego wieku, świetnie spisała się na Windows 2012 R2. Tutaj rozważono sposoby zastosowania.

Mnie interesowało nauczenie pracy z długimi ścieżkami PowerShell. Z nim prawie jak w starym dowcipie o Ivanie Carewiczu i Wasilisie Pięknej.

Szybki sposób

Przejść na Linuxa i nie martwić się Windows 10/2016/2019 oraz włączyć odpowiedni parametr polityki grupowej/edytować rejestr. Nie będę się rozwodzić nad tym sposobem, ponieważ w sieci jest już wiele artykułów na ten temat, na przykład, ten.

Biorąc pod uwagę, że w większości firm jest wiele, oględnie mówiąc, nieświeżych wersji systemów operacyjnych, ten sposób jest szybki tylko na papierze, jeśli oczywiście nie jesteś jednym z tych szczęśliwców, którzy mają mało systemów legacy i dominują Windows 10/2016/2019.

Długi sposób

Od razu zastrzeżmy, że zmiany nie wpłyną na zachowanie eksploratora Windows, ale umożliwią użycie długich ścieżek w poleceniach PowerShell, takich jak Get-Item, Get-ChildItem, Remove-Item itp.

Na początek zaktualizujmy PowerShell. To się robi na raz-dwa-trzy.

  1. Aktualizujemy .NET Framework do wersji co najmniej 4.5. System operacyjny musi być nie niższy niż Windows 7 SP1/2008 R2. Aktualną wersję można pobrać tutaj, dodatkowe informacje można przeczytać tutaj.
  2. Pobieramy i instalujemy Windows Management Framework 5.1
  3. Restartujemy maszynę.

Pracowici mogą wykonać opisane powyżej kroki ręcznie, leniwi – za pomocą SCCM, polityk, skryptów i różnych narzędzi automatyzacji.

Obecną wersję PowerShell można poznać z zmiennej $PSVersionTable. Po aktualizacji powinno być mniej więcej tak:

Windows, PowerShell i długie ścieżki

Teraz podczas używania poleceń Get-ChildItem i tym podobnych zamiast zwykłego Ścieżka będziemy używać LiteralPath.

Format ścieżek będzie nieco inny:

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

Dla wygody konwersji ścieżek z tradycyjnego formatu do formatu LiteralPath można użyć takiej funkcji:

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"}
}

Zwróć uwagę, że przy podawaniu parametru LiteralPath nie można używać znaków zastępczych (*, ? itd.).

Oprócz parametru LiteralPath, w zaktualizowanej wersji PowerShell polecenie Get-ChildItem zyskało parametr Depth, którego można używać do określania głębokości zagnieżdżenia dla rekursywnego wyszukiwania, użyłem go kilka razy i byłem zadowolony.

Teraz możesz nie obawiać się, że twój skrypt PS zboczy z długiej, krętej drogi i nie dostrzeże odległych plików. Mnie na przykład bardzo pomogło to podejście przy pisaniu skryptu do resetowania atrybutu „tymczasowy” dla plików w folderach DFSR. Ale to już inna historia, o której postaram się opowiedzieć w innym artykule. Czekam na interesujące komentarze od was i zapraszam do wzięcia udziału w ankiecie.

Przydatne linki:
docs.microsoft.com/ru-ru/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

Tylko zarejestrowani użytkownicy mogą brać udział w ankiecie. Zaloguj się, proszę.

Czy problem długich ścieżek jest dla Ciebie aktualny?

  • Tak

  • Był aktualny, ale już rozwiązany

  • Przeszkadza, ale niezbyt

  • Nie myślałem o tym, wszystko działa

  • Nie

  • Inne (proszę wskazać w komentarzach)

155 użytkowników oddało głos. 25 użytkowników wstrzymało się.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster