≡ Menu

Read target folder of a symlink using Powershell

The code provided in this post will help you to get the target folder configured for a symlink. This the folder to which your symlink will redirect(or I should say proxy) when you access the symlink folder.

function Get-SymlinkTaregetDirectory {            
[cmdletbinding()]            
param(            
[string]$SymlinkDir            
)            
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            

[System.Win32]::GetSymbolicLinkTarget($SymlinkDir)            
}

Usage:

Get-SymlinkTargetDirectory -SymlinkDir c:\mytemp

Hope this helps.