在PowerShell中,我需要解析結點(符號鏈接)的目標路徑。powershell解決目標路徑結點
例如,說我有一個結c:\someJunction
其目標是c:\temp\target
我試過的$junc = Get-Item c:\someJunction
變化,但只能得到c:\someJunction
如何找到交界的目標路徑,以給定交叉點的這個例子c:\temp\target
?
在PowerShell中,我需要解析結點(符號鏈接)的目標路徑。powershell解決目標路徑結點
例如,說我有一個結c:\someJunction
其目標是c:\temp\target
我試過的$junc = Get-Item c:\someJunction
變化,但只能得到c:\someJunction
如何找到交界的目標路徑,以給定交叉點的這個例子c:\temp\target
?
您可以通過執行得到以下路徑:
Get-ChildItem -Path C:\someJunction
編輯查找路徑和文件夾
Add-Type -MemberDefinition @"
private const int FILE_SHARE_READ = 1;
private const int FILE_SHARE_WRITE = 2;
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
if (path[0] == '\\' && path[1] == '\\' && path[2] == '?' && path[3] == '\\')
return path.ToString().Substring(4);
else
return path.ToString();
}
"@ -Name Win32 -NameSpace System -UsingNamespace System.Text,Microsoft.Win32.SafeHandles,System.ComponentModel
$dir = Get-Item D:\1
[System.Win32]::GetSymbolicLinkTarget($dir)
該做的伎倆用更少的工作沒有內容,甚至可以用於遠程服務器上的路口:
fsutil reparsepoint query "M:\Junc"
如果您只想目標名稱:
fsutil reparsepoint query "M:\Junc" | where-object { $_ -imatch 'Print Name:' } | foreach-object { $_ -replace 'Print Name\:\s*','' }
所以
function Get_JunctionTarget($p_path)
{
fsutil reparsepoint query $p_path | where-object { $_ -imatch 'Print Name:' } | foreach-object { $_ -replace 'Print Name\:\s*','' }
}
此外,下面的代碼是喬希上面提供的代碼稍加修改。它可以被放置在被多次讀取一個文件,並在網絡驅動器的情況下,正確處理主導\\?\
:
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)
}
並給予上述功能Get_UNCPath
,我們可以改善功能Get_JunctionTarget
如下:
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
}
謝謝......第一個命令對我非常有效。它花了一些時間才意識到輸出包括路徑的十六進制字節......以及ascii路徑(在右邊)。 – Xantix
我們最終使用此功能
function Get-SymlinkTargetDirectory {
[cmdletbinding()]
param(
[string]$SymlinkDir
)
$basePath = Split-Path $SymlinkDir
$folder = Split-Path -leaf $SymlinkDir
$dir = cmd /c dir /a:l $basePath | Select-String $folder
$dir = $dir -join ' '
$regx = $folder + '\ *\[(.*?)\]'
$Matches = $null
$found = $dir -match $regx
if ($found) {
if ($Matches[1]) {
Return $Matches[1]
}
}
Return ''
}
只有像'C:\ Users \ Joe \ SendTo'這樣的系統重新分析點的解決方案afaict – Frank
已增強New-Item,Remove-Item和Get-ChildItem以支持創建和管理符號鏈接。 New-Item的-ItemType參數接受一個新值SymbolicLink。現在,您可以通過運行New-Item cmdlet在一行中創建符號鏈接。
What's New in Windows PowerShell
我檢查了我的Windows 7機器上的符號鏈接的支持,它的正常工作。
> New-Item -Type SymbolicLink -Target C: -Name TestSymlink
Directory: C:\Users\skokhanovskiy\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----l 06.09.2016 18:27 TestSymlink
獲得符號鏈接的目標和創建目標一樣簡單。
> Get-Item .\TestSymlink | Select-Object -ExpandProperty Target
C:\
呵呵。謝謝你。我將不得不進行調查。 –
[這看起來一樣的東西。(http://techibee.com/powershell/read-target-folder-of-a-symlink-using-powershell/1916) –
@BobLobLaw實際上得到了它從http://chrisbensen.blogspot.ru/2010/06/getfinalpathnamebyhandle.html – Josh
謝謝,它的工作!我覺得我必須抱怨爲了得到像路口目標目標這樣簡單的東西所需的努力,但這不是你的錯......我的牛肉與力量。 – ash