I have seen many similar questions posted on stackoverflow.com, but this is different, and before you are wondering, why don't I post the question on stackoverflow.com? Because I am currently banned from asking questions there, and I currently don't have enough time to edit all those questions.
A brief description of what I want to do: I want to pin elevated cmd, powershell, pwsh, python etc. to taskbar programmatically, and of course I know how to create shortcuts using explorer.exe and pin them, but I consider the GUI method to be tiresome and tedious, having to click many times to get a simple job done, and I want to pin many programs...
I have found this:
How to create a Run As Administrator shortcut using Powershell
An example:
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$Home\Desktop\PowerShell.lnk")
$Shortcut.TargetPath = "C:\Windows\System32\WindowsPowerShell\v1.0\PowerShell.exe"
$Shortcut.Save()
$bytes = [System.IO.File]::ReadAllBytes("$Home\Desktop\PowerShell.lnk")
$bytes[0x15] = $bytes[0x15] -bor 0x20
[System.IO.File]::WriteAllBytes("$Home\Desktop\PowerShell.lnk", $bytes)
The example will create a shortcut to default PowerShell named "PowerShell" on desktop with admin rights.
Now, to wrap it in a function:
function admin-shortcut {
PARAM (
[Parameter(ValueFromPipeline=$true, Mandatory=$true, Position=0)] [system.string] $path,
[Parameter(ValueFromPipeline=$true, Mandatory=$true, Position=1)] [system.string] $name
)
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$Home\Desktop\$name.lnk")
$Shortcut.TargetPath = $path
$Shortcut.Save()
$bytes = [System.IO.File]::ReadAllBytes("$Home\Desktop\$name.lnk")
$bytes[0x15] = $bytes[0x15] -bor 0x20
[System.IO.File]::WriteAllBytes("$Home\Desktop\$name.lnk", $bytes)
}
I have seen many posts on stackoverflow.com about methods to pin programs directly to taskbar, but none of them solves my problem as I want to give the pinned shortcuts Administrator privileges, none of the methods I have seen does it.
So I Googled how to create an admin shortcut using PowerShell, and found the method mentioned above, now I only need to figure out how to pin the .lnk files to taskbar, unfortunately all Google search results of "how to pin shortcuts to taskbar" talks about pinning the program directly, none of them involves .lnk files, and I already explained why they won't work in this case.
So do you have any ideas? Any help will be appreciated.
Outdated methods that no longer work on Windows 10:
Method #1
$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');
Method #2
$shell = new-object -com "Shell.Application"
$folder = $shell.Namespace('C:\Windows')
$item = $folder.Parsename('notepad.exe')
$verb = $item.Verbs() | ? {$_.Name -eq 'Pin to Tas&kbar'}
if ($verb) {$verb.DoIt()}
Method #3
$sa = new-object -c shell.application
$pn = $sa.namespace($env:windir).parsename('notepad.exe')
$pn.invokeverb('taskbarpin')
I pasted all these codes into PowerShell, no error messages showed up, but these commands literally do nothing, I had even restarted explorer.exe, still no change observed...
But no, wait! All is not lost, I can drag the resultant shortcut to taskbar to pin it to taskbar, and I can right click and pin to start, but imagine dragging 2 dozens of them... If I can figure out what exactly these actions do, I can replicate them with commands...
I have opened %Appdata%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar
Folder and found some (non-UWP) app icons that I have pinned are indeed there,
and I have found some app icons that I have added to start menu here:
%AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\StartMenu
However, I have confirmed simply copying the shortcuts there wouldn't work.
Found this:https://docs.microsoft.com/en-us/windows/configuration/configure-windows-10-taskbar, it is useful.
I have found a method to do this, since all I want is to add lines to the xml file, I can use this:
[string[]]$xmlconfig=get-content $template | % {
$_
if ($_ -match $pattern) {$line}
}
I know this is stupid, that's why I didn't post it as an answer, but it does get the job done, don't laugh at me as I am still learning, I am currently researching how to properly manipulate .xml files...
I tried:
[xml]$template=Get-Content $templatefile
$template.SelectNodes("//DesktopApp")
But it doesn't work, it also doesn't work on xml objects converted from .admx files, however .ChildNodes works, and it is not shown by Get-Member... I think treating it like plain text file is the best method now, otherwise I have to use something like this:
$template.LayoutModificationTemplate.CustomTaskbarLayoutCollection.TaskbarLayout.TaskbarPinList.DesktopApp.DesktopApplicationLinkPath
I have already solved it, I will post it as an answer now, I didn't pursue the registry key, and I no longer want to pin programs to start menu as I don't normally use it...
The method you are looking for is Pin to Tas&kbar, but has been removed. MSFT's official word is that it was been removed so that programs can not pin unwanted items to the taskbar. [...] They also said that they would continue to make changes that will eventually prevent any application from pinning to a user's taskbar
. Maybe you're on a lost case here. But maybe you can see if there is anxml
for startmenu and taskbar. search forLayoutModificationTemplate