I've found a nasty VBS way to do this, but I'm looking for a native PoSh procedure to edit the properties of a .LNK file. The goal is to reach out to remote machines, duplicate an existing shortcut with most of the correct properties, and edit a couple of them.
If it would just be easier to write a new shortcut file, that would work too.
Just drag and drop them into the Notepad window. If you open them via the Open dialog, Notepad will open the exe file pointed to by the . lnk file.
doc file in a folder and select Copy and then right-click the Desktop and selectPaste Shortcut, Windows creates a . lnk file that points to the . doc file.
Copy-Item $sourcepath $destination ## Get the lnk we want to use as a template
$shell = New-Object -COM WScript.Shell
$shortcut = $shell.CreateShortcut($destination) ## Open the lnk
$shortcut.TargetPath = "C:\path\to\new\exe.exe" ## Make changes
$shortcut.Description = "Our new link" ## This is the "Comment" field
$shortcut.Save() ## Save
Found the VB version of the code here: http://www.tutorialized.com/view/tutorial/Extract-the-target-file-from-a-shortcut-file-.lnk/18349
Below are the functions I use for dealing with .lnk files. They are modified versions of the functions found here as mentioned by @Nathan Hartley. I've improved Get-Shortcut
to handle wildcards like *
by passing strings to dir
to expand them into sets of FileInfo objects.
function Get-Shortcut {
param(
$path = $null
)
$obj = New-Object -ComObject WScript.Shell
if ($path -eq $null) {
$pathUser = [System.Environment]::GetFolderPath('StartMenu')
$pathCommon = $obj.SpecialFolders.Item('AllUsersStartMenu')
$path = dir $pathUser, $pathCommon -Filter *.lnk -Recurse
}
if ($path -is [string]) {
$path = dir $path -Filter *.lnk
}
$path | ForEach-Object {
if ($_ -is [string]) {
$_ = dir $_ -Filter *.lnk
}
if ($_) {
$link = $obj.CreateShortcut($_.FullName)
$info = @{}
$info.Hotkey = $link.Hotkey
$info.TargetPath = $link.TargetPath
$info.LinkPath = $link.FullName
$info.Arguments = $link.Arguments
$info.Target = try {Split-Path $info.TargetPath -Leaf } catch { 'n/a'}
$info.Link = try { Split-Path $info.LinkPath -Leaf } catch { 'n/a'}
$info.WindowStyle = $link.WindowStyle
$info.IconLocation = $link.IconLocation
New-Object PSObject -Property $info
}
}
}
function Set-Shortcut {
param(
[Parameter(ValueFromPipelineByPropertyName=$true)]
$LinkPath,
$Hotkey,
$IconLocation,
$Arguments,
$TargetPath
)
begin {
$shell = New-Object -ComObject WScript.Shell
}
process {
$link = $shell.CreateShortcut($LinkPath)
$PSCmdlet.MyInvocation.BoundParameters.GetEnumerator() |
Where-Object { $_.key -ne 'LinkPath' } |
ForEach-Object { $link.$($_.key) = $_.value }
$link.Save()
}
}
A short addition to @JasonMArcher's answer..
To see available properties you can just run $shortcut
after $shortcut = $shell.CreateShortcut($destination)
in a PS.
This will print all properties and their current values.
I don't think there's a native way.
There is this DOS util: Shortcut.exe.
You still need to copy the util to the remote system, then possibly call it using WMI to make the changes you're looking for.
I'm thinking the easier way will be to overwrite and/or create a new file.
Do you have access to these systems via a remote share?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With