Skip to content

Commit f1f271b

Browse files
committed
Add New-RunasShortcut and Set-PinTaskbar commands
1 parent 6e98cc1 commit f1f271b

File tree

3 files changed

+181
-0
lines changed

3 files changed

+181
-0
lines changed

Modules/Scripts/New-RunasShortcut.ps1

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<#
2+
.SYNOPSIS
3+
Creates a new elevated shortcut to a given target
4+
5+
.PARAMETER LinkPath
6+
Path where the shortcut lnk file is to be created.
7+
This should include the name of the link.lnk file
8+
9+
.PARAMETER TargetPath
10+
Path of the executable to run from the shortcut
11+
12+
.PARAMETER Arguments
13+
Arguments to pass to the executable
14+
#>
15+
16+
param(
17+
[parameter(Mandatory=$True, HelpMessage='Path of shortcut lnk file to create')]
18+
[ValidateNotNullOrEmpty()]
19+
[string] $LinkPath,
20+
21+
[parameter(Mandatory=$True, HelpMessage='Path of executable')]
22+
[ValidateNotNullOrEmpty()]
23+
[string] $TargetPath,
24+
25+
[parameter(HelpMessage='Optional arguments to executable')]
26+
[string] $Arguments
27+
)
28+
29+
if (Test-Path $TargetPath)
30+
{
31+
$TargetPath = (Resolve-Path $TargetPath).Path
32+
}
33+
else
34+
{
35+
Write-Warning "$TargetPath does not exist"
36+
return
37+
}
38+
39+
$shortcut = (New-Object -comObject WScript.Shell).CreateShortcut($LinkPath)
40+
$shortcut.TargetPath = $TargetPath
41+
42+
if ($Arguments)
43+
{
44+
$shortcut.Arguments = $Arguments
45+
}
46+
47+
$shortcut.Save()
48+
49+
# the magic...
50+
51+
$bytes = [IO.File]::ReadAllBytes($LinkPath)
52+
$bytes[0x15] = $bytes[0x15] -bor 0x20 #set byte 21 (0x15) bit 6 (0x20) ON
53+
$bytes | Set-Content $LinkPath -Encoding Byte

Modules/Scripts/Set-PinTaskbar.ps1

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<#
2+
.SYNOPSIS
3+
Pins or unpins a target item to the Windows Taskbar
4+
5+
.PARAMETER Target
6+
Path of the target item to pin to the Taskbar
7+
8+
.PARAMETER Unpin
9+
If true then unpin target from the Taskbar
10+
11+
.NOTES
12+
https://community.spiceworks.com/topic/2165665-pinning-taskbar-items-with-powershell-script
13+
#>
14+
15+
param(
16+
[parameter(Mandatory=$True, HelpMessage='Path of target item to pin to the Taskbar')]
17+
[ValidateNotNullOrEmpty()]
18+
[string] $Target,
19+
20+
[Parameter(HelpMessage='If true then unpin target from the Taskbar')]
21+
[switch] $Unpin
22+
)
23+
24+
Begin
25+
{
26+
function RegisterShellHandlerVerb
27+
{
28+
Write-Verbose '... registering shell handler verb'
29+
$guid = (Get-ItemProperty ('HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\' + `
30+
'Explorer\CommandStore\shell\Windows.taskbarpin')
31+
).ExplorerCommandHandler
32+
33+
$script:shellKey = (Get-Item 'HKCU:\SOFTWARE\Classes'
34+
).OpenSubKey('*', $true
35+
).CreateSubKey('shell', $true)
36+
37+
$shellKey.CreateSubKey('{:}', $true).SetValue('ExplorerCommandHandler', $guid)
38+
Write-Verbose '... shell handler verb registered'
39+
}
40+
41+
function UnregsisterShellHandlerVerb
42+
{
43+
if ($shellKey)
44+
{
45+
Write-Verbose '... unregistering shell handler verb'
46+
$shellKey.DeleteSubKeyTree('{:}', $false)
47+
$shellKey.Close()
48+
$shellKey.Dispose()
49+
Write-Verbose '... shell handler verb unregistered'
50+
}
51+
}
52+
53+
function GetTaskbandPinMap
54+
{
55+
Write-Verbose '... getting Taskband pin map'
56+
# Taskband\FavoritesResolve is a binary value containing pinned items
57+
$key = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband'
58+
$name = 'FavoritesResolve'
59+
60+
# gets contents in ASCII format and filter out non-readable chars so -like will work
61+
return [Text.Encoding]::ASCII.GetString(
62+
(Get-ItemProperty -Path $key -Name $name | Select-Object -ExpandProperty $name)
63+
) -Replace '[^\x20-\x2f^\x30-\x39\x41-\x5A\x61-\x7F]+', ''
64+
}
65+
66+
function InvokeShellHandlerVerb
67+
{
68+
Write-Verbose '... invoking handler verb'
69+
$item = (Get-Item $Target)
70+
71+
(New-Object -ComObject 'Shell.Application'
72+
).Namespace($item.DirectoryName
73+
).ParseName($item.Name
74+
).InvokeVerb('{:}')
75+
76+
Write-Verbose '... handler verb invoked'
77+
}
78+
}
79+
Process
80+
{
81+
if (!(Test-Elevated))
82+
{
83+
Write-Warning 'must run from an elevated process'
84+
}
85+
86+
if (Test-Path $Target)
87+
{
88+
$Target = (Resolve-Path $Target).Path
89+
}
90+
else
91+
{
92+
Write-Warning "$Target does not exist"
93+
return
94+
}
95+
96+
RegisterShellHandlerVerb
97+
98+
$map = GetTaskbandPinMap
99+
100+
if ($Unpin)
101+
{
102+
# only unpin if item is pinned
103+
if ($map.Contains((Split-Path $Target -Leaf)))
104+
{
105+
Write-Verbose '... unpinning'
106+
InvokeShellHandlerVerb
107+
}
108+
}
109+
else
110+
{
111+
# only pin if item hasn't been pinned
112+
if (!$map.Contains((Split-Path $Target -Leaf)))
113+
{
114+
Write-Verbose '... pinning'
115+
InvokeShellHandlerVerb
116+
}
117+
}
118+
}
119+
End
120+
{
121+
UnregsisterShellHandlerVerb
122+
}

readme.md

+6
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ Create a persistent mapping of a folder to a new drive letter. (persistent SUBST
173173
#### `New-Host` -IP a -Name n
174174
Adds or updates an entry in the Windows hosts file
175175

176+
#### `New-RunAsShortcut` -LinkPath l -TargetPath t [-Arguments a]
177+
Creates a new elevated shortcut (.lnk file) to a given target
178+
176179
#### `New-VMClone` -Name n -Path p -Template t [-Checkpoint]
177180
Create a new VM from a registered VM or an exported VM.
178181

@@ -206,6 +209,9 @@ Set the ownership of an item - folder or file - to the specified user group.
206209
#### `Set-OutDefaultOverride`
207210
(Internal) Helper function for Get-ChildItemColorized.
208211

212+
#### `Set-PinTaskbar` -Target t [-Unpin]
213+
Pins or unpins a target item to the Windows Taskbar (_currently broken!_)
214+
209215
#### `Set-RegistryOwner` -Hive h -Key k [-Recurse]
210216
Set full-access ownership of a specified Registry key.
211217

0 commit comments

Comments
 (0)