PinTo10v4 (PowerShell),v4.1 (VBS) and PinToTaskBar1903.

After a long time scouring the internet for partial working solutions to the problem that occurred because the previous script-able pinning techniques were removed by Microsoft I have created (cobbled together from various sources and refined) PinTo10_v4!

PinTo10_v4 is a Powershell script.  It requires three arguments passed to it, much the same as previous iterations of the PinTo10 tools.  It is able to pin icons (not modern apps) to the Windows 10 Start Menu and Taskbar and is tested to work in Windows 10 up to version 1809!  I’m also told it works on Server 2016.

Feel free to grab a copy of the 0.6 release of the v4 PowerShell script or the v4.1 VBS script and do your own testing.  I may well do some further updates but so far it seems to work pretty well.  Let me know how you get on…

PinTo10_v4.1 is a port of the PowerShell script to VBS that actually might work better than the PowerShell version.  It started as a direct port but I’ve added a few more checks and longer loops.  If the PowerShell version doesn’t work for you then try this one.  I’m unlikely to add any further updates to the PowerShell version now.  The VBS version also adds support for Windows 7.

Powershell v4 ( Version 0.6.  PS1 and compiled EXE files included)
https://www.dropbox.com/s/nf9cjinsugzt3yr/PinTo10_v4_0.6.zip?dl=1

VBS v4.1 (Version 0.4)
https://www.dropbox.com/s/o4i908yidfyi1j3/PinTo10_v4.1.vbs?dl=1

As noted by several users, the above tools no longer work in Windows 10 1903.  I have a new script that can pin to the 1903 TaskBar (no Start Menu pinning (and don’t expect any to be added 😦 ))
PinToTaskBar1903 PowerShell Script…
https://www.dropbox.com/s/q7ttcj69ljont06/PinToTaskBar1903.ps1?dl=1

Stuart Pearson

113 thoughts on “PinTo10v4 (PowerShell),v4.1 (VBS) and PinToTaskBar1903.”

    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.

      Like

    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)
      folderItem.InvokeVerb(“taskbarunpin”)
      End If
      Next

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

      Like

      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.

        Thanks!!!

        Like

      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
        lnk.Save

        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)

        Like

      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

        Like

      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.

        Thanks,
        Brett

        Like

      5. @Stephan — thanks for the code snippet. I played around with it today and created this repo on github: https://github.com/Gundark/TaskbarUnpinner. 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 … ?

        Like

      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.

        Like

      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. 😦

        Like

      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 (http://alexweinberger.com/main/pinning-network-program-taskbar-programmatically-windows-10/) 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

        Like

  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.

    Like

    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…

      Environment.Exit(0);
      to
      actionIndex = pin ? 51201 : 51394;

      and then recompile it.

      This should work (completely untested)…
      https://www.dropbox.com/s/tewwil1axsovxa8/PinTo10v2_NoOSCheck.zip?dl=1

      Stuart

      Liked by 2 people

      1. So is the correct syntax something like this:

        PinTo10v2_NoOSCheck.exe /pintb ‘paint.net’
        -or-
        PinTo10v2_NoOSCheck /pintb ‘C:\Program Files\paint.net\paintdotnet.exe’
        -or-
        PinTo10v2_NoOSCheck /pintb ‘C:\Program Files\paint.net\paintdotnet.lnk’

        Thanks

        Like

      2. Hi,

        Either…

        PinTo10v2_NoOSCheck /pintb “C:\Program Files\paint.net\paintdotnet.exe”
        -or-
        PinTo10v2_NoOSCheck /pintb “C:\Program Files\paint.net\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.

        Stuart

        Like

    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.

      Like

  2. Hi There

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

    Like

  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.
    Thanks!

    Like

    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.

      However…

      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…

      https://sccmguru.wordpress.com/2016/08/18/windows-10-1607-taskbar-and-start-customization-deep-dive/

      Stuart

      Like

  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!

    Thanks.

    Like

    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!

      Like

    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.

      Like

    1. This might be useful…
      http://stackoverflow.com/questions/14899422/how-to-navigate-a-few-folders-up
      https://msdn.microsoft.com/en-us/library/system.environment.specialfolder(v=vs.110).aspx

      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_, @”..\”));

      Like

  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
    etc
    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?

    PS
    I’m using Windows10 LTSB (special corporate edition)

    Like

    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.

      Like

      1. To get around just create the shortcuts first eg

        batch.cmd
        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″

        :shortcut
        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

        Like

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

        Like

  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

    C:\scripts\pinto10\

    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?

    Like

  7. Hi guys,

    Thanks to some clever scripting found here…
    https://stackoverflow.com/questions/31720595/pin-program-to-taskbar-using-ps-in-windows-10/

    … 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(objVerb.name, “&”, “”)) = “UNPIN FROM TASKBAR” Then
    ContinuePin = “No”
    End If
    Next

    ‘ 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”
    objShell.Namespace(objFSO.GetParentFolderName(objFile)).ParseName(objFSO.GetFileName(objFile)).InvokeVerb(“{:}”)
    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(objVerb.name, “&”, “”)) = “PIN TO TASKBAR” Then
    objVerb.DoIt
    End If
    Next
    End If
    End If

    ‘ Unpin from Taskbar ———————————————————————————————————————————-
    If UCase(objAction) = “UNPIN” Then
    For Each objVerb in colVerbs
    If UCase(Replace(objVerb.name, “&”, “”)) = “UNPIN FROM TASKBAR” Then
    objVerb.DoIt
    End If
    Next
    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(objVerb.name, “&”, “”)) = “PIN TO START” Then
    objVerb.DoIt
    End If
    Next
    End If

    ‘ Unpin from Start ————————————————————————————————————————————
    If UCase(objAction) = “UNPIN” Then
    For Each objVerb in colVerbs
    If UCase(Replace(objVerb.name, “&”, “”)) = “UNPIN FROM START” Then
    objVerb.DoIt
    End If
    Next
    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: https://drive.google.com/open?id=1Hbd2btbzrpYeo62pVksaSQoRmXgxc6VH

    Like

  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

    Like

      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.

        Like

    1. Hi Stuart, unfortunately the tool does not work as expected:

      C:\>powershell -noprofile -ExecutionPolicy Bypass -file PinTo10_v4.ps1 “C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE” PIN TASTKBAR

      TargetFile = C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE

      PinUnpin = PIN

      Location = TASTKBAR

      Target file found. Continuing…

      PINUNPIN variable set to PIN

      Third arguemnt not set to START or TASKBAR. Exiting…


      No pinning takes place. 😦

      When using the .exe provided:


      C:\>PinTo10_v4.exe “C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE” PIN TASKBAR

      TargetFile = C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE

      PinUnpin = PIN

      Location = TASKBAR

      Target file found. Continuing…

      PINUNPIN variable set to PIN

      LOCATION variable set to TASKBAR

      FullFileName = WINWORD

      FileNameWithExt = WINWORD.EXE

      Directory = C:\Program Files (x86)\Microsoft Office\root\Office16

      ERROR: You cannot call a method on a null-valued expression.
      ERROR: You cannot call a method on a null-valued expression.
      ERROR: You cannot call a method on a null-valued expression.
      ERROR: You cannot call a method on a null-valued expression.
      Shortcut not found in the Taskbar shortcuts folder. Trying to pin.
      ERROR: You cannot call a method on a null-valued expression.
      ERROR: You cannot call a method on a null-valued expression.
      ERROR: You cannot call a method on a null-valued expression.

      Thanks!

      Like

      1. Hi Simon. In your PowerShell version you have a typo… “TASTKBAR”

        I can’t offer any support for the exe version other than to say that it works OK for me. If it doesn’t work for you then start debugging the PowerShell.

        Re-try the PowerShell script with TASKBAR. Also, I would use the Start Menu shortcut as the target file rather than the WinWord.exe executable. Although it worked for me using the exe as the target I don’t like that it creates a shortcut called “WinWord” rather than “Word”.

        Stuart

        Like

  10. Hi Stuart,

    We’ve been using this tool for a number of years & it works great – I’m struggling to get the v4 to work though, I’m getting ‘Error – You cannot call a method on a null-valued expression’

    I do get one line which says ‘Shortcut not found in the Taskbar Shortcuts folder. Trying to Pin’ but it fails to pin.

    I’m using the syntax “Filelocation\pinTo10v4.exe” “FileLocation\Shortcut.lnk” PIN TASKBAR

    I’m having this issue on both Windows 2016 LTSB (of which PinTo10v2 works fine) & also on Windows 2019 LTSC.

    Any ideas on what I’m doing wrong?

    Many thanks.

    Like

  11. Hi Stuart, thank you for your efforts! FINALLY A SCRIPT THAT WORKS on 1809 😀

    However, I’ve found some errors…
    1. Line 52 and 59 has a spelling error, “… arguemnt not…” should be “… argument not…”
    2. When action is PIN and the app is already pinned it is UNPINNED :-/
    I’ve identified the error. According to https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-6; “When the Include parameter is used, the Path parameter needs a trailing asterisk (*) wildcard … If a trailing asterisk (*) is not included in the Path parameter, the command does not return any output”

    I’ve experimented and found this to be working well…
    In the PIN TO TASKBAR section:
    $FindFile=Get-Childitem -Path $env:APPDATA”\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\*” -Name -Include $FileNameNoExt”.lnk” -ErrorAction SilentlyContinue

    if (!($FindFile)){
    write-host “Shortcut not found in the Taskbar shortcuts folder. Trying to pin.”
    $Item.InvokeVerb(“{:}”)

    And similarly in the UNPIN FROM TASKBAR section:
    $FindFile=Get-Childitem -Path $env:APPDATA”\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\*” -Name -Include $FileNameNoExt”.lnk” -ErrorAction SilentlyContinue

    if ($FindFile){
    write-host “Shortcut found in the Taskbar shortcuts folder. Trying to unpin.”
    $Item.InvokeVerb(“{:}”)

    In your original script you’ve added -Recurse to the Get-ChildItem line in the Unpin section. I couldn’t really see the point of it so I removed it.

    And I’ve got a suggestion… I’m sure there are many foreigners, like myself, finding this script very useful. Maybe it would be possible to implement some language logic in stead of hard coding just one set of localized verbs…?
    I’ve tried but my PS knowledge isn’t good enough, this syntax fails:
    Switch ($args[3].ToUpper()) {
    “NO” {
    $PinToStartVerb = “FEST TIL START”
    $UnPinFromStartVerb = “LØSNE FRA START”
    }

    “SE” {
    $PinToStartVerb = “FÄST PÅ START”
    $UnPinFromStartVerb = “TA BORT FRÅN START”
    }

    default {
    $PinToStartVerb = “PIN TO START”
    $UnPinFromStartVerb = “UNPIN FROM START”
    }
    }
    Fixing the syntax here and adding a fourth (optional) argument to specify the language would make this script truly international 😉

    Thank you again and br
    Axel

    Like

  12. Hi again 😉

    I figured out the Switch statement:
    Switch ($args[3]) {
    “NO” {
    $PinToStartVerb = “FEST TIL START”
    $UnPinFromStartVerb = “LØSNE FRA START”
    $Language = “NO”
    }

    “SE” {
    $PinToStartVerb = “FÄST PÅ START”
    $UnPinFromStartVerb = “TA BORT FRÅN START”
    $Language = “SE”
    }

    default {
    $PinToStartVerb = “PIN TO START”
    $UnPinFromStartVerb = “UNPIN FROM START”
    $Language = “EN”
    }
    }

    I also changed the line
    if ($args.count -gt 3){
    to
    if ($args.count -ge 3){
    and added
    write-host “Language =”$Language`r`n
    to the bottom of that.

    Now I can call the script with a language argument 😉
    Had to compile a new exe which gets blocked by the AV but I’m hoping that it’ll be green-lighted by tomorrow…

    Thank you again!
    Axel

    Like

    1. Or…

      You could use…
      (Get-WinSystemLocale).Name
      … and then set the verbs by variables for the verbs accordingly and repeat for any known .

      Example…

      Replace

      $PinToStartVerb = “PIN TO START”
      $UnPinFromStartVerb = “UNPIN FROM START”

      With…

      if ((Get-WinSystemLocale).Name -eq “en-GB” -Or (Get-WinSystemLocale).Name -eq “en-US”){
      $PinToStartVerb = “PIN TO START”
      $UnPinFromStartVerb = “UNPIN FROM START”
      }

      if ((Get-WinSystemLocale).Name -eq “nb-NO”){
      $PinToStartVerb = “FEST TIL START”
      $UnPinFromStartVerb = “LØSNE FRA START”
      }

      if ((Get-WinSystemLocale).Name -eq “sv-SE”){
      $PinToStartVerb = “FÄST PÅ START”
      $UnPinFromStartVerb = “TA BORT FRÅN START”
      }

      Better than that there must be a way to read the verb strings from the dll. I did give it a look but I couldn’t find a way to do it but the above would work perfectly fine.

      I’ll need to find some time to look into the other issue you’ve listed about the Get-Childitem with the trailing backslash and asterisk.

      The script is not set in stone (the benefit of a script rather than an executable) so it’s nice to see people taking it (and fixing it) and making it work for them.

      Like

      1. Thanks Stuart! That’s a much more refined way to do it 😉

        However, I have more bad news… The script (both PS and EXE, both your and my version) fails to pin icons on a personal (non domain joined) computer… It might be something other than the fact that it’s not joined to a domain but I have no idea of what that might be…

        The PC I’m trying it on now has a fresh install of Win10 1809 whereas the other one (the one that’s in a domain) has been upgraded from 1607 (all the way up to 1809). But I also have my own PC, which has been upgraded from 1709, it doesn’t work there either.

        Seems that both pin to Start and pin to taskbar fails. I’ve added some Write-Host lines just to check that the language code works, it does 😉

        Oh well… It’s a disappointment but my main use of this script is on domain joined computers and i have by far more of those so I can easily live with having to pin manually on the few non-joined computers I manage 😀

        I’m looking forward to using your script going forward!
        Axel

        Like

  13. Thanks again, Stuart, no improvement for me yet, but here’s the german translation:

    if ($SystemLocale -eq “de-DE”){
    $PinToStartVerb = “An Taskleiste anheften”
    $UnPinFromStartVerb = “Von Taskleiste lösen”

    if ($SystemLocale -eq “de-AT”){
    $PinToStartVerb = “An Taskleiste anheften”
    $UnPinFromStartVerb = “Von Taskleiste lösen”

    Like

    1. Simon, there are two lines in the script… #$file.Verbs() | select *
      Can you remove the hash so that it echoes out all of the verbs found and then paste the whole contents of the window in order to see what is happening?

      Like

      1. Hey Stuart,
        here’s the output:
        —-
        c:\temp\PinTo10_v4_0.3> .\PinTo10_v4.ps1 ‘C:\ProgramData\Microsoft\Windows\Start Menu\Program
        s\Acrobat Reader DC.lnk’ PIN START

        TargetFile = C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Acrobat Reader DC.lnk

        PinUnpin = PIN

        Location = START

        Target file found. Continuing…

        PINUNPIN variable set to PIN

        LOCATION variable set to START

        FullFileName = Acrobat Reader DC

        FileNameWithExt = Acrobat Reader DC.lnk

        Directory = C:\ProgramData\Microsoft\Windows\Start Menu\Programs

        Shortcut found in current user’s start menu, no need to copy, just pin

        FileNameWithExt = Acrobat Reader DC.lnk

        Directory = C:\ProgramData\Microsoft\Windows\Start Menu\Programs

        Application Parent Name
        ———– —— —-
        Ö&ffnen

        Da&teipfad öffnen
        An Startmenü anheften (Open-Shell)
        &Behandeln von Kompatibilitätsproblemen
        Vorg&ängerversionen wiederherstellen

        &Ausschneiden
        &Kopieren
        &Verknüpfung erstellen
        &Löschen
        &Umbenennen
        E&igenschaften

        c:\temp\PinTo10_v4_0.3>
        —–
        Thanks!
        Simon

        Like

  14. Simon, the verbs that you have given me are related to the TaskBar, not the Start Menu (the script only needs the Start Menu localized verbs as it handles the TaskBar in a different way) so the script is only ever looking for the English verbs.

    I’ve updated the download to version 4.04 to try and add support for German and Austrian locales. Download that one and give it a go.

    Stuart

    Like

    1. Hey Stuart,

      I noticed a couple of things:
      1) Pinning to the taskbar now works for me
      2) correction of the systemlocale thing for german. It should say:
      if ($SystemLocale -eq “de-DE” -Or $SystemLocale -eq “de-AT”){
      $PinToStartVerb = “AN START ANHEFTEN”
      $UnPinFromStartVerb = “VON START LÖSEN”
      3) I am using Open-Shell, so this might change context menu entries
      4) here’s the output for startmenu:

      PS C:\temp\> .\PinTo10_v4.ps1 ‘C:\programdata\Microsoft\Windows\Start Menu\Programs\7-Zip File Manager.lnk’ PIN START

      TargetFile = C:\programdata\Microsoft\Windows\Start Menu\Programs\7-Zip File Manager.lnk

      PinUnpin = PIN

      Location = START

      Target file found. Continuing…

      PINUNPIN variable set to PIN

      LOCATION variable set to START

      FullFileName = 7-Zip File Manager

      FileNameWithExt = 7-Zip File Manager.lnk

      Directory = C:\programdata\Microsoft\Windows\Start Menu\Programs

      Shortcut not found in current user’s start menu. Need to check the all users start menu now

      Shortcut found in all user’s start menu, no need to copy, just pin

      FileNameWithExt = 7-Zip File Manager.lnk

      Directory = C:\programdata\Microsoft\Windows\Start Menu\Programs

      Application Parent Name
      ———– —— —-
      &Öffnen
      Da&teipfad öffnen
      An Startmenü anheften (Open-Shell)
      &Als Administrator ausführen
      &Behandeln von Kompatibilitätsproblemen
      An “Start” an&heften

      Edit with &Notepad++
      Mit Windows Defender überprüfen…
      In MagentaCLOUD speichern
      Von &Taskleiste lösen
      Vorg&ängerversionen wiederherstellen

      &Ausschneiden
      &Kopieren
      &Verknüpfung erstellen
      &Löschen
      &Umbenennen
      E&igenschaften

      PS C:\Users\temp>

      Thanks,
      Simon

      Like

      1. Simon, I’ve made another change which should allow pinning to the Open-Shell Start Menu work for you. HOWEVER… Open-Shell Start Menu is completely different to the Windows Start Menu (as I’m sure you’re aware), to pin to the Open-Shell Start Menu you only need to copy a shortcut into…
        %APPDATA%\OpenShell\Pinned

        If you want to unpin using this script then you have to use the shortcut file from inside %APPDATA%\OpenShell\Pinned as your target file as the unpin verb only exists on that file. You can keep pinning the same file to the Open-Shell Start Menu and it will just keep duplicating and the verb doesn’t change to unpin. This may be a bug in Open-Shell or it may be by design. I’m not going to suggest I offer any further support for it as it’s actually really easy to simply copy and delete files from there (I wish the Windows Start Menu was that easy).

        Stuart

        Like

  15. Hi, how i can create your script to an exe file, on my pc it doesent´t work. could you add an exe file on your dropbox?
    Thanks

    Dennis

    Like

    1. Preview build? That just means that Microsoft are trying harder and harder for these sort of scripts to keep working (or something’s broken in the preview build). Either way, I’m not sure that this is a viable method to keep expecting to work moving forward so I’m looking at leaving a blank TaskBar and Start Menu in the future…

      Like

      1. It can not be pinned due to that there is no verb “Pin to…” (if in English).

        # create shortcut for Devices
        $target = “$env:SystemRoot\System32\control.exe”
        $file = “$env:AppData\Microsoft\Windows\Start Menu\Programs\System Tools\Devices.lnk”
        $shell = New-Object -ComObject Wscript.Shell
        $shortcut = $shell.CreateShortcut($file)
        $shortcut.TargetPath = $target
        $shortcut.Arguments = “/name Microsoft.DevicesAndPrinters”
        $shortCut.IconLocation = “$env:SystemRoot\system32\DeviceCenter.dll”
        $shortcut.Save()

        That is the problem, not build version.

        Like

  16. How control panel could be pinned?
    It is located in “$env:APPDATA\Microsoft\Windows\Start Menu\Programs\System Tools”. By default it doesn’t have “Pin to Start ” verb, so I created a shortcut. Verb appeared, but even it’s pinned, verb doesn’t change from “pin to…” to “unpin from…”.

    Like

    1. How did you create the Control Panel shortcut in order to have the verb available to it? My script might not perform well when the target is a GUID (not direct to an exe file) so that may be an issue.

      Like

      1. $target = “control”
        $file = “$env:APPDATA\Microsoft\Windows\Start Menu\Programs\System Tools\Control 2.lnk”
        $shell = New-Object -ComObject Wscript.Shell
        $shortcut = $shell.CreateShortcut($file)
        $shortcut.TargetPath = $target
        $shortCut.IconLocation = “$env:SystemRoot\system32\control.exe”
        $shortcut.Save()

        Liked by 1 person

  17. Running through that manually also produces strange results. Right-clicking the shortcut that bit of powershell creates and choosing “Pin to Start” never changes the verb (on my 1809 install at least) to “Unpin from Start”. It actually creates another shortcut inside %APPDATA%\Roaming\Microsoft\Windows\Start Menu\Programs with the same name and pins that.

    Sadly I can’t replicate the actual pinning via script. The “Pin” verb is not available on the control.exe file so Windows is doing something else when the manual pinning is done.

    Like

  18. I’m using the version 1.1 for many years without issues, just tested on the build 1903 of windows, it’s not working. I’ve also tested the latest version of the tool (both VBS and EXE) and it’s not working either. Do you think you will try to update it? You would save my life 🙂

    Like

    1. Hi Fred. I’ve only just installed 1903 (although I was already aware that it does not work). I might get a chance to take another look, but in truth I don’t think I have the skills to really debug what has changed. Fingers crossed though. I’ve already changed my 1809 deployments to use a fixed Taskbar and pre-configured Start menu.

      Like

      1. Actually, pinning to Start no longer seems viable. Access is denied and it seems as though Microsoft have made significant efforts to disable scripting access to the process.

        Like

      2. It’s just my opinion, but only having the task bar working is already a huge benefit as it’s the most “visible” for users. Thanks a lot for doing this !

        Like

      3. Hi Stuart, I have used the official Microsoft docs method to customize the taskbar for Windows 10 (1903) deployment, however I have an issue with Chrome and its default profile I copied into the default user folder.
        After opening Chrome, everything seems to be all right until the next log off or restart, after which Chrome is pinned twice on the taskbar.
        If you remove Chrome from the layoutmodification.xml and pin it manually, everything works fine.

        I would like to use your Masquerade-PEB based script to ping Chrome when the profile is first created, however, I would rather not use powershell (with its executionpolicy restrictions) and I was wondering if your taskbar pin script is available in vbscript, I would really appreciate if you could share that

        Stuart Edit… (can’t reply to this post…)
        The masquerade PEB is a .NET function (if I remember correctly) and can’t be ported to VBS, sorry.

        Like

    1. You’d have to ask the author of that function. I’m quite familiar with AutoIt but wouldn’t know where to start, if it’s even possible, to port the native .Net code to the AutoIt language.

      If anyone is wanting a fully functional, closed-source solution then a new version of Syspin has just been released that now supports Start and TaskBar pinning on 1903 (so it can be done).

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

      Like

      1. I am not affiliated with the author of Syspin. If you can track him down then feel free to request a 32-bit version (and also his source code too 🙂 )

        Like

  19. Contratulation for this scrips!

    i have a issue running with SCCM. i deploy the ps in a MSI transform (MST) with SCCM. In client execution user is System and with this user, logicaly, don´t run. Do you how to do to pinto task bar in the login user?

    Regards and thank you for your time!

    José

    Like

    1. Hi José,

      Typically I would have an SCCM Package that simply creates a scheduled task to run as any user at logon (or create a RunOnce entry in the registry). The same package (or a different pre-requisite one) can copy the script files locally as required. I copy the script files to %ALLUSERSPROFILE%\%COMPANYNAME% so everyone has read access.

      If using a scheduled task (I do) then the script can write a file at the end of the process to check for at the start of the process so it effectively doesn’t do the pins on subsequent logins (unless you want to).

      Given the fact that my scripts don’t work correctly in 1903 I’ve all but abandoned these scripts in favour of Microsoft’s supported XML system…
      https://docs.microsoft.com/en-us/windows/configuration/configure-windows-10-taskbar
      https://docs.microsoft.com/en-us/windows/configuration/windows-10-start-layout-options-and-policies

      … which can be managed by GPO or done as part of an SCCM Task Sequence.

      hope this is helpful…

      Stuart

      Like

  20. I’ve reversed syspin,
    Its principle is to inject explorer and then call the’pin to task’ method in explorer.
    i made a copy like syspin,mine exe’size only 17kb,but syspin’s size is 19kb,
    Not sure if there is a back door in syspin

    Like

      1. Probably doesn’t work via NSIS as it needs to run in user context, not as admin typically. Most times NSIS will be running as admin. One most typical way to resolve this is to create a scheduled task that runs as “USERS” and then to invoke the scheduled task.

        Stuart

        Like

  21. Looks like the pin to taskbar still works on 1909, but bitdefender antivirus flags it as malware. I haven’t done any thorough testing, however by the looks of it, I will need to rebuild my reference image using a different method. 😦

    Like

Leave a Reply to TestPin Cancel reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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