Recently, I had to create symbolic link while running a scan on some systems and found that was not a native way to achieve this in PowerShell.PowerShell を使用すると、シンボリック リンクを作成する必要があります。 現在、mklink.exe を使用してこれを動作させることができますが、これは cmd.exe でのみ動作します。
mklink.exe
その代わり、コマンドにアクセスするために、まず cmd.exe を呼び出し、次に mklink.exe を呼び出さなければなりません。 まあ、私はそうではありません。 mklink.exe を使用してシンボリック リンクを作成する前に、まず cmd.exe を呼び出すことに頼る必要はないはずです。 Pinvoke を使用して Win32 API にアクセスできるおかげで、この運命を受け入れる必要はありません。
pinvoke.net に出てみると、kernel32 の下に私が探しているものを満たす CreateSymbolicLink という関数があることがわかります。
必要なものの基本は次のとおりです。
public static extern bool CreateSymbolicLink(strin
この関数をセッションに追加すると利用できるように、先頭に ‘public’ キーワードを追加する必要がありました。 これはコードのすべてではなく、サイトで利用可能だったものだけです。 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
これで、シンボリック リンクを作成するために使用できる型が完成しました。 必要なのは、リンクに使用するパスと実際の SymName、そして 0 (File) または 1 (Directory) のいずれかで、どのようなシンボリック リンクが作成されるかを決定することのみです。 結果の値はブール値で、If/Else文に追加して残りのアクションを処理することが簡単にできます。
::CreateSymbolicLink('C:\Users\Administrator\Desktop\SQL2008Install',"\dc1\SharedStorage\SQL 2008",1)
SQL2008Install シンボリック リンクを見てみると、ReparsePoint としてラベル付けされているので、シンボリック リンクであることが属性でわかります:
これで、私のデスクトップに、リモート サーバーの SQL2008 インストール フォルダを指すシンボリック リンクが作成されたことになります。
New-SymLink
この関数は、基本的にこれまで説明したことを行いますが、移植可能でより使いやすい関数形式になっています。 この関数では、ディレクトリまたはファイルのシンボリック リンクを作成できます。
関数の開始部分では、pinvoke 型をすでにロードしているかどうかを確認し、ロードしていない場合は Add-Type を使用して型を追加します。 追加項目として、シンボリック リンクとリンクが参照しているターゲット パスを示すオブジェクトを出力します。
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) } }}
Lets see this in action! この関数をダウンロードするためのリンクは以下のとおりです。 この関数についてどう思うか教えてください!
Download
Script Repository