Very much a place-holder for now but I thought my Windows command-line tool PinTo10v2 could do with a home page…

A lot of IT admins will know that the popular VB Script that pins items to the Windows 7 Task Bar and Start Menu does not work in Windows 10.  I made PinTo10 about 18 months ago based on the Nullsoft Scriptable Installer framework which was functional but slow and heavy for a command-line tool and not really the right tool for the job at all.  Now, based on some great work by Alex Weinberger ( ), I’ve made PinTo10v2 which has the same functionality as the original but is a fraction of the size and far more efficient. The source code isn’t very pretty as I’m no c# coder (I normally stick to basic scripting) but it works.

Give it a go, source code included…


Update…  Someone has posted some pretty simple VBS / PowerShell code here…

I’ve modified it to work across Windows 7 / 8 / 8.1 / 10 and take some command parameters.  I’ve posted my modified script in the comments…

Stuart Pearson




50 thoughts on “PinTo10v2”

    1. Rob, Sadly not. This method still uses the verb method (with a little modification for it to work on Windows 10 thanks to Alex Weinberger). As the default pinning of Edge doesn’t seem to actually directly link to a .lnk or .exe that verb can’t be triggered. The best methods available at the moment seem to be importing a set of registry keys to HKCU for a basic “taskband” and restarting explorer.exe. Then you can pin whichever icons you want back. It’s not pretty but it’s probably the best solution at this point in time.


    2. I was still able to unpin with the old vbscript method just unable to pin so for edge you could use something along the line of

      Set sho = CreateObject(“Shell.Application”)

      sourcedir = fso.GetFile(WScript.ScriptFullName).ParentFolder
      Set folder = sho.Namespace(“shell:AppsFolder”)

      For Each item In folder.Items
      If contains(item.Name,”Microsoft Edge”) Then
      Set folderItem = folder.ParseName(item.Path)
      End If

      Function contains(sourceStr, checkStr)
      contains=InStr(1, sourceStr, checkStr, vbTextCompare) > 0
      End Function


      1. Stefan,
        You absolutely rock!!!

        I did a quick test of this vbs script on a Win10 1703 and it removed Edge. I tweaked it to remove Store and Mail from the taskbar and it removed those too. I’m not sure why this works when the “Pin to taskbar” verb was supposed to be removed from being able to be scripted. But, hey, it works!

        Stuart, I cannot forget your work either. Your utility helps me immensely in scripting the addition of customer-requested items to the taskbar and start menu.

        Between both of your efforts, you have both made my customization and deployment of Win10 that much easier.



      2. I am not the author or anything so maybe I misinterpret the code but I think for modern apps where you would have to use their AppUserModelID to call them the method that tricks windows into thinking the pinning verb is present might not work. So the most simple workaround would be to create a shortcut to the app (the app can be found in shell:AppsFolder with the Path being the AppUserModelID) So you could use a code like the one I posted above and then create a shortcut where it doesn’t hurt you (for example in the start menu). For this you have to add shell:AppsFolder\ in front of the path (so something like:

        Set lnk = wso.CreateShortcut(“C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Edge.lnk”)
        lnk.TargetPath = “shell:AppsFolder\” & item.Path

        within the if in my code)
        Then you can pin and unpin with the lnk as a the target. (This would also work as alternative method for unpinning, but you need to create the shortcuts programatically (alternatively you could also try to create them once by hand and then copy them to you system thus getting rid of the scripting)


      3. thanks
        Just had to create a lnk file and point the path shellappsfolderwindowslivemail Etc but unfortunately you have to use a custom icon which I used shell32.dll,156


      4. Hello Stefan,

        Thanks for the vb script. However, when I try to run your script (exactly as posted above), I get an error :
        Line: 3
        Char: 1
        Error: Object Required: ‘fso’
        Code: 800A01A8
        Source: Microsoft VBScript runtime error

        I’m not programmer, but I see that fso is not defined and can only assume that’s what it’s complaining about? I’d appreciate any assistance in getting this to run.



      5. @Stephan — thanks for the code snippet. I played around with it today and created this repo on github: I put a link to it in my ‘startup’, since on my machine the default pinned apps come back every time I log in. Grrrr.

        The script works fine for normal apps, but has some issues with IE and File Explorer on my machine. There are some oddities with these two that I documented in the README file — if I get time I will research them later.

        The basic problem is that the shell:Applications namespace seems to be inconsistent.

        A) It doesn’t always have the correct status of the app. For instance, when IE is pinned to the taskbar, the context menu still says ‘pin to taskbar’, when it should say ‘unpin from taskbar’. Since verbs are being taken from this context, the appropriate verb is missing, and can’t be called.

        B) It doesn’t always have the ‘unpin from taskbar’ verb when it should. I found this with File Explorer — in the Start menu, File Explorer shows either “Pin to Taskbar” or “Unpin from Taskbar”, depending on whether it is already pinned. In the shell:Applications namespace, it shows neither one, regardless of current pin status.

        I’m not sure how much of this is just Windows, and how much is weirdness with the way my company provisions their machines.

        I’m wondering if there is a different namespace that can be used to get the list of applications, one that might work more consistently. Perhaps the start menu itself … ?


      6. Unfortunately the whole pinning thing is kind of a mess so I know of no one method that really works in all cases. Especially Internet Explorer is behaving so strange it does not even work correctly if you follow MS own tutorials. For example if you use the default way of pinning the xml layout file via gpo they would recommend using the DesktopApplicationID of IE and it would lead to internet explorer.exe not being grouped together with it’S icon after opening… Therefore it is kinda hard to say what the real content of the link in the provisioning package even points to (in our company we created a new ie link in the “old” start menu path in program data for example). Despite this completely awkward implementation microsoft uses everywhere related to pinning however I still found it possible to use some hack or another for each case, just so far not one that does everything. For IE the PinTo10v2 tool this very blog is originally about still worked fine for me. Did you also encounter problems using it directly on the ie exe in programfiles (possible programfiles (x86) depending on your companies solution for the provisioning) Normally Stuarts tool works just fine because what it does what a vbscript can sadly never do is alter the executable in memory after it has been loaded but before the verbs are read. By renaming it to explorer.exe Windows will then read the pin and unpin verbs again just fine. The only reason I posted my old vbs code here was that his tool will not work perfectly with some apps that do not really have the same kind of executable normal programs have. So while neither the script nor the tool really can do everything by combining them at least I was able to pin and unpin all the types of icons we needed so far.


      7. Stefan:

        Yes, I had the same problem when using “Program Files” or “Program Files (x86)”. I played around with different namespaces, and found that the content of “\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar” is the most reliable. Using that, I was able to unpin nearly everything, including Internet Explorer. The only exception was File Explorer.

        To handle File Explorer, I refactored the main loop into a function, and called the namespace processor twice; once with a namespace that worked for File Explorer, and once for everything else. This approach works quite well, and lends itself easily to adding new icons, or additional namespaces if needed.

        So in the end, I ran into the same issue you in that no single solution works for everything. The good news is that one technical approach handles everything. I just needed to feed it several namespaces. Not perfect, but reasonably clean and easy to maintain.

        The tedious part is finding a namespace / directory that works. I (somewhat ironically) used File Explorer to find all shortcuts to File Explorer on my C: drive. Then right clicked on them until I found one that had the ‘Unpin’ verb.

        And … the reason I did all this instead of using the Pin-to-10 tool is that my company blocks me from downloading it. 😦


      8. Glad you got it to work. As for blocking the download, I know the struggle with overly protective download rules in the workplace. Rules like that are a huge annoyance for me as well. In case you still find a situation where vbs is not good enough stuart has posted the page with the source code he used as basis for his tool ( so if you know a little bit c# you could just compile a tool yourself. The main magic is in the ChangeImagePathName function but for taskbar pinning the code for PinUnpinTaskbar is also included on that page. It is missing the part for start menu pinning stuart also included but the comments explain how to do that as well


  1. Hello Stuart
    What is the reason that your (very nice) tool doesn’t work on Server OS, for example Server 2016?
    Ever since I discovered this tool we’ve been using it for our Windows 10 deployments. Now I wanted to also use it for Server 2016 but apparently it’s not supported.


    1. Hi Mike,

      Only Windows 7 and 10 are supported because those are the OS’s that have been tested and are known to work. This is why I’ve provided the source code for it.

      If you look at line 71 of Program.cs you’ll see that it exits the program if it doesn’t detect Windows 7 or 10. You should simply be able to change that line from…

      actionIndex = pin ? 51201 : 51394;

      and then recompile it.

      This should work (completely untested)…


      Liked by 2 people

      1. So is the correct syntax something like this:

        PinTo10v2_NoOSCheck.exe /pintb ‘’
        PinTo10v2_NoOSCheck /pintb ‘C:\Program Files\\paintdotnet.exe’
        PinTo10v2_NoOSCheck /pintb ‘C:\Program Files\\paintdotnet.lnk’



      2. Hi,


        PinTo10v2_NoOSCheck /pintb “C:\Program Files\\paintdotnet.exe”
        PinTo10v2_NoOSCheck /pintb “C:\Program Files\\paintdotnet.lnk”

        … should work as long as the file exists. Full paths are needed (although I appreciate that I only put “filename” in the help file.

        Please note that the NoOSCheck might operate differently or not at all on OS’s that are not Win 7 or 10 so if something isn’t working (and you’re not using Win 7 or 10) then please try it on a “supported” operating system first.



    1. Feel free to link back to this site and this statement. I’m no lawyer and don’t know how open source really works but I am providing the compiled exe and source code available to everyone to use with no suggestion that this is fit for purpose or comes with any expression of support or warranty. Please use at your own risk. I have tested it and know it to work as I intended. As it is based on someone else’s source code you would have to also check that they are also happy for the code to be used.


  2. Hi There

    Is it possible to add an argument?
    PinTo10v2.exe /pintb path=”C:\Program Files\FileMaker\FileMaker Pro 15 Advanced\FileMaker Pro Advanced.exe” arg=”\\domain\share\FILETOOPEN.fmp12″


  3. Hey there, I have used this tool 2 times until now and it all worked fine until now. I am trying to pin a folder link (same happens with and .exe or application link) to the start menu of Windows 10 1607 (via CMD command, but it gives the same error with PS as well) and it fails with the following description:
    Unbehandelte Ausnahme: System.UnauthorizedAccessException: Der Zugriff auf den Pfad “C:\ProgramData\Microsoft\Windows\Start Menu\Programme” wurde verweigert.
    bei System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
    bei System.IO.FileSystemEnumerableIterator`1.AddSearchableDirsToStack(SearchData localSearchData)
    bei System.IO.FileSystemEnumerableIterator`1.MoveNext()
    bei System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
    bei System.IO.Directory.GetFiles(String path, String searchPattern, SearchOption searchOption)
    bei PinTo10v2.Program.Main(String[] args)

    I would appreciate any help.


    1. Hi, support will be quite minimal (if any) but do you have the command line you’re trying to run?

      I didn’t test any folder shortcuts but looking at them then I think pinning them to the Start Menu may work but the verb to pin them to the taskbar doesn’t appear to be there by default. I also have no idea if this will work in any language than US / UK which is why I’ve provided the source.

      If you look at line 122 of Utils.cs you will see that it’s hard-coded to look at…
      string currentuserstart = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @”\Microsoft\Windows\Start Menu\Programs”;

      I would guess that the folder %APPDATA%\Microsoft\Windows\Start Menu\Programs doesn’t exist on a German system? This can be changed to whatever it should be and re-compiled in Visual Studio. Whilst you’re at it you could also fix a bug on line 233 of the same file which is currently…
      counter = counter = + 1;
      but should be…
      counter = counter + 1;

      As it stands it can go into an infinite loop.

      Hope this is of some help.


      The way I’m working on my deployments for this summer is going to be based on the update of a Powershell Cmddlet for applying a default Start Menu menu to new user to include the default TaskBar…



  4. Hi,
    I will look into it and get back with some results. I actually never used VS until now, but I will learn, not a problem.
    The reason for trying to use your app, is that in 1607 the XML does not pin Folders, and my Customers have that as a requirement.

    The command line for pinto I use is:
    path to pinto exe /pinsm “path to shortcut”
    Indeed I have tested it on US MUI and it works, so what do you suggest I do to add support for other languages, because my Customers are multinational, including Japanese and Chinese?

    I am following the other blog as well!



    1. Hi, if you modify the start menu path to point at special folder “startup” and traverse up a folder from there you will get the startmenu > programs from there on 100% of international OSes. BTW this app works on server 2012 and server 2016. I wish it could run faster but I am using it at our school to pin many things including control_panel>printers with windows 10 and it works very well, good job!


    1. You can look in the user’s directory to see which Win32 apps are pinned to the TaskBar…
      %APPDATA%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar

      Not so easy to check for items already pinned to the Start Menu. The only way I can think of would be to check all .lnk files in the start menu to see if the verb for “Unpin from Start” is present. This would probably be a relatively lengthy process and, again, won’t work for modern apps.


    1. This might be useful…

      Presumably you could use something like this to work for all languages (completely untested)…

      string currentuserstart_ = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
      string currentuserstart = Path.GetFullPath(Path.Combine(currentuserstart_, @”..\”));


  5. Hi. Great tool but not correctly works with explorer.exe

    What do I mean?

    1. PinTo10v2.exe /pintb “%windir%\explorer.exe” – Explorer shortcut pins to taskbar, everything works fine
    2. PinTo10v2.exe /pintb “%windir%\explorer.exe” – Explorer shortcut renames to Explorer(2) in folder %appdata%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar and shortcut on taskbar doesn’t work
    3. PinTo10v2.exe /pintb “%windir%\explorer.exe” – no reaction
    4. PinTo10v2.exe /pintb “%windir%\explorer.exe” – no reaction
    5. PinTo10v2.exe /pintb “%windir%\explorer.exe” – no reaction
    The only way to fix it is right- click on Explorer shortcut in taskbar and select “unpin”.

    Other files, f.e. write.exe (WordPad) greatly work with this tool, no matter how times you execute command.

    Can you fix it?

    I’m using Windows10 LTSB (special corporate edition)


    1. Running Win 10 Enterprise 2015 LTSB 10.0.10240, V2 just hangs when run as described above. Guessing some patch (enhancement) is blocking the script.

      Anyone seeing this.


      1. To get around just create the shortcuts first eg

        call :shortcut “%temp%” “Explorer” “c:\windows\explorer.exe”
        call :shortcut “%temp%” “Mail” “c:\windows\explorer.exe” “c:\windows” “shell:AppsFolder\microsoft.windowscommunicationsapps_8wekyb3d8bbwe!microsoft.windowslive.mail” “C:\Windows\System32\SHELL32.dll, 156”
        call :shortcut “%temp%” “Print Server” “c:\windows\explorer.exe” “c:\windows” “\\PrintServer” “%SystemRoot%\system32\shell32.dll,60”
        call :shortcut “%temp%” “Devices and Printers” “c:\windows\explorer.exe” “c:\windows” “shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}” “%systemroot%\system32\DeviceCenter.dll”
        call :shortcut “%temp%” “logoff” “C:\Windows\System32\shutdown.exe” “C:\Windows\System32” “/l” “C:\Windows\System32\SHELL32.dll, 25″

        set _vbs=”%temp%\_.vbs”
        if exist %_vbs% del /f /q %_vbs%
        >%_vbs% echo set objShell = CreateObject(“WScript.Shell”)
        >>%_vbs% echo sLinkFile = %1 ^& “\” ^& %2 ^& “.lnk”
        >>%_vbs% echo Set oLink = objShell.CreateShortcut(sLinkFile)
        if “%~3” neq “” echo oLink.TargetPath = %3>>%_vbs%
        if “%~4” neq “” echo oLink.WorkingDirectory = %4>>%_vbs%
        if “%~5” neq “” echo oLink.Arguments = “”%5″”>>%_vbs%
        if “%~6” neq “” echo oLink.IconLocation = %6>>%_vbs%
        >>%_vbs% echo oLink.Save
        cscript //nologo %_vbs%
        “%~dp0PinTo10v2_NoOSCheck.exe” /pintb “%temp%\%~2.lnk” >nul
        exit /b


      2. We seen that behavior and we use a profile server… just exclude
        \AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar


  6. Is there a help file to this. I am not able to get this to work. On the root of C:, I have a scripts folder


    with the exe and a command file that I had gotten from the previous version. I have another folder with all my shortcuts in it. In the .cmd file, I have lines in there one for unpining eg….
    pinto10v2.exe /unpintb “c:\scripts\pinapps\ehr.lnk
    then below
    pinto20v2.exe /pintb “c:\scripts\pinapps\ehr.lnk

    So, when I run the cmd file, nothing happens. Any ideas of what I am doing wrong?


  7. Hi guys,

    Thanks to some clever scripting found here…

    … I’ve converted the whole process back to a simple VBS again. I prefer this way, far easier to implement and edit…

    ‘ VBS Script to pin / unpin files to the Windows 7 / 10 Taskbar or Start Menu

    ‘ Use with three arguments
    ‘ First argument is the full path to the file you wish to pin, .exe or .lnk
    ‘ Second argument needs to either be “PIN” or “UNPIN” (no quotes, case insensitive)
    ‘ Third argument needs to be either “TASKBAR” or “START” (no quotes, case insensitive)

    ‘ If the script is missing arguments then quit
    If WScript.Arguments.Count 0 Or Instr(ProductName,”Windows 8″) > 0 Then

    If UCase(objAction) = “PIN” Then

    ‘ This checks if the shortcut is already pinned as you can’t read the verb “Pin to Taskbar”. Not doing this would unpin the object if already pinned
    ContinuePin = “Yes”
    For Each objVerb in colVerbs
    If UCase(Replace(, “&”, “”)) = “UNPIN FROM TASKBAR” Then
    ContinuePin = “No”
    End If

    ‘ Only pin if found not to already be pinned
    If ContinuePin = “Yes” Then
    KeyValue = objWSShell.RegRead(“HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\Windows.taskbarpin\ExplorerCommandHandler”)
    objWSShell.RegWrite sKey2, KeyValue, “REG_SZ”
    objWSShell.Run(“Reg.exe delete “”” & Replace(sKey1, “\\”, “”) & “”” /F”), 0, True
    End If

    End If

    End If

    ‘ Pin to Taskbar for Windows 7
    If Instr(ProductName,”Windows 7″) > 0 Then
    If UCase(objAction) = “PIN” Then
    For Each objVerb in colVerbs
    If UCase(Replace(, “&”, “”)) = “PIN TO TASKBAR” Then
    End If
    End If
    End If

    ‘ Unpin from Taskbar ———————————————————————————————————————————-
    If UCase(objAction) = “UNPIN” Then
    For Each objVerb in colVerbs
    If UCase(Replace(, “&”, “”)) = “UNPIN FROM TASKBAR” Then
    End If
    End If

    End If

    ‘ Pin and Unpin from the Start Menu – Works in old way for all OS’s

    If UCase(objLocation) = “START” Then

    ‘ Pin to Start —————————————————————————————————————————————-
    If UCase(objAction) = “PIN” Then
    For Each objVerb in colVerbs
    If UCase(Replace(, “&”, “”)) = “PIN TO START” Then
    End If
    End If

    ‘ Unpin from Start ————————————————————————————————————————————
    If UCase(objAction) = “UNPIN” Then
    For Each objVerb in colVerbs
    If UCase(Replace(, “&”, “”)) = “UNPIN FROM START” Then
    End If
    End If

    End If

    Liked by 1 person

  8. Hello.
    I’ve found and fixed a bug in PinTo10v2.
    It crashes while trying to pin/unpin an item to/from taskbar if the tool is launched from %TEMP% and user name is either long or contains spaces or non-latin characters.
    This happens because %TEMP% contains something like C:\User\LONGUS~1\AppData\Local\Temp, but GetDirectoryName() in ChangeImagePathName() expands it to C:\User\LongUserName\AppData\Local\Temp. As a result, ChangeImagePathName() fails and throws the Exception(“new ImagePathName cannot be longer than the original one”).
    I’ve made a couple of changes: added some basic exception handling, just to prevent unhandled exception window from appearing in case of error, and got rid of GetDirectoryName() in ChangeImagePathName().
    The source and the binary can be found here:


  9. Hello, could it be that Your program does not run on Windows 10 > 1803? Tried it in Windows 10 Enterprise x64 German 1803 and 1809 with no success. With 1709 ist functioned well as far as I remember. Would be great it there would be fix, if there is a change in 1803 and onward. By the way: Great tool! cu Rainer


      1. Thanks! Can You format the VBS-Scource or provide a ZIP? A couple of time ago I tried to copy&paste it and there where some problems, so that it does not run. And I am not so good to find every fault. Would be great! Thanks in advance, used Your code for a long time till it “broke” in 1803.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s