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
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 { [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.
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 )
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!
Download
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:
You can see the full script here: https://gist.github.com/mzs-github/09df37aabd89149c3831
Awesome! Nice addition to the function!