Nedávno jsem potřeboval vytvořit symbolický odkaz při skenování některých systémů a zjistil jsem, že v prostředí PowerShell neexistuje nativní způsob, jak toho dosáhnout. Nyní mohu k tomuto účelu použít soubor mklink.exe, který však bude fungovat pouze pod cmd.exe. To znamená, že pod prostředím PowerShell vlastně nemohu zavolat mklink.exe.
mklink.exe
Místo toho musím nejprve zavolat cmd.exe a následně mklink.exe, abych získal přístup k příkazu.
cmd.exe /c mklink.exe
Mohlo by se tedy zdát, že s tímto výsledkem budu spokojen. No, nejsem. Neměl bych se spoléhat na to, že nejprve zavolám cmd.exe a teprve potom pomocí mklink.exe vytvořím symbolický odkaz. A díky tomu, že se pomocí Pinvoke dostanu do rozhraní API Win32, se s tímto osudem nemusím smířit!“
Přejdu na stránku pinvoke.net a vidím, že pod kernel32 existuje funkce CreateSymbolicLink, která splňuje to, co hledám.
Základní informace o tom, co potřebuji, jsou uvedeny níže:
public static extern bool CreateSymbolicLink(strin
Musel jsem na začátek přidat klíčové slovo ‚public‘, aby tato funkce byla dostupná, když ji přidám do své relace. Toto není celý kód, jen to, co bylo k dispozici na webu. Musel jsem provést trochu kódování v jazyce C#, abych z toho vytvořil typ, který mohu importovat do relace prostředí PowerShell pomocí funkce 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
Teď mám typ, který lze použít k vytvoření symbolického odkazu. Jediné, co vyžaduje, je Cesta, která se použije pro odkaz, a skutečný název SymName a pak buď 0 (Soubor), nebo 1 (Adresář), aby se rozhodlo, jaký druh symbolického odkazu bude vytvořen. Výsledná hodnota je logická hodnota, kterou lze snadno přidat do příkazu If/Else a zpracovat tak zbytek akcí.
::CreateSymbolicLink('C:\Users\Administrator\Desktop\SQL2008Install',"\dc1\SharedStorage\SQL 2008",1)
Podíváte-li se na symbolický odkaz SQL2008Install, vidíte podle atributů, že se jedná o symbolický odkaz, protože je označen jako ReparsePoint:
S tím mám nyní na ploše symbolický odkaz, který ukazuje na složku instalace SQL2008 na vzdáleném serveru.
Vzhledem k tomu, že tato metoda vyžaduje určitou práci, je přirozené, že se z ní může stát funkce, která je opakovaně použitelná.
New-SymLink
Tato funkce v podstatě dělá to, co jsem vám ukázal, ale ve formě funkce, která je přenosná a snadněji použitelná. Umožňuje vytvořit symbolický odkaz buď pro adresář, nebo pro soubor.
Část Begin mé funkce zahrnuje kontrolu, zda jsem již načetl svůj typ pinvoke, a pokud ne, přidání typu 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 (pro parametr Path nechávám vstupovat pipeline) je místem, kde používám svůj typ k vytvoření symbolického odkazu a během tohoto procesu sleduji případné problémy. Jako doplněk vypíšu objekt zobrazující symbolický odkaz a cílovou cestu, na kterou odkaz odkazuje.
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) } }}
Ukažme si to v akci!“
New-SymLink -Path "C:\Users\Administrator\Downloads" -SymName Downloads -Directory -Verbose
A tím funkce vytvoří symbolický odkaz pro mou složku Downloads na ploše. Odkaz ke stažení této funkce je uveden níže. Dejte mi vědět, co si o této funkci myslíte!
Stáhnout
Úložiště skriptů