Tworzenie dowiązania symbolicznego za pomocą PowerShell

Ostatnio miałem potrzebę utworzenia dowiązania symbolicznego podczas skanowania niektórych systemów i odkryłem, że nie ma natywnego sposobu w PowerShell, aby to osiągnąć. Teraz mogę użyć mklink.exe, aby to zrobić, ale to będzie działać tylko pod cmd.exe. Oznacza to, że nie mogę faktycznie wywołać mklink.exe pod PowerShell.

mklink.exe

image

Zamiast tego, muszę najpierw wywołać cmd.exe, a następnie mklink.exe, aby uzyskać dostęp do polecenia.

cmd.exe /c mklink.exe

image

Więc można by pomyśleć, że byłbym zadowolony z tego wyniku. Cóż, nie jestem. Nie powinienem być zmuszony do polegania na wywołaniu cmd.exe przed użyciem mklink.exe do utworzenia dowiązania symbolicznego. A dzięki użyciu Pinvoke, aby dostać się do Win32 API, nie muszę akceptować tego losu!

Wychodząc na stronę pinvoke.net, widzę pod kernel32, że istnieje funkcja o nazwie CreateSymbolicLink, która spełnia to, czego szukam.

image

Podstawy tego, czego potrzebuję są poniżej:

public static extern bool CreateSymbolicLink(strin

Musiałem dodać słowo kluczowe 'public’ na początku, więc ta funkcja będzie dostępna, gdy dodam ją do mojej sesji. To nie jest cały kod, tylko to, co było dostępne na stronie. Musiałem zrobić trochę kodu C#, aby przekształcić to w typ, który mogę zaimportować do mojej sesji PowerShell za pomocą Add-Type.

Add-Type @"using System;using System.Runtime.InteropServices; namespace mklink{ public class symlink { public static extern bool CreateSymbolicLink(string lpSymlinkFileName, string lpTargetFileName, int dwFlags); }}"@
 | get-member -static

image

Teraz mam typ, który może być użyty do utworzenia dowiązania symbolicznego. Wszystko, czego wymaga, to ścieżka do użycia dla linku i rzeczywista nazwa SymName, a następnie 0 (plik) lub 1 (katalog), aby zdecydować, jaki rodzaj symbolicznego linku zostanie utworzony. Wartość wynikowa jest wartością boolean, która może być łatwo dodana do instrukcji If/Else, aby obsłużyć resztę działań.

::CreateSymbolicLink('C:\Users\Administrator\Desktop\SQL2008Install',"\dc1\SharedStorage\SQL 2008",1)

image

Patrząc na dowiązanie symboliczne SQL2008Install, widać po atrybutach, że jest to dowiązanie symboliczne, ponieważ jest oznaczone jako ReparsePoint:

image

Dzięki temu mam teraz dowiązanie symboliczne na pulpicie, które wskazuje na folder instalacyjny SQL2008 na moim zdalnym serwerze.

Ponieważ ta metoda wymaga trochę pracy, naturalnym jest, że może ona stać się funkcją wielokrotnego użytku.

New-SymLink

Ta funkcja w zasadzie robi to, co pokazałem, ale w formie funkcji, która jest przenośna i łatwiejsza w użyciu. Pozwala ona na utworzenie dowiązania symbolicznego dla katalogu lub pliku.

Początkowa część mojej funkcji polega na sprawdzeniu, czy załadowałem już mój typ pinvoke, a jeśli nie, dodaniu typu za pomocą Add-Type.

Begin { Try { $null = } Catch { Add-Type @" using System; using System.Runtime.InteropServices; namespace mklink { public class symlink { public static extern bool CreateSymbolicLink(string lpSymlinkFileName, string lpTargetFileName, int dwFlags); } }"@ }}

Blok Process (pozwalam na wejście rurociągu dla parametru Path) jest miejscem, w którym używam mojego typu do utworzenia dowiązania symbolicznego i obserwuję wszelkie problemy podczas tego procesu. Jako dodatkowy element, wyślę obiekt pokazujący dowiązanie symboliczne i ścieżkę docelową, do której to dowiązanie się odnosi.

Process { #Assume target Symlink is on current directory if not giving full path or UNC If ($SymName -notmatch "^(?::\)|(?:\\\w+\$)") { $SymName = "{0}\{1}" -f $pwd,$SymName } $Flag = @{ File = 0 Directory = 1 } If ($PScmdlet.ShouldProcess($Path,'Create Symbolic Link')) { Try { $return = ::CreateSymbolicLink($SymName,$Path,$Flag) If ($return) { $object = New-Object PSObject -Property @{ SymLink = $SymName Target = $Path Type = $PScmdlet.ParameterSetName } $object.pstypenames.insert(0,'System.File.SymbolicLink') $object } Else { Throw "Unable to create symbolic link!" } } Catch { Write-warning ("{0}: {1}" -f $path,$_.Exception.Message) } }}

Zobaczmy to w akcji!

New-SymLink -Path "C:\Users\Administrator\Downloads" -SymName Downloads -Directory -Verbose

image

I w ten sposób, funkcja tworzy dowiązanie symboliczne do mojego folderu Downloads na pulpicie. Link do pobrania tej funkcji znajduje się poniżej. Daj mi znać, co myślisz o tej funkcji!

Pobierz

Repozytorium skryptów

.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.