I Should Have Done This Years Ago (New-Shortcut, Revisited)

In spite of having this blog, sometimes I rewrite a function because I forgot I wrote it already.  Case in point, New-Shortcut.  It was one of my earlier entries in this blog:

https://blogs.msdn.com/b/timid/archive/2009/09/06/powershell-for-non-n00bs-symlinks.aspx

However, the “I should have done this years ago” refers to something else – the fact that I should auto-populate shortcuts for TaskMgr.exe and PowerShell.exe on my Desktop and my StartUp folder on all my machines.

Desktop is $home\Desktop.  The StartUp folder was hidden long ago under $env:AppData, specifically “$env:AppData\Microsoft\Windows\Start Menu\Programs\Startup”.

With this, it becomes as simple as:

 @(‘taskmgr’, ‘powershell’) |
% {

    $exe = "$_.exe";
    $lnk = "$_.lnk";

    @("$home\Desktop", "$env:AppData\Microsoft\Windows\Start Menu\Programs\Startup") |
    % {

        if(!(Test-Path -Path "$_\$lnk"))
        {

            New-Shortcut -Target $exe -Path $_;

        }

    }

}

Or, if you don't value readability:

@(‘taskmgr’, ‘powershell’) | % { $exe = "$_.exe"; $lnk = "$_.lnk"; @("$home\Desktop", "$env:AppData\Microsoft\Windows\Start Menu\Programs\Startup") | % { if(!(Test-Path -Path "$_\$lnk")) { New-Shortcut -Target $exe -Path $_; } } }

That's much handier for copy-pasting into a window, though most of this is going into my Grand Unified $PROFILE:

https://blogs.msdn.com/b/timid/archive/2014/02/05/profile-and-rdp-sessions.aspx

 function New-Shortcut
{
    param (
        [string]$Target = $null,
        [string]$Path = (Get-Location),
        [object[]]$Arguments = @()
    );

    #region Massage -Target value

    if (!$Target) 
    {
        Write-warning "$($MyInvocation.MyCommand.Name) -Target not specified, required.  Stopping.";
        return;

    } # if (!$Target)

    $_target = $Target;

    if (Test-Path $_target)
    {
        $_target = (Resolve-Path $_target).ProviderPath;

    } # if (Test-Path $_target)
    elseif ($_target = (Get-Command $Target -ErrorAction SilentlyContinue).Path)
    {
        # no-op.  negative logic is harder to read, hence this dead-end branch.

    } # elseif ($_target = (Get-Command $Target -ErrorAction SilentlyContinue).Path)
    else
    {
        Write-warning "$($MyInvocation.MyCommand.Name) -Target '$Target' not found.  Stopping.";
        return;

    } # if (Test-Path $_target)
    
    #endregion
    #region Massage -Path value    

    $_path = $Path;

    if ((Test-Path $_path) -and (Get-Item $_path).PsIsContainer)
    {
        $_path = Join-Path -Path $_path -ChildPath "$((Split-Path -Leaf $_target) -replace '\.[^\.]*$', '.lnk')";

    } # if ((Test-Path $_path) -and (Get-Item $_path).PsIsContainer)

    if ($_path -notmatch '\.lnk$')
    {
        $_path += ".lnk";

    } # if ($_path -notmatch '\.lnk$')

    if (Test-Path $_path)
    {
        $_path = (Resolve-Path $_path).ProviderPath;
        Write-Warning "$() -Target '$Target' -Path '$path' resolves path to '$_path', which exists.  Stopping.";
        return;

    } # if (Test-Path $_path)
    else
    {
        md $_path | Out-Null;
        $_path = (Resolve-Path $_path).ProviderPath;
        rm $_path;

    } # if (Test-Path $_path)

    #endregion
    #region make the shortcut
    
    $shortcut = (New-Object -ComObject WScript.Shell).CreateShortcut($_path);
    $shortcut.TargetPath = $_target;

    if ($Arguments.Count)
    {
        $shortcut.Arguments = $arguments;

    } # if ($Arguments.Count)

    $shortcut.Save();

    if (Test-Path $_path)
    {
        Write-Host -ForegroundColor Green -BackgroundColor Black "$_path created";

    } # if (Test-Path $Path)
    else
    {
        Write-Warning "$($MyInvocation.MyCommand.Name) -Target '$Target' -Path '$Path' failed to create file '$_path'.";

    } # if (Test-Path $Path) ... else

} # function New-Shortcut