1) Create a hard link between 2 files
2) run command gci | ? { $_.LinkType } | Select FullName, LinkType, Target from Powershell V5
3) run same command from powershell core.
New-Item -ItemType HardLink -Path C:\ -Name cdl.txt -Value C:\ComponentDetectionLog.txt
gci | ? { $_.LinkType } | Select FullName, LinkType, Target
Target array returns all linked files.
Target array is empty on Windows PWSH 6.2.3
PS c:> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.18362.145
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.18362.145
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
PS c:> gci | ? { $_.LinkType } | Select FullName, LinkType, Target
FullName LinkType Target
-------- -------- ------
C:\cdl.txt HardLink {C:\ComponentDetectionLog.txt}
C:\ComponentDetectionLog.txt HardLink {C:\cdl.txt}
Powershell Core
c:> gci | ? { $_.LinkType } | Select FullName, LinkType, Target
FullName LinkType Target
-------- -------- ------
C:\cdl.txt HardLink {}
C:\ComponentDetectionLog.txt HardLink {}
C:> $PSVersionTable
Name Value
---- -----
PSVersion 6.2.3
PSEdition Core
GitCommitId 6.2.3
OS Microsoft Windows 10.0.18363
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
You should use childrenWithHardlink format view.
Hardlinks was removed from default format output due to performance. See https://github.com/PowerShell/PowerShell/pull/8789
C:s> gci | ft -view childrenWithHardLink
ft : The view name childrenWithHardLink cannot be found. Specify one of the following Table views and try again: children.
I get the same output with both powershell versions listed in the original issue post. In what versions should this work? Or do I need to import something to my session?
Even if this does work, how would a normal person EVER discover this feature?
You could try latest 7.0 RC build (we expect the release in month).
Even if this does work, how would a normal person EVER discover this feature?
It is already documented https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-7
Also you could open new issue to request tab completion for View parameter.
The Get-ChildItem cmdlet gets the items in one or more specified locations. If the item is a container, it gets the items inside the container, known as child items. You can use the Recurse parameter to get items in all child containers and use the Depth parameter to limit the number of levels to recurse. Get-ChildItem does not display empty directories. When a Get-ChildItem command includes the Depth or Recurse parameters, empty directories are not included in the output. Locations are exposed to Get-ChildItem by PowerShell providers. A location can be a file system directory, registry hive, or a certificate store. For more information, see about_Providers.
This issue has been marked as answered and has not had any activity for 1 day. It has been closed for housekeeping purposes.
Not working even with RC2.
@psmitt Please add more info that does not work for you.
I still cannot display Target information for hard links, not even with Format-Table.
Here is to reproduce:
PS C:\Temp> New-Item -ItemType File test1.txt
PS C:\Temp> New-Item -ItemType HardLink test2.txt -Value test1.txt
PS C:\Temp> Get-ChildItem | Format-Table -View childrenWithHardLink # will not display Target
PS C:\Temp> Get-ChildItem | Format-Table -Property Mode, Name, LinkType, Target # will display empty Target
Question1: how to display hardlink targets?
Question2: is there any way in PowerShell to check if two hardlinks target the same file?
Target makes sense only for symbolic links. You will see only mode:
la--- 1/27/2020 4:32 PM 0 test1.txt
la--- 1/27/2020 4:32 PM 0 test2.txt
Please read again the original issue: it is pointing out exactly that hardlink targets are diplayed properly in older versions (even in MS PowerShell), and the question is why that behaviour changed. Is there any way to identify which hardlinks refer to the same file?
@psmitt The behavior was changed because (1) performance, (2) portability (Windows and Unix API work different).
is there any way in PowerShell to check if two hardlinks target the same file?
It is internal API. You can see source code to see how it is implemented starting with nternal static bool IsHardLink(FileSystemInfo fileInfo).
This feels like a breaking change to me. A very useful feature of PS 5 has been removed. I will admit the usage is likely lower than other but now I have to find a non-PS way to fix some scripts. I can see not pulling in hardlinks by default. But when they are specifically requested it seems like the caller must be willing to pay whatever performance penalty there is. I'm only a casual *nix user but I seem to recall similar behavior there.
Please consider a feature to re-enable this on demand. Lowest-Common-Denominator should not mean removing useful features just because they are hard to implement across platforms or are perceived as "slow." However many hours I have to spend finding a new way, fixing broken scripts will probably never equal whatever time difference it takes to retrieve the data. It sounds like I would have to discover the issue (already did), find the new parameter (alas!) and save all my scripts anyway.
I see your point but ... Really we already have dozen of a breaking changes from Windows PowerShell to PowerShell Core. Although the policy is to avoid such changes, product evolution makes them sometimes inevitable.
The breaking change already was made and changing Target property behavior/type would again be a breaking change in 3 year old product.
And the feature must work in the same way on all supported platforms. NTFS allows easily get all targets for the hardlink. I don't found the same API on Unix, all examples say about full enumerating that is extremely slow. Apparently, therefore, symlinks are more preferable in practice and therefore I prefer current Target property behavior (show symlink target).
The feature request looks like an edge case otherwise we would have better underlying API support in .Net Core and OS APIs.
Perhaps @mklement0 has an idea how resolve this. Maybe Windows-only cmdlet like Get-HardLinkPath?
For Linux:
https://unix.stackexchange.com/questions/398434/why-no-file-name-in-inode-information
https://superuser.com/questions/12972/how-can-you-see-the-actual-hard-link-by-ls
For NTFS:
https://stackoverflow.com/questions/4193309/list-hard-links-of-a-file-in-c
https://stackoverflow.com/questions/4510269/c-sharp-count-and-list-hardlink-locations-of-a-file
https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstfilenamew
Unix & Linux Stack ExchangeI know that symlinks have a separated inode from the original file and that they only point for the inode containing the data. My question is, where is the hardlink name stored if there's no field ...
Super UserI run ln /a/A /b/B I would like to see at the folder a where the file A points to by ls.
Stack OverflowI want to write a program that shows the files of an other drive with hard links. I want to keep both hardlinks consistent in filename and other things so I have to get a function/method where I ca...
Stack OverflowI'm currently searching for a C# solution which can read the number of hardlinks of a file and their links locations. I'm thinking of the program link shell extension which can do this by going to ...
Creates an enumeration of all the hard links to the specified file. The FindFirstFileNameW function returns a handle to the enumeration that can be used on subsequent calls to the FindNextFileNameW function.
Most helpful comment
This feels like a breaking change to me. A very useful feature of PS 5 has been removed. I will admit the usage is likely lower than other but now I have to find a non-PS way to fix some scripts. I can see not pulling in hardlinks by default. But when they are specifically requested it seems like the caller must be willing to pay whatever performance penalty there is. I'm only a casual *nix user but I seem to recall similar behavior there.
Please consider a feature to re-enable this on demand. Lowest-Common-Denominator should not mean removing useful features just because they are hard to implement across platforms or are perceived as "slow." However many hours I have to spend finding a new way, fixing broken scripts will probably never equal whatever time difference it takes to retrieve the data. It sounds like I would have to discover the issue (already did), find the new parameter (alas!) and save all my scripts anyway.