diff --git a/CHANGELOG.md b/CHANGELOG.md index ed30f29..9fc8653 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -89,6 +89,14 @@ The format is based on `-ErrorAction Stop` - Name the computer in the warning of `Get-NTFSEffectiveAccess` when the computer of `-ServerName` can't be reached +- Document that `Get-NTFSHardLink` and `New-NTFSHardLink -PassThru` fail for + a path whose root isn't the root of the volume that holds the file, such + as a path on a drive made with `subst`. `Get-NTFSHardLink` writes a + `FileNotFound` error for a file that exists, and + `New-NTFSHardLink -PassThru` creates the link and then stops with a + `FileNotFoundException`. A volume that is mounted into a folder, and a + junction or symbolic link to another volume, probably fail the same way. + Use a path that starts at the root of the volume ### Deprecated diff --git a/Docs/Cmdlets/Get-NTFSHardLink.md b/Docs/Cmdlets/Get-NTFSHardLink.md index b1aefef..d3e37c9 100644 --- a/Docs/Cmdlets/Get-NTFSHardLink.md +++ b/Docs/Cmdlets/Get-NTFSHardLink.md @@ -104,6 +104,8 @@ Hard links exist only within a single NTFS volume. Every object that this cmdlet Windows can't list the names of a file on a network share, also when the share lies on an NTFS volume of the file server. For such a file the cmdlet writes a non-terminating `GetHardLinkError` with the message "The request is not supported" and continues with the next path; run the cmdlet on the file server itself instead. Before 5.0.0, a file on a network share and a folder stopped the cmdlet with a terminating error, so that it skipped the remaining paths. +The cmdlet combines the names that the file system reports with the root of the path that you pass in, which is right only when that root is the root of the volume that holds the file. For a path on a drive that you made with `subst`, the cmdlet writes a non-terminating `FileNotFound` error for a file that exists and returns no object; use `D:\Data\Report.txt` instead of `Z:\Report.txt` for the drive `Z:` that `subst Z: D:\Data` made. A volume that is mounted into a folder, and a junction or a symbolic link to another volume, probably behave the same way. Use a path that starts at the root of the volume. + Because all hard links of a file share the same data, they also share the file content, the file size, and the time stamps. The security descriptor is stored with the file as well, so changing permissions through one name changes them for every name. The cmdlet resolves paths through the AlphaFS library and therefore also works with paths that exceed the 260-character `MAX_PATH` limit. diff --git a/Docs/Cmdlets/New-NTFSHardLink.md b/Docs/Cmdlets/New-NTFSHardLink.md index 818cb7a..1b92041 100644 --- a/Docs/Cmdlets/New-NTFSHardLink.md +++ b/Docs/Cmdlets/New-NTFSHardLink.md @@ -150,6 +150,8 @@ Windows supports hard links only for files on the same NTFS volume. A link that The cmdlet creates hard links on a network share as well, but Windows can't list the names of a file there. With `-PassThru` on a share, the cmdlet creates the link and writes a non-terminating `GetHardLinkError` with the message "The request is not supported" instead of the objects. Before 5.0.0, it stopped with a terminating error after it had created the link. +With `-PassThru`, the cmdlet lists the names of the file like `Get-NTFSHardLink` and has its limit: when the root of `-Path` isn't the root of the volume that holds the file, such as for a drive that you made with `subst`, the cmdlet creates the link and then stops with a terminating `System.IO.FileNotFoundException`. The objects are missing, and the links that follow in the pipeline aren't created. A volume that is mounted into a folder, and a junction or a symbolic link to another volume, probably behave the same way. Use a path that starts at the root of the volume, or leave out `-PassThru`. + The cmdlet does not overwrite anything. If `-Path` already exists, if `-Target` is missing or is a folder, or if a path contains a character that Windows doesn't allow, such as `|`, the cmdlet writes a non-terminating `CreateHardLinkError` with the category `ResourceExists`, `ObjectNotFound`, or `InvalidArgument`, leaves the file system unchanged, and continues with the next object from the pipeline. It checks `-Path` before `-Target`, and the error for an existing `-Path`, a missing `-Target`, or a folder as `-Target` names that path. When Windows refuses the link, such as for a target on another volume, the cmdlet writes a `CreateHardLinkError` as well. Because all names of a file share the same data, the number of hard links is a property of the file, not of an individual name. Use `Get-NTFSHardLink` to list them, and delete a link with `Remove-Item2` or `Remove-Item`, which removes only that name as long as other names remain. diff --git a/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml b/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml index e440a11..ab38c39 100644 --- a/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml +++ b/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml @@ -5307,6 +5307,7 @@ PS C:\> Get-NTFSAudit -SecurityDescriptor $sd Hard links exist only within a single NTFS volume. Every object that this cmdlet returns therefore refers to a path on the volume of the file that you passed in. Windows can't list the names of a file on a network share, also when the share lies on an NTFS volume of the file server. For such a file the cmdlet writes a non-terminating `GetHardLinkError` with the message "The request is not supported" and continues with the next path; run the cmdlet on the file server itself instead. Before 5.0.0, a file on a network share and a folder stopped the cmdlet with a terminating error, so that it skipped the remaining paths. + The cmdlet combines the names that the file system reports with the root of the path that you pass in, which is right only when that root is the root of the volume that holds the file. For a path on a drive that you made with `subst`, the cmdlet writes a non-terminating `FileNotFound` error for a file that exists and returns no object; use `D:\Data\Report.txt` instead of `Z:\Report.txt` for the drive `Z:` that `subst Z: D:\Data` made. A volume that is mounted into a folder, and a junction or a symbolic link to another volume, probably behave the same way. Use a path that starts at the root of the volume. Because all hard links of a file share the same data, they also share the file content, the file size, and the time stamps. The security descriptor is stored with the file as well, so changing permissions through one name changes them for every name. The cmdlet resolves paths through the AlphaFS library and therefore also works with paths that exceed the 260-character `MAX_PATH` limit. @@ -7191,6 +7192,7 @@ PS C:\Data> Get-NTFSSecurityDescriptor Windows supports hard links only for files on the same NTFS volume. A link that points to a file on another volume, or a target on a file system that does not implement hard links, cannot be created. The cmdlet creates hard links on a network share as well, but Windows can't list the names of a file there. With `-PassThru` on a share, the cmdlet creates the link and writes a non-terminating `GetHardLinkError` with the message "The request is not supported" instead of the objects. Before 5.0.0, it stopped with a terminating error after it had created the link. + With `-PassThru`, the cmdlet lists the names of the file like `Get-NTFSHardLink` and has its limit: when the root of `-Path` isn't the root of the volume that holds the file, such as for a drive that you made with `subst`, the cmdlet creates the link and then stops with a terminating `System.IO.FileNotFoundException`. The objects are missing, and the links that follow in the pipeline aren't created. A volume that is mounted into a folder, and a junction or a symbolic link to another volume, probably behave the same way. Use a path that starts at the root of the volume, or leave out `-PassThru`. The cmdlet does not overwrite anything. If `-Path` already exists, if `-Target` is missing or is a folder, or if a path contains a character that Windows doesn't allow, such as `|`, the cmdlet writes a non-terminating `CreateHardLinkError` with the category `ResourceExists`, `ObjectNotFound`, or `InvalidArgument`, leaves the file system unchanged, and continues with the next object from the pipeline. It checks `-Path` before `-Target`, and the error for an existing `-Path`, a missing `-Target`, or a folder as `-Target` names that path. When Windows refuses the link, such as for a target on another volume, the cmdlet writes a `CreateHardLinkError` as well. Because all names of a file share the same data, the number of hard links is a property of the file, not of an individual name. Use `Get-NTFSHardLink` to list them, and delete a link with `Remove-Item2` or `Remove-Item`, which removes only that name as long as other names remain. Before 5.0.0, the error for a missing `-Target` said "The target path exist", the opposite of the cause.