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 `


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


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
        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.


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.



This leads us down to the function itself!

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


Will it work?


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!


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:

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s