52

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:
Available verbs in UI

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

vsminkov
  • 10,912
  • 2
  • 38
  • 50
Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
  • 1
    maybe is a case for microsoft connect? It seem that the verb is missing! But a lookup in the regedit seem present! – CB. Jul 30 '15 at 13:47
  • 3
    @CB. Good idea. Here is the report: https://connect.microsoft.com/PowerShell/feedbackdetail/view/1609288/pin-to-taskbar-no-longer-working-in-windows-10 Although, I have a feeling that it might be intentional, to stop programs from "polluting" the taskbar? – Daniel Hilgarth Jul 30 '15 at 14:54
  • 3
    Yes, can be, but anyway Msft must start to documents this kind of change! Ï'll up vote on connect – CB. Jul 30 '15 at 15:36
  • 1
    Eww... I will have a few login scripts to change if this is not resolved by the time we move to win10 in our org. – ATek Jul 31 '15 at 20:07
  • 1
    You call `ParseName` with a lowercase N, since it's a COM object and not a powershell method, it may make a difference. If I right click a folder, I see a 'Pin to Start', but not 'Pin To Taskbar' – Eris Aug 09 '15 at 22:05
  • @Eris No, this doesn't make a difference. And I am not trying to pin a folder but an executable :) – Daniel Hilgarth Aug 26 '15 at 06:01
  • I'm having the same issue. I suspect this is intentionally broken. – Garr Godfrey Aug 27 '15 at 05:22
  • `Join-Path $env:SystemRoot System32\WindowsPowerShell\v1.0` is this still the path for powershell in Win 10? – Jeter-work Nov 03 '15 at 22:09
  • @Xalorous Sure. See screenshot above – Daniel Hilgarth Nov 03 '15 at 22:33
  • @DanielHilgarth Thanks. I see it now. – Jeter-work Nov 04 '15 at 19:12
  • It seems that a shortcut is created in `"$env:appdata\Microsoft\Internet Explorer\Quick Launch\User Pinned\Taskbar\"` folder. That's trivial to do in Powershell but that shortcut itself is not enough. I see that `HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband\**Favorites**` (Reg_Binary) and a couple others in that keys is getting updated as well. I am not sure how that can be updated. – Adil Hindistan Nov 12 '15 at 05:11
  • **This method completely fails on Win 10 21H2 and Windows 11**. Would greatly appreciate if you could modify / update the answer to address the current state of play with Windows? – YorSubs Oct 26 '22 at 09:34

9 Answers9

16

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 "$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)
}
Alex Kwitny
  • 11,211
  • 2
  • 49
  • 71
Skatterbrainz
  • 1,077
  • 5
  • 23
  • 31
  • 1
    First off, THIS IS AWESOME! I hadn't checked back on this thread in a while, so I was super happy to see a PS solution. @Skatterbrainz (or anyone), I am curious about two details. 1: At the end, there is a test to see if the shell key has any contents after the verb key has been deleted. But both of those keys are created earlier. Why the test rather than just using Remove-Item on the shell key with -recurse? – Gordon Sep 23 '18 at 10:55
  • 1
    2: If I use this code and the shortcut is already pinned, it gets unpinned. I kind of expected it to be left alone, i.e. the end result of the verb PinToTaskbar is the current state, so no need to do anything. – Gordon Sep 23 '18 at 10:56
  • 1
    OK, regarding #2, I searched for the GUID found in HKLM, and there is a reference in HKCR with ImplementsVerbs=taskbarpin;taskbarunpin, so that explains the toggle behavior. – Gordon Sep 23 '18 at 11:16
  • 1
    But it raises another question. Is the GUID set in stone, or is it different with different builds of Win10, different languages, etc? If it's always the same, couldn't that just be hard coded rather than finding it in HKLM first? – Gordon Sep 23 '18 at 11:18
  • 1
    I apologize for the slow reply. I've been busy and haven't check back in awhile. I think some GUID's are consistent but some have changed as well. Mostly with changing features like "People" "Phone", etc. But I'm not sure of which are which, exactly. – Skatterbrainz Oct 15 '18 at 19:52
  • Hello, When I run this on a fresh Windows 2016, I see this error: PS C:\Users\Administrator\Documents> .\pinme.ps1 "C:\Windows\System32\notepad.exe" You cannot call a method on a null-valued expression. At C:\Users\Administrator\Documents\pinme.ps1:23 char:1 + $Key3 = $Key2.CreateSubKey($KeyPath3, $true) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull – WubiUbuntu980 Unity7 Refugee Jan 09 '19 at 02:32
  • ugh... well, as of Windows 10 1809 at least, this doesn't appear to work like it did with 1803 and before. I'm working on this to see what changed and if there's a fix. – Skatterbrainz Apr 10 '19 at 20:30
  • works like a charm on Windows Server 2019 Datacanter - thanks – RichJohnstone Mar 05 '20 at 13:43
  • 3
    Windows 10 Pro version 20H2 and this doesn't work. I don't get an error. I don't notice any changes at all. I wonder if I just edited my registry in unknown ways. – Eric Hansen Jan 20 '21 at 02:22
  • 1
    No more luck on Windows 11. – zelocalhost Feb 05 '22 at 17:41
  • 1
    **This method completely fails on Win 10 21H2 and Windows 11**. Would greatly appreciate if you could modify / update the answer to address the current state of play with Windows? – YorSubs Oct 26 '22 at 09:34
9

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.

deru
  • 460
  • 1
  • 4
  • 15
  • 3
    Given the existence of the Technosys EXE, it seems likely that there is an approach that would work in powerShell using some inlined C#. In my case I have a "commercial" need, in that I am managing a conference lab and we put the shortcuts for the session software on the task bar, refreshing between sessions using PowerShell. Hoping to license something if need be. Any suggestions? – Gordon Feb 25 '16 at 11:27
  • 1
    FWIW, the desire to license stems from the Technosys EXE not being signed code, and I would rather pay for signed code than ask people to trust unsigned code. – Gordon Feb 25 '16 at 11:56
  • 1
    Bump. Anyone found a way to do this in C#? Technosys wants $2k to license this tiny feature, which seems excessive. – Gordon May 15 '16 at 23:25
  • True. Noone but Technosys managed to pin an app to Windows 10 taskbar yet. – GeekUser May 18 '16 at 08:19
  • check this link (first solution is not fine but works): https://connect.microsoft.com/PowerShell/feedback/details/1609288/pin-to-taskbar-no-longer-working-in-windows-10 – deru May 18 '16 at 14:30
  • @Gordon look at [this answer](http://stackoverflow.com/a/38880235/733760) for how to do it in C# – AlexDev Aug 10 '16 at 17:47
  • I've been using `syspin.exe` for a few years, and it seems to be the only way that works. **All of the PowerShell methods on this page completely fail on Win 10 21H2 and Windows 11** (presumably Microsoft changed something that broke these solutions). Would greatly appreciate if any C# solution that is found could be posted here so that PowerShell folks could get it in a version suitable for PowerShell scripts. – YorSubs Oct 26 '22 at 09:36
  • SysPin is not working on Win11 22H2 – AVEbrahimi Dec 14 '22 at 04:51
9

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)
}
fourwhey
  • 490
  • 4
  • 19
8

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.

AlexDev
  • 4,049
  • 31
  • 36
6

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"
Humberto Freitas
  • 461
  • 1
  • 6
  • 21
  • 2
    I've tried all of these suggestions (ps1, vbs) on Win 10 vers 1903 and none worked. Anyone have an update on this? – julesverne Jul 30 '19 at 06:30
  • Apparently MS deactivated the pin through this way. I have another script that uses the method of this solution and it still works, so it seems that she sees this pin shape as a security hole. This solution still works: https://stackoverflow.com/a/34182076/3732138 – Humberto Freitas Jul 31 '19 at 21:02
  • @julesverne, indeed, now Oct 2022, on Win 10 21H2 and Windows 11, none of the PowerShell or VBScript answers here work (2 years after you pointed it out). Please can some of the geniuses on here that came up with these great answers, please update them to account for Microsoft breaking this? Hint: the only answer on this page that *works* is by using `syspin.exe`, and on that answer are links on how to do it in C#. If that can be translated to PowerShell, then this page will have working answers (currently this entire page is a honey-trap, people just waste time as no PowerShell here works). – YorSubs Oct 26 '22 at 09:55
5

Warning: None of the PowerShell / VBScript answers on this page work on Windows 10 21H2 or Windows 11 (and this functionality has been broken as far back as 2019).

Just putting this in bold so that people do not waste their time here. Hopefully someone can update the above (as they were great answers, but do not work any more due to Microsoft making changes, so hopefully some tweaking of the answers here can get them working again). As there is currently no known method of pinning apps to the Taskbar with PowerShell (since none of the solutions on this page work), the only solution that I know that works is the syspin.exe app. Please can the PowerShell answers be updated, as that would be far better than using syspin. Currently (and sadly), this page serves mostly as a "honey trap"; people come here, happy to find an answer to this, only to waste their time trying solutions that are all broken.

YorSubs
  • 3,194
  • 7
  • 37
  • 60
3

Refer to @Humberto Freitas answer that i tweaked for my aim, you can try this vbscript in order to pin a program to taskbar using Vbscript in Windows 10.

Vbscript : TaskBarPin.vbs

Option Explicit
REM Question Asked here ==> 
REM https://stackoverflow.com/questions/31720595/pin-program-to-taskbar-using-ps-in-windows-10/34182076#34182076
Dim Title,objFSO,ws,objFile,sKey1,sKey2,KeyValue
Title = "Pin a program to taskbar using Vbscript in Windows 10"
'----------------------------------------------------------------------
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set Ws     = CreateObject("WScript.Shell")
objFile    = DeQuote(InputBox("Type the whole path of the program to be pinned or unpinned !",Title,_
"%ProgramFiles%\windows nt\accessories\wordpad.exe"))
REM Examples
REM "%ProgramFiles%\Mozilla Firefox\firefox.exe"
REM "%ProgramFiles%\Google\Chrome\Application\chrome.exe"
REM "%ProgramFiles%\windows nt\accessories\wordpad.exe"
REM "%Windir%\Notepad.exe"
ObjFile = ws.ExpandEnvironmentStrings(ObjFile)
If ObjFile = "" Then Wscript.Quit()
sKey1      = "HKCU\Software\Classes\*\shell\{:}\\"
sKey2      = Replace(sKey1, "\\", "\ExplorerCommandHandler")
'----------------------------------------------------------------------
With CreateObject("WScript.Shell")
    KeyValue = .RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer" & _
    "\CommandStore\shell\Windows.taskbarpin\ExplorerCommandHandler")
    .RegWrite sKey2, KeyValue, "REG_SZ"
    
    With 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
'----------------------------------------------------------------------
Function DeQuote(S)
    If Left(S,1) = """" And Right(S, 1) = """" Then 
        DeQuote = Trim(Mid(S, 2, Len(S) - 2))
    Else 
        DeQuote = Trim(S)
    End If
End Function
'----------------------------------------------------------------------

EDIT : on 24/12/2020

Refer to : Where is Microsoft Edge located in Windows 10? How do I launch it?

Microsoft Edge should be in the taskbar. It is the blue 'e' icon.

Taskbar

If you do not have that or have unpinned it, you just need to repin it. Unfortunately the MicrosoftEdge.exe can not be run by double clicking and creating a normal shortcut will not work. You may have found it at this location.

Location

What you need to do is just search for Edge in the Start menu or search bar. Once you see Microsoft Edge, right click on it and Pin to taskbar.

Search


You can run the Microsoft Edge with this vbscript : Run-Micro-Edge.vbs

CreateObject("wscript.shell").Run "%windir%\explorer.exe shell:Appsfolder\Microsoft.MicrosoftEdge_8wekyb3d8bbwe!MicrosoftEdge"
Hackoo
  • 18,337
  • 3
  • 40
  • 70
0

I wrote a Powershell Class using the above answers as motivation. I just put it into a module then imported into my other scripts.

using module "C:\Users\dlambert\Desktop\Devin PC Setup\PinToTaskbar.psm1"

[PinToTaskBar_Verb] $pin = [PinToTaskBar_Verb]::new();

$pin.Pin("C:\Windows\explorer.exe") 
$pin.Pin("$env:windir\system32\SnippingTool.exe") 
$pin.Pin("C:\Windows\explorer.exe") 
$pin.Pin("C:\Program Files (x86)\Google\Chrome\Application\chrome.exe") 
$pin.Pin("C:\Program Files\Notepad++\notepad++.exe") 
$pin.Pin("$env:windir\system32\WindowsPowerShell\v1.0\PowerShell_ISE.exe") 

Module below

class PinToTaskBar_Verb 
{
    [string]$KeyPath1  = "HKCU:\SOFTWARE\Classes"
    [string]$KeyPath2  = "*"
    [string]$KeyPath3  = "shell"
    [string]$KeyPath4  = "{:}"
    
    [Microsoft.Win32.RegistryKey]$Key2 
    [Microsoft.Win32.RegistryKey]$Key3
    [Microsoft.Win32.RegistryKey]$Key4

    PinToTaskBar_Verb()
    {
        $this.Key2 = (Get-Item $this.KeyPath1).OpenSubKey($this.KeyPath2, $true)
    }
    

    [void] InvokePinVerb([string]$target)
    {
        Write-Host "Pinning $target to taskbar"
        $Shell = New-Object -ComObject "Shell.Application"
        $Folder = $Shell.Namespace((Get-Item $Target).DirectoryName)
        $Item = $Folder.ParseName((Get-Item $Target).Name)
        $Item.InvokeVerb("{:}")
    }



    [bool] CreatePinRegistryKeys()
    {
        $TASKBARPIN_PATH = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\Windows.taskbarpin";
        $ValueName = "ExplorerCommandHandler"
        $ValueData = (Get-ItemProperty $TASKBARPIN_PATH).ExplorerCommandHandler
        
        Write-Host "Creating Registry Key: $($this.Key2.Name)\$($this.KeyPath3)"
        $this.Key3 = $this.Key2.CreateSubKey($this.KeyPath3, $true)

        Write-Host "Creating Registry Key: $($this.Key3.Name)\$($this.KeyPath4)"
        $this.Key4 = $this.Key3.CreateSubKey($this.KeyPath4, $true)

        Write-Host "Creating Registry Key: $($this.Key4.Name)\$($valueName)"
        $this.Key4.SetValue($ValueName, $ValueData)

        return $true
    }

    [bool] DeletePinRegistryKeys()
    {
        Write-Host "Deleting Registry Key: $($this.Key4.Name)"
        $this.Key3.DeleteSubKey($this.KeyPath4)
        if ($this.Key3.SubKeyCount -eq 0 -and $this.Key3.ValueCount -eq 0) 
        {
            Write-Host "Deleting Registry Key: $($this.Key3.Name)"
            $this.Key2.DeleteSubKey($this.KeyPath3)
        }
        return $true
    }

    [bool] Pin([string]$target)
    {
        try
        {
            $this.CreatePinRegistryKeys()
            $this.InvokePinVerb($target)
        }
        finally
        {
            $this.DeletePinRegistryKeys()
        }
        return $true
    }

}
Devin Gleason Lambert
  • 1,516
  • 1
  • 13
  • 22
  • 2
    Does this by chance unpin from taskbar too, and from Windows 10 20H2 version? I'm having trouble getting anything to work to unpin programmatically from Windows 10 20H2 with all answers here and other posts I've tried. Curious if you know anything regarding this and if you have anything you confirmed works to unpin from taskbar programmatically using PS or anything really I can run from PS including C# code. Figured it'd be worth an ask to you if nothing else. From what I gather (and tested) Microsoft changed something so you can no longer do the unpin via the method people have written about. – Bitcoin Murderous Maniac Dec 26 '20 at 20:21
  • 1
    Looks cool but didn't work for me on win10 pro 20H2.. – Baxorr Feb 19 '21 at 20:03
-1

I recommend to use this Windows 10 feature. It allows people to specify pinned programs (and other things) via an XML file.

Cristian
  • 1,338
  • 1
  • 9
  • 12