In PowerShell, I need resolve the target path of a junction (symlink).
for example, say I have a junction c:\someJunction
whose target is c:\temp\target
I tried variations of $junc = Get-Item c:\someJunction
, but was only able to get c:\someJunction
How do I find the target path of the junction, in this example c:\temp\target
, of a given junction?
New-Item, Remove-Item, and Get-ChildItem have been enhanced to support creating and managing symbolic links. The -ItemType parameter for New-Item accepts a new value, SymbolicLink. Now you can create symbolic links in a single line by running the New-Item cmdlet.
What's New in Windows PowerShell v5
I've checked the symlink support on the my Windows 7 machine, it's works fine.
PS> 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 target of the symbolic link as easy as to create it.
> Get-Item .\TestSymlink | Select-Object -ExpandProperty Target C:\
There are some really complicated answers to this question! Here's a super simple and self explanatory one:
(Get-Item C:\somejunction).Target
You can get the path by doing the following:
Get-ChildItem -Path C:\someJunction
Edit for finding the path and not the contents of the folder
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With