Last active
January 27, 2022 02:53
-
-
Save rkitover/28a811e4ff9e0a9f7da144f6a87b8cb1 to your computer and use it in GitHub Desktop.
ver and mklink $profile functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function ver_windows { | |
$osver = [environment]::osversion.version | |
$major = $osver.major | |
$build = $osver.build | |
if ($major -eq 10 -and $build -gt 22000) { | |
$major = 11 | |
} | |
try { | |
$arch = [System.Runtime.InteropServices.RuntimeInformation,mscorlib]::OSArchitecture | |
} catch {} | |
'Windows {0} build {1}{2}' ` | |
-f $major, | |
$build, | |
$(if ($arch) { " $arch" }) | |
} | |
function global:ver { | |
if ($iswindows) { | |
ver_windows | |
} | |
else { | |
$uname_parts = $(if ($islinux) { 'sri' } | |
elseif ($ismacos) { 'srm' } | |
).getenumerator() | %{ uname "-$_" } | |
# Remove -xxx-xxx suffixes from kernel versions. | |
if ($islinux) { | |
$uname_parts[1] = $uname_parts[1] -replace '-.*','' | |
} | |
"{0} kernel {1} {2}" -f $uname_parts | |
} | |
} | |
function global:mklink { | |
$usage = 'args: [link] target' | |
$args = $args | %{ $_ } | ? length | |
if (-not $args) { $args = @($input) } | |
while ($args.count -gt 2 -and $args[0] -match '^/[A-Z]$') { | |
$null,$args = $args | |
} | |
if (-not $args -or $args.count -gt 2) { | |
write-error $usage -ea stop | |
} | |
$link,$target = $args | |
if (-not $target) { | |
$target = $link | |
if (-not (split-path -parent $target)) { | |
write-error ($usage + "`n" + 'cannot make link with the same name as target') -ea stop | |
} | |
$link = split-path -leaf $target | |
} | |
if (-not ($link_parent = split-path -parent $link)) { | |
$link_parent = get-location | % path | |
} | |
if (-not ($target_parent = split-path -parent $target)) { | |
$target_parent = get-location | % path | |
} | |
$link_parent = try { | |
$link_parent | resolve-path -ea stop | % path | |
} | |
catch { write-error $_ -ea stop } | |
if (-not (resolve-path $target -ea ignore)) { | |
write-warning "target '${target}' does not yet exist" | |
} | |
$absolute = @{ | |
link = join-path $link_parent (split-path -leaf $link) | |
target = join-path $target_parent (split-path -leaf $target) | |
} | |
$home_dir_re = [regex]::escape($home) | |
$dir_sep_re = [regex]::escape($dir_sep) | |
$in_home = @{} | |
$absolute.getenumerator() | %{ | |
if ($_.value -match ('^'+$home_dir_re+"($dir_sep_re"+'|$)')) { | |
$in_home[$_.key] = $true | |
} | |
} | |
# If target is in home, make sure ~ is resolved. | |
# | |
# Make sure relative links are relative to link parent | |
# (::ispathrooted() does not understand ~ paths and considers | |
# them relative.) | |
# | |
# And if both link and target are in home dir, force relative | |
# link, this is to make backups/copies/moves and SMB shares of | |
# the home/profile dir easier and less error-prone. | |
$target = if (-not ( | |
$in_home.target ` | |
-or [system.io.path]::ispathrooted($target) | |
) -or $in_home.count -eq 2) { | |
pushd $link_parent | |
resolve-path -relative $absolute.target | |
popd | |
} | |
else { | |
$absolute.target | |
} | |
if (-not $iswindows -or $psversiontable.psversion.major -ge 6) { | |
# PSCore. | |
try { | |
new-item -itemtype symboliclink $absolute.link ` | |
-target $target -ea stop | |
} | |
catch { write-error $_ -ea stop } | |
} | |
else { | |
# WinPS or older. | |
$params = @( | |
if (test-path -pathtype container $target) { '/D' } | |
) | |
cmd /c mklink @params $absolute.link $target | |
if (-not $?) { write-error "exited: $LastExitCode" -ea stop } | |
} | |
} | |
function global:rmlink { | |
$args = @($input),$args | %{ $_ } | ? length | |
if (-not $args) { | |
write-error 'args: link1 [link2 ...]' -ea stop | |
} | |
$args | %{ | |
try { $_ = gi $_ -ea stop } | |
catch { write-error $_ -ea stop } | |
if (-not $_.target) { | |
write-error "$_ is not a symbolic link" -ea stop | |
} | |
if ((test-path -pathtype container $_) ` | |
-and $iswindows ` | |
-and $psversiontable.psversion.major -lt 7) { | |
# In WinPS remove-item does not work for dir links. | |
cmd /c rmdir $_ | |
if (-not $?) { write-error "exited: $LastExitCode" -ea stop } | |
} | |
else { | |
try { ri $_ } | |
catch { write-error $_ -ea stop } | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment