Public/New-ItemLink.ps1
function New-ItemLink { [CmdletBinding()] Param ( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [string]$Path , [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [string]$Value , [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [ValidateSet('HardLink', 'Junction', 'SymbolicLink')] [string]$ItemType , [Parameter(Mandatory=$false)] [switch]$Force ) begin { $_errorActionPreference = $ErrorActionPreference $_path = $Path.Trim() $_value = $Value.Trim() if ($env:OS -eq 'Windows_NT') { $_path = $_path -replace "/","\" $_value = $_value -replace "/","\" } }process { try { $ErrorActionPreference = 'Stop' "ItemType: '$($ItemType)', Path: '$($_path)', Value: '$($_value)'" | Write-Verbose $item = Get-Item -Path $_path -Force -ErrorAction SilentlyContinue if ($item) { if (!$item.LinkType) { throw "Existing item '$_path' is not a HardLink, Junction, or SymbolicLink." } if (!$Force) { if ($item.LinkType -eq $ItemType) { # The UNC target of an existing item's .Target is returned in the format 'UNC\*', thus requiring formatting as '\\*' for evaluation $matchInfo = $item.Target | Select-String -Pattern '^UNC\\(.*)' $itemTarget = if ($matchInfo) { "\\$($matchInfo.Matches.Groups[1].Value)" } else { $item.Target } if ($itemTarget -eq $_value) { "Matching item '$_path' already exists. Skipping" | Write-Verbose return } } } # New-Item with -Force cannot override an existing Junction, hence the need to remove the existing Link: Junction, SymbolicLink, or HardLink if ($ItemType -eq 'Junction') { if ($PSVersionTable.PSVersion.Major -le 5) { $item.Delete() # Powershell 5 requires a special way to remove a SymbolicLink, see: https://stackoverflow.com/a/63172492 }else { $item | Remove-Item -Force } } } "Creating item '$_path'" | Write-Verbose New-Item -Path $_path -ItemType $ItemType -Value $_value -Force:$Force }catch { Write-Error -ErrorRecord $_ -ErrorAction $_errorActionPreference } } } |