này hiện các trick với công việc ít hơn, và hoạt động ngay cả đối với các nút giao trên máy chủ từ xa:
fsutil reparsepoint query "M:\Junc"
Nếu bạn muốn chỉ tên đích:
fsutil reparsepoint query "M:\Junc" | where-object { $_ -imatch 'Print Name:' } | foreach-object { $_ -replace 'Print Name\:\s*','' }
nên
function Get_JunctionTarget($p_path)
{
fsutil reparsepoint query $p_path | where-object { $_ -imatch 'Print Name:' } | foreach-object { $_ -replace 'Print Name\:\s*','' }
}
Ngoài ra, các mã dưới đây là một sửa đổi nhỏ của mã mà Josh cung cấp ở trên. Nó có thể được đặt trong một tập tin được đọc nhiều lần, và nó xử lý hàng đầu \\?\
một cách chính xác trong trường hợp của một ổ đĩa mạng:
function Global:Get_UNCPath($l_dir)
{
if((([System.Management.Automation.PSTypeName]'System.Win32').Type -eq $null) -or ([system.win32].getmethod('GetSymbolicLinkTarget') -eq $null))
{
Add-Type -MemberDefinition @"
private const int CREATION_DISPOSITION_OPEN_EXISTING = 3;
private const int FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
[DllImport("kernel32.dll", EntryPoint = "GetFinalPathNameByHandleW", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetFinalPathNameByHandle(IntPtr handle, [In, Out] StringBuilder path, int bufLen, int flags);
[DllImport("kernel32.dll", EntryPoint = "CreateFileW", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode,
IntPtr SecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);
public static string GetSymbolicLinkTarget(System.IO.DirectoryInfo symlink)
{
SafeFileHandle directoryHandle = CreateFile(symlink.FullName, 0, 2, System.IntPtr.Zero, CREATION_DISPOSITION_OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, System.IntPtr.Zero);
if(directoryHandle.IsInvalid)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
StringBuilder path = new StringBuilder(512);
int size = GetFinalPathNameByHandle(directoryHandle.DangerousGetHandle(), path, path.Capacity, 0);
if (size<0)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
// The remarks section of GetFinalPathNameByHandle mentions the return being prefixed with "\\?\"
// More information about "\\?\" here -> http://msdn.microsoft.com/en-us/library/aa365247(v=VS.85).aspx
string sPath = path.ToString();
if(sPath.Length>8 && sPath.Substring(0,8) == @"\\?\UNC\")
{
return @"\" + sPath.Substring(7);
}
else if(sPath.Length>4 && sPath.Substring(0,4) == @"\\?\")
{
return sPath.Substring(4);
}
else
{
return sPath;
}
}
"@ -Name Win32 -NameSpace System -UsingNamespace System.Text,Microsoft.Win32.SafeHandles,System.ComponentModel
}
[System.Win32]::GetSymbolicLinkTarget($l_dir)
}
và đưa ra các chức năng Get_UNCPath
trên, chúng ta có thể cải thiện chức năng Get_JunctionTarget
như sau :
function Global:Get_JunctionTarget([string]$p_path)
{
$l_target = fsutil reparsepoint query $p_path | where-object { $_ -imatch 'Print Name\:' } | foreach-object { $_ -replace 'Print Name\:\s*','' }
if($l_target -imatch "(^[A-Z])\:\\")
{
$l_drive = $matches[1]
$l_uncPath = Get_UncPath $p_path
if($l_uncPath -imatch "(^\\\\[^\\]*\\)")
{
$l_machine = $matches[1]
$l_target = $l_target -replace "^$l_drive\:","$l_machine$l_drive$"
}
}
$l_target
}
[này trông giống như điều tương tự.] (Http://techibee.com/powershell/read-target-folder-of-a-symlink-using-powershell/1916) –
@BobLobLaw Trên thực tế đã nhận nó từ http://chrisbensen.blogspot.ru/2010/06/getfinalpathnamebyhandle.html – Josh
Cảm ơn, nó đã hoạt động!Tôi cảm thấy rằng tôi phải phàn nàn về những nỗ lực cần thiết để có được một cái gì đó đơn giản như một mục tiêu của ngã ba, nhưng đó không phải là lỗi của bạn ... thịt bò của tôi với sức mạnh. – ash