Create a Hard Link Using PowerShell

Following on the heels of my last article where I talked about creating a symbolic link using PowerShell, I figured I would throw another script out there that will do what mklink.exe does with creating a hard link and do it the PowerShell way.

The process is practically the same as what I did with the symbolic link, so I really don’t want to regurgitate an already existing article.

With mklink.exe, you can do the following to create the hard link in PowerShell:

cmd.exe /c mklink /H C:\users\Administrator\Desktop\WSUSDBMaint `
C:\Users\Administrator\Downloads\Invoke-WSUSDBMaintenance.ps1

image

Once again, I am going to use the kernel32 and the CreateHardLink function this time.

image

Using the given code example, I am able to add this as a type in my PowerShell session.

Add-Type @"
using System;
using System.Runtime.InteropServices;
 
namespace mklink
{
    public class hardlink
    {
        [DllImport("Kernel32.dll")]
        public static extern bool CreateHardLink(string lpFileName,string lpExistingFileName,IntPtr lpSecurityAttributes);
    }
}
"@

 

The main difference with using this vs. using the CreateSymbolicLink function mentioned in my previous article are the parameters expected.

image

I need a target name, the existing file (no directories allowed this time!) that will be used for the hard link and then I need to supply something for the System.IntPtr (in this case, I just use [IntPtr]:Zero). Nothing too crazy that can’t easily be made into a function. When used, it will return a boolean value, much like CreateSymbolicLink.

[mklink.hardlink]::CreateHardLink(
    'C:\users\Administrator\Desktop\WSUSDBMaint',
    'C:\Users\Administrator\Downloads\Invoke-WSUSDBMaintenance.ps1',
    [IntPtr]::Zero
)

image

This leads us down to the function itself!

New-HardLink -Path C:\PortQry.exe -HardLink Portqry.exe -Verbose

image

Will it work?

image

Yes, it works as advertised. So with that, the script is available to download below at the Script Repository. Check it out and let me know what you think!

Download

Script Repository

This entry was posted in powershell, scripts and tagged , , , , . Bookmark the permalink.

2 Responses to Create a Hard Link Using PowerShell

  1. Hi Bo,

    Thanks for this article. I wanted to get a nice exception when creation fails so I added the SetLastError attribute to the DLL import along with a wrapper function to throw the exception:

        public class hardlink
        {
            // SetLastError: tell the .NET runtime to capture the last Win32
            // error if it fails
            [DllImportAttribute("Kernel32.dll", SetLastError = true)]
            public static extern bool CreateHardLink(string lpFileName,string lpExistingFileName,IntPtr lpSecurityAttributes);
    
            // Wrapper for CreateHardLink() that throws an exception on failure.
            // Done in C# rather than in PowerShell to ensure PowerShell
            // internals don't clobber the error.
            public static void CreateHardLinkOrThrow(string lpFileName,string lpExistingFileName,IntPtr lpSecurityAttributes)
            {
                if (!CreateHardLink(lpFileName, lpExistingFileName, lpSecurityAttributes)) {
                    throw new System.ComponentModel.Win32Exception();
                }
            }
        }
    

    You can see the full script here: https://gist.github.com/mzs-github/09df37aabd89149c3831

Leave a comment