Add mstsc to shortcut target powershell - powershell

A little background about what I'm trying to do and why. We are slowly migrating from using a local copy of office on our end users Win7 machines to publishing office through RDS 2012. With 2012 you can have the end users machine subscribe to a webfeed which puts the shortcuts to the actual RDP files in Appdata. In order to have our image pretty much mirror before RDS, I need to pin the shortcuts to the taskbar. If you pin the shortcut as it comes from the RDS Gateway server the icon on the taskbar is that of the .rdp file. If you edit the target for the shortcut and put mstsc.exe before the path to the .rdp file you can then pin the shortcut to the taskbar using those icons of the shortcut.
I have found posts on how to change the target field of shortcuts but nothing on how to add something to what is currently there. An environment variable is needed since the path to the shorts will be different for each user. Below is I have tried thus far
$Word = $env:userprofile + "\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\RemoteApp and Desktop Connections\Microsoft Word 2010.lnk"
$sh = New-Object -COM WScript.Shell
$targetPath = $sh.CreateShortcut($Word).TargetPath
$sh.TargetPath = "mstsc.exe" + $targetPath ## Make changes
$sh.Save() ## Save$shell = New-Object -COM WScript.Shell
One of the errors i'm getting is : Property 'Arguments' cannot be found on this object; make sure it exists and is settable.
Any help will be greatly appreciated.

Instead of using Shell COM object, how about using a .Net wrapper class? There is a great sample.
To use the VBAccelerator's wrapper in Powershell, extract the source code and compile a DLL like so,
C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:library /out:ShellLink.dll /r:System.Drawing.dll .\ShellLink.cs .\FileIcon.cs
This should create ShellLink.dll, which you can add as Powershell type like so,
Add-Type -path .\ShellLink.dll
And use the class by creating a new object like so,
$lnk = new-object vbAccelerator.Components.Shell.ShellLink
$lnk.Target = "C:\Windows\System32\mstsc.exe"
$lnk.Arguments = "some arguments"
$lnk.Description = "My awesome shortcut"
$lnk.Save("c:\temp\test.lnk")

Your code will prepend "mstsc.exe" to the current target path if you just add this line before your ## Make changes line:
$sh = $sh.CreateShortcut($word)
Sounds like you also want to add a space, so that your lnk file is the "connection file" argument of mstsc.exe. You can set the Arguments property like so:
function Set-RDSshortcut {
param( [parameter(mandatory=$true)]$Shortcut )
$sh = New-Object -COM WScript.Shell
$targetPath = $sh.CreateShortcut($Shortcut).TargetPath
$targetPath = "mstsc.exe"
$sh = $sh.CreateShortcut($Shortcut)
$sh.TargetPath = $targetPath
$sh.Arguments = $Shortcut
$sh.Save()
} #end function

Related

Making a .lnk that opens in a new window with powershell

Good Day everyone!
I am looking to make PowerShell script that creates a .lnk shortcut on the desktop. Which isn't too big a deal, but when I make one manually with chrome, 3 dots>more tools>create shortcut I get this option. Notice how it has the "Open in a new window" option. That is what I'm looking to accomplish. How would I go about making a .lnk file on the desktop that opens in a new window?
make an .lnk shortcut on desktop save it to desktop
.lnk file opens in new window
-preferably grabs an icon from the browser like when you make one with chrome so I don't have to point to one.
$Shell = New-Object -ComObject ("WScript.Shell")
$Favorite = $Shell.CreateShortcut($env:USERPROFILE + "\Desktop\Google.lnk")
$Favorite.TargetPath = "http://google.com";
$Favorite.IconLocation = "Picturelocation"
$Favorite.Arguments
$Favorite.Save()
Thanks for your time!
Notice the Icon and Open in a New window button
Use the following to create a shortcut file (.lnk) that launches Chrome with a given URL in a new window:
# Define the target URL
$url = 'https://google.com'
# Derive a friendly site name from it, to serve as the name
# of the shortcut file and the downloaded favicon.
# Adjust as needed, e.g. $friendlySiteName = 'Google'
$friendlySiteName = $url -replace '^https?://(?:www\.)?'
# Determine the full path of the shortcut file; adjust as needed.
# Note the required ".lnk" extension
$shortcutPath = "$HOME\Desktop\$friendlySiteName.lnk"
# Determine the full path of the chrome.exe executable, via the registry.
# Note: This is only necessary because chrome.exe is *not* in one
# of the directories listed in $env:PATH.
$chromeExePath = Get-ItemPropertyValue -LiteralPath 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe' '(default)'
# Download the favicon:
# Create a designated local directory for storing favicons...
$targetDir = New-Item -Type Directory -Force "$HOME\favicons"
# ... and download the target site's favicon into it.
$favIconPath = Join-Path $targetDir.FullName ($friendlySiteName + '.ico')
& {
$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest -OutFile $favIconPath "$url/favicon.ico"
}
# Create the shortcut file, set its properties, and save it.
$shell = New-Object -ComObject WScript.Shell
$favorite = $shell.CreateShortcut($shortcutPath)
# Tell the shortcut to launch Chrome...
$favorite.TargetPath = $chromeExePath
# ... with the following arguments; -new-window ensures that the
# specified URL is opened in a new window.
$favorite.Arguments = "-new-window $url"
# ... and assign the icon.
$favorite.IconLocation = $favIconPath
$favorite.Save()
Note: The above downloads and assigns the target site's specific favicon as the shortcut file's icon, you can omit the relevant code above, which will make the shortcut file show Chrome's icon.
For the sake of completeness: Creating a URL shortcut file (.url) with the target site's favicon:
Note that such URL shortcut files invariably:
use the default web browser on invocation, and default to that browser's own icon.
typically create a new tab in an existing browser window rather than opening a new window.
As explained in this answer, assigning a custom icon programmatically isn't directly supported via the WScript.Shell COM object, but can be achieved via plain-text processing to modify the .url file after the fact, as shown below.
# Define the target URL.
$url = 'https://google.com'
# Derive a friendly representation from it, to serve as the name of the shortcut file
# and the downloaded favicon.
# Adjust as needed; e.g. $friendlySiteName = 'Google'
$friendlySiteName = $url -replace '^https?://(?:www\.)?'
# Determine the full path of the shortcut file; adjust as needed.
# Note the required ".url" extension.
$urlShortcutPath = "$HOME\Desktop\$friendlySiteName.url"
# Download the favicon:
# Create a designated local directory for storing favicons...
$targetDir = New-Item -Type Directory -Force "$HOME\favicons"
# ... and download the target site's favicon into it.
$favIconPath = Join-Path $targetDir.FullName ($friendlySiteName + '.ico')
& {
$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest -OutFile $favIconPath "$url/favicon.ico"
}
# Create the URL shortcut file, set its properties, and save it.
$shell = New-Object -ComObject WScript.Shell
$urlShortcut = $shell.CreateShortcut($urlShortcutPath)
# Tell the URL shortcut what URL to launch.
# !! No other properties are directly supported for URL shortcut files.
# !! Plain-text processing below compensates for that.
$urlShortcut.TargetPath = $url
$urlShortcut.Save()
# Now use plain-text processing to add the icon location.
Add-Content -LiteralPath $urlShortcut.FullName -Value #"
IconIndex=0
HotKey=0
IconFile=$favIconPath
"#

Creating a RDP icon on desktop with specific parameters

Does anybody have a Powershell script that generates a RDP icon on the desktop of the user. I already have the code for the desktop icon creation. But the next thing I need is the RDP extension to be created with specific paramters (Single usage of monitor)
Thanks in advance!
$wshshell = New-Object -ComObject WScript.Shell
$lnk = $wshshell.CreateShortcut("C:\Users\Public\Desktop\RDP.lnk")
$lnk.TargetPath = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Accessories\Remote Desktop Connection.lnk"
$lnk.Description = "RDP"
$lnk.Save()
You did it almost correct. But better to set TargetPath to mstsc.exe directly.
Use $lnk.Arguments to set parameters like server name (/v), fullscreen (/f) and others.
$wshshell = New-Object -ComObject WScript.Shell
$lnk = $wshshell.CreateShortcut("C:\Users\Public\Desktop\RDP.lnk")
$lnk.TargetPath = "%windir%\system32\mstsc.exe"
$lnk.Description = "RDP"
$lnk.Arguments = "/v:server-1 /f"
$lnk.Save()
If you need some tweaks inside mstsc its better to use shared folder for all computers and place .rdp file with your config here. After that use $lnk.TargetPath to this .rdp file.

Create " *.url " file using powershell and CMD

i was inquiring if there are options to create a url shortcut to be placed on c:\users\username\favorites to be applied to be added to the login script of the user on Active directory to create the favorites for any user
i tried searching all over the internet and i only found "MD" and "MKDir" commands
Not the most PowerShell answer but this is the widely used one with the best compatibility in versions. Much like this answer but small changes for URLs
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$Home\Favorites\Google.url")
$Shortcut.TargetPath = "http://www.google.ca"
$Shortcut.Save()
This will make a shortcut to Google in your favorites. $Home being one of PowerShell's Automatic Variables
If you happen to have PowerShell 5.0 it can now do this natively. Again refer to this answer for more information

creating a shortcut on a remote desktop, but the shortcut is created with a "file" instead of "file folder" as the "target type"

I'm trying to create a shortcut on a remote desktop in the domain here, and I'm a domain admin. If I run the following code directly on the target machine, the shortcut can be created and is able to lead me to the target path.
$shortcutpath3 = "c:\Users\Public\Desktop\Shortcuts to Test Custom\VV 1211 -TC.lnk"
$WshShell3 = New-Object -comObject WScript.Shell
$Shortcut3 = $WshShell3.CreateShortcut($shortcutpath3)
$Shortcut3.TargetPath = "\\machine\testcustom\"
$Shortcut3.Save()
I saved this script as test.ps1, run it with folloing code on a different mahchine. The code ends without any errors/warings, and the shortcut is created on the target machine with the propeties i specified. But it cannot lead me to the target place, it actually ask me to pick a program to open that file. I compared the properties of the 2 shortcuts, and found that the "target type" of the broken shortcut is "file" while it is "file folder" for a good shortcut.
Invoke-Command -ComputerName TARGETSERVER -FilePath test.ps1
Any idea how i can fix this? And why is this happening? Thank!!!
I had the same problem and and I used Get-Item to make it work. Try this:
$targetPath = Get-Item("\\machine\testcustom\")
$WshShell3 = New-Object -comObject WScript.Shell
$Shortcut3 = $WshShell3.CreateShortcut($shortcutpath3)
$Shortcut3.TargetPath = $targetPath.FullName
$Shortcut3.Save()
Since you're a domain admin I'd strongly recommend doing this with a Group Policy Preference. You can restrict shortcut creation to particular users/groups/computers/etc. via item-level targeting.
I've been battling this for the past several hours, Googling to no avail. For posterity, here's my summary. While alternatives suggestions are appreciated:
PowerShell inexplicably has no direct way to create a shortcut. It can create symbolic link, but 1) it requires admin rights, and 2) it behaves differently.
Group Policy Preferences are great--but only if your machines are in office or routinely on a VPN.
If you're trying to create a shortcut to a network folder, setting the TargetPath to that folder only works if the computer actually can reach it when the script runs, i.e. same issue as with Group Policy Preferences. PowerShell will create the shortcut, but the Target Type will be a File rather than a File Folder (and I found no info online how to control that; trailing slash or not doesn't matter).
The behavior of running these code suggestions varies depending whether you run this interactively or as a script.
Here's what I found does work:
Set the $shortcut.TargetPath to "C:\Windows\Explorer.exe"
Add a line: $shortcut.Arguments = """Target folder""" (the """ are needed as an escape character for the shortcut to show as C:\Windows\Explorer.exe "Target folder")
So for your example above, the following should work (assuming permissions to c:\Users\Public\Desktop):
$shortcutpath3 = "c:\Users\Public\Desktop\Shortcuts to Test Custom\VV 1211 -TC.lnk"
$WshShell3 = New-Object -comObject WScript.Shell
$Shortcut3 = $WshShell3.CreateShortcut($shortcutpath3)
$Shortcut3.TargetPath = "C:\Windows\Explorer.exe"
$shortcut.Arguments = """\\machine\testcustom\"""
$Shortcut3.Save()

Powershell running under a service hangs on *.zip CopyHere

I'm running a Windows Service (Hudson) which in turn spawns a PowerShell process to run my custom PowerShell commands. Part of my script is to unzip a file using CopyHere. When I run this script locally, I see a progress dialog pop up as the files are extracted and copied. However, when this runs under the service, it hangs at the point where a dialog would otherwise appear.
Here's the unzip portion of my script.
# Extract the contents of a zip file to a folder
function Extract-Zip {
param([string]$zipFilePath, [string]$destination)
if(test-path($zipFilePath)) {
$shellApplication = new-object -com shell.application
$zipFile = get-item $zipFilePath
$zipFolder = $shellApplication.NameSpace($zipFile.fullname)
$destinationFile = get-item $destination
$destinationFolder = $shellApplication.NameSpace($destinationFile.fullname)
$destinationFolder.CopyHere($zipFolder.Items())
}
}
I suspect that because its running under a service process which is headless (no interaction with the desktop), its somehow stuck trying to display a dialog.
Is there a way around this?
If it's still actual, I managed to fix this with having CopyHere params equal 1564.
So in my case extract zip function looks like:
function Expand-ZIPFile{
param(
$file, $destination
)
$shell = new-object -com shell.application
$zip = $shell.NameSpace($file)
foreach($item in $zip.items())
{
$shell.Namespace($destination).copyhere($item,1564)
"$($item.path) extracted"
}
1564 description can be found here - http://msdn.microsoft.com/en-us/library/windows/desktop/bb787866(v=vs.85).aspx:
(4) Do not display a progress dialog box.
(8) Give the file being operated on a new name in a move, copy, or rename operation if a file with the target name already exists.
(16) Respond with "Yes to All" for any dialog box that is displayed.
(512) Do not confirm the creation of a new directory if the operation requires one to be created.
(1024) Do not display a user interface if an error occurs.
If this is running on Vista or Windows 7, popping up UI from a service isn't going to be seen by the end user as you suspected. See this paper on Session 0 Isolation. However, does the progress dialog require user input? If not, I wouldn't think that would cause the service to hang. I would look for an option to disable the progress display. If you can't find that, then try switching to another ZIP extractor. PSCX 1.2 comes with an Expand-Archive cmdlet. I'm sure there are also others available.
Looking at the documentation for PowerShell, it looks like the -NonInteractive option may help here