Pin program to taskbar using PS in Windows 10

Pin program to taskbar using PS in Windows 10

I am trying to pin a program to the taskbar in Windows 10 (RTM) using this code:
$shell = new-object -com “Shell.Application”
$folder = $shell.Namespace((Join-Path $env:SystemRoot System32\WindowsPowerShell\v1.0))
$item = $folder.Parsename(‘powershell_ise.exe’)
$item.invokeverb(‘taskbarpin’);

This worked on Windows 8.1, but no longer works on Windows 10.
If I execute $item.Verbs(), I get these:
Application Parent Name
———– —— —-
&Open
Run as &administrator
&Pin to Start

Restore previous &versions

Cu&t
&Copy
Create &shortcut
&Delete
Rena&me
P&roperties

As you can see, there is no verb for pinning it to the taskbar. If I right click that specific file, however, the option is there:

Questions:
Am I missing something?
Is there a new way in Windows 10 to pin a program to the taskbar?

Solutions/Answers:

Solution 1:

Here’s Humberto’s vbscript solution ported to PowerShell:

Param($Target)

$KeyPath1  = "HKCU:\SOFTWARE\Classes"
$KeyPath2  = "*"
$KeyPath3  = "shell"
$KeyPath4  = "{:}"
$ValueName = "ExplorerCommandHandler"
$ValueData = (Get-ItemProperty("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\" +
  "Explorer\CommandStore\shell\Windows.taskbarpin")).ExplorerCommandHandler

$Key2 = (Get-Item $KeyPath1).OpenSubKey($KeyPath2, $true)
$Key3 = $Key2.CreateSubKey($KeyPath3, $true)
$Key4 = $Key3.CreateSubKey($KeyPath4, $true)
$Key4.SetValue($ValueName, $ValueData)

$Shell = New-Object -ComObject "Shell.Application"
$Folder = $Shell.Namespace((Get-Item $Target).DirectoryName)
$Item = $Folder.ParseName((Get-Item $Target).Name)
$Item.InvokeVerb("{:}")

$Key3.DeleteSubKey($KeyPath4)
if ($Key3.SubKeyCount -eq 0 -and $Key3.ValueCount -eq 0) {
    $Key2.DeleteSubKey($KeyPath3)
}

Solution 2:

Sorry to resurrect something so old.

I do not know how to do this in powershell, but in vbscript you can do this method that I developed. It works regardless of the system language.

Works on windows 8.x and 10.

Script

If WScript.Arguments.Count < 1 Then WScript.Quit
'----------------------------------------------------------------------
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFile    = WScript.Arguments.Item(0)
sKey1      = "HKCU\Software\Classes\*\shell\{:}\\"
sKey2      = Replace(sKey1, "\\", "\ExplorerCommandHandler")
'----------------------------------------------------------------------
With WScript.CreateObject("WScript.Shell")
    KeyValue = .RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer" & _
        "\CommandStore\shell\Windows.taskbarpin\ExplorerCommandHandler")

    .RegWrite sKey2, KeyValue, "REG_SZ"

    With WScript.CreateObject("Shell.Application")
        With .Namespace(objFSO.GetParentFolderName(objFile))
            With .ParseName(objFSO.GetFileName(objFile))
                .InvokeVerb("{:}")
            End With
        End With
    End With

    .Run("Reg.exe delete """ & Replace(sKey1, "\\", "") & """ /F"), 0, True
End With
'----------------------------------------------------------------------

Command line:

pin and unpin: taskbarpin.vbs [fullpath]

Example: taskbarpin.vbs "C:\Windows\notepad.exe"
Related:  Is an exception from a .NET method a terminating or not-terminating error?

Solution 3:

Very nice! I made a few small tweaks to that powershell example, I hope you don’t mind 🙂

param (
    [parameter(Mandatory=$True, HelpMessage="Target item to pin")]
    [ValidateNotNullOrEmpty()]
    [string] $Target
)
if (!(Test-Path $Target)) {
    Write-Warning "You freaking dumbass!!! $Target does not exist"
    break
}

$KeyPath1  = "HKCU:\SOFTWARE\Classes"
$KeyPath2  = "*"
$KeyPath3  = "shell"
$KeyPath4  = "{:}"
$ValueName = "ExplorerCommandHandler"
$ValueData =
    (Get-ItemProperty `
        ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\" + `
            "CommandStore\shell\Windows.taskbarpin")
    ).ExplorerCommandHandler

$Key2 = (Get-Item $KeyPath1).OpenSubKey($KeyPath2, $true)
$Key3 = $Key2.CreateSubKey($KeyPath3, $true)
$Key4 = $Key3.CreateSubKey($KeyPath4, $true)
$Key4.SetValue($ValueName, $ValueData)

$Shell = New-Object -ComObject "Shell.Application"
$Folder = $Shell.Namespace((Get-Item $Target).DirectoryName)
$Item = $Folder.ParseName((Get-Item $Target).Name)
$Item.InvokeVerb("{:}")

$Key3.DeleteSubKey($KeyPath4)
if ($Key3.SubKeyCount -eq 0 -and $Key3.ValueCount -eq 0) {
    $Key2.DeleteSubKey($KeyPath3)
}

Solution 4:

In windows 10 Microsoft added a simple check before showing the verb. The name of the executable must be explorer.exe. It can be in any folder, just the name is checked. So the easy way in C# or any compiled program would be just to rename your program.

If that’s not possible, you can fool the shell object in to thinking your program is called explorer.exe. I wrote a post here on how to do it in C# by changing the Image Path in the PEB.

Solution 5:

I have the same problem and I still do not know how to handle it, but this little command line tool does:

http://www.technosys.net/products/utils/pintotaskbar

You can use it in command line like that:

syspin "path/file.exe" c:5386

to pin a program to taskbar and

syspin "path/file.exe" c:5387

to unpin it. This works fine for me.

References