Adding Remote App File associations via PowerShell

We have a lot of RemoteApp and RDS deployments out in the field. Sometimes users want to use the RemoteApp to directly open the correctly associated applications, like .docx for Word files. When using Windows 8 or Windows 10 this can be done automatically by entering the RemoteApp Connection Default URL via the group policy found at the following location:

User Configuration -> Policies -> Administrative Templates ->Windows Components->Remote Desktop Services->RemoteApp and Desktop Connections->Specify default connection URL

This works great if all the clients are in the same domain as the RDS farm or if you are not running RemoteApps from within RDS. When running in a different domain the default File Associations are not applied because the user credentials do not match the credentials on the server-side, also Microsoft does not support deploying the default RemoteApp connections within a RDS Farm. The event log will show you the error:

The installation of the default connection has been cancelled. A default connection cannot be used on a system that is part of a Remote Desktop Services deployment.

This does mean you can add the Default Connection via a logon script or by manually configuring the URL in the Control panel. The downside of this is that the File Associations are not added to the users register. To resolve this I’ve created a function that creates reg keys for each user to correct this. The usage of the function is pretty straight forward; all you have to do is place the .RDP file and the .ICO file on a public location(e.g. C:\Users\Public\ or a file share) and run the following command:

Add-RemoteAppDefaultProgram -RemoteAppName "Winword Remote App" -Extension ".txt" -RDPFile "C:\Users\Public\Winword Remote App.rdp" -IconFile "C:\Users\Public\Winword Remote App.ico"

The script takes an array as the Extention value, so you can add multiple extentions as such;

Add-RemoteAppDefaultProgram -RemoteAppName "Winword Remote App" -Extension ".txt",".doc",".log" -RDPFile "C:\Users\Public\Winword Remote App.rdp" -IconFile "C:\Users\Public\Winword Remote App.ico"

The script is included below, a slight warning: the script overwrites the current file association for the extention. as always, be careful, and happy powershelling!

<code>&lt;#
.SYNOPSIS

Adds a remote app to the "OpenWith" file assosciations options in Windows 8/10, useful for when using RemoteApps within RDS collections, or when RemoteApp is not fully supported.

.DESCRIPTION

Adds a remote app to the "OpenWith" file assosciations options in Windows 8/10, useful for when using RemoteApps within RDS collections, or when RemoteApp is not fully supported.

Warning: Overwrites current File Assoc settings.

.PARAMETER RemoteAppName
Specifies the RemoteApp name. Strongly advised to keep this the same as the RDCollection name (e.g. "Winword Remote App")

.PARAMETER Extension
Specifies the extension you want to make default. Allowed to specify multiple extentions. ".txt",".log"

.PARAMETER RDPFile
Specifies the .RDP file to use.

.PARAMETER IconFile
Specifies the .ICO file to use.

.INPUTS

None. Does not accept pipeline input.

.OUTPUTS
lists created registry keys with verbose output.

.EXAMPLE

PS> Add-RemoteAppDefaultProgram -RemoteAppName "Winword Remote App" -Extension ".txt" -RDPFile "C:\Users\Public\Winword Remote App.rdp" -IconFile "C:\Users\Public\Winword Remote App.ico"


.EXAMPLE

PS> Add-RemoteAppDefaultProgram -RemoteAppName "Winword Remote App" -Extension ".txt",".doc",".log" -RDPFile "C:\Users\Public\Winword Remote App.rdp" -IconFile "C:\Users\Public\Winword Remote App.ico"


.LINK

<blockquote class="wp-embedded-content" data-secret="VvGHwF80ps"><a href="https://www.cyberdrain.com/">Home</a></blockquote><iframe class="wp-embedded-content" data-secret="VvGHwF80ps" frameborder="0" height="282" marginheight="0" marginwidth="0" sandbox="allow-scripts" scrolling="no" security="restricted" src="https://www.cyberdrain.com/embed/#?secret=5SRuslFkKV#?secret=VvGHwF80ps" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);" title="“Home” — CyberDrain" width="500"></iframe>

#>

function Add-RemoteAppDefaultProgram{
 Param(
   [Parameter(Mandatory=$true)]
   [string]$RemoteAppName,
   [Array]$Extension,
   [string]$RDPFile,
   [string]$IconFile

) #end param
$username = $Env:Username
$AppName = $RemoteAppName

foreach($ext in $Extension){
New-Item "HKCU:\Software\Classes\$($Ext)" -force -ea SilentlyContinue
New-Item "HKCU:\Software\Classes\$($Ext)\OpenWithProgIds" -force -ea SilentlyContinue
New-ItemProperty -LiteralPath "HKCU:\Software\Classes\$($Ext)\OpenWithProgIds" -Name "TSWorkspace.$($AppName)" -Value "" -PropertyType String -Force -ea SilentlyContinue;
}

#Adding Workspace to "OpenWith" registry.
New-Item "HKCU:\Software\Classes\TSWorkspace.$($AppName)" -force -ea SilentlyContinue
New-Item "HKCU:\Software\Classes\TSWorkspace.$($AppName)\Application" -force -ea SilentlyContinue
New-Item "HKCU:\Software\Classes\TSWorkspace.$($AppName)\CurVer" -force -ea SilentlyContinue
New-Item "HKCU:\Software\Classes\TSWorkspace.$($AppName)\DefaultIcon" -force -ea SilentlyContinue
new-Item "HKCU:\Software\Classes\TSWorkspace.$($AppName)\shell" -force -ea SilentlyContinue
New-Item "HKCU:\Software\Classes\TSWorkspace.$($AppName)\shell\open" -force -ea SilentlyContinue
New-Item "HKCU:\Software\Classes\TSWorkspace.$($AppName)\shell\open\command" -force -ea SilentlyContinue
New-ItemProperty -LiteralPath "HKCU:\Software\Classes\TSWorkspace.$($AppName)" -Name "(default)" -Value "$($AppName) $($Ext)" -PropertyType String -Force -ea SilentlyContinue;
New-ItemProperty -LiteralPath "HKCU:\Software\Classes\TSWorkspace.$($AppName)" -Name "RemoteApp" -Value 1 -PropertyType DWord -Force -ea SilentlyContinue;
New-ItemProperty -LiteralPath "HKCU:\Software\Classes\TSWorkspace.$($AppName)\Application" -Name "ApplicationName" -Value "$($AppName)" -PropertyType String -Force -ea SilentlyContinue;
New-ItemProperty -LiteralPath "HKCU:\Software\Classes\TSWorkspace.$($AppName)\Application" -Name "ApplicationDescription" -Value "$($AppName)" -PropertyType String -Force -ea SilentlyContinue;
New-ItemProperty -LiteralPath "HKCU:\Software\Classes\TSWorkspace.$($AppName)\Application" -Name "ApplicationIcon" -Value "`"$($IconFile)`",0" -PropertyType String -Force -ea SilentlyContinue;
New-ItemProperty -LiteralPath "HKCU:\Software\Classes\TSWorkspace.$($AppName)\Application" -Name "ApplicationCompany" -Value "Applicaties" -PropertyType String -Force -ea SilentlyContinue;
New-ItemProperty -LiteralPath "HKCU:\Software\Classes\TSWorkspace.$($AppName)\CurVer" -Name "(default)" -Value "TSWorkspace.$($AppName)" -PropertyType String -Force -ea SilentlyContinue;
New-ItemProperty -LiteralPath "HKCU:\Software\Classes\TSWorkspace.$($AppName)\DefaultIcon" -Name "(default)" -Value "`"$($IconFile)`",0" -PropertyType String -Force -ea SilentlyContinue;
New-ItemProperty -LiteralPath "HKCU:\Software\Classes\TSWorkspace.$($AppName)\shell\open\command" -Name "(default)" -Value "`"%systemroot%\system32\mstsc.exe`" /REMOTEFILE:`"%1`" `"$($RDPFile)`"" -PropertyType ExpandString -Force -ea SilentlyContinue;

}</code>

Recent Articles

The return of CyberDrain CTF

CyberDrain CTF returns! (and so do I!)

It’s been since september that I actually picked up a digital pen equivalent and wrote anything down. This was due to me being busy with life but also my side projects like CIPP. I’m trying to get back into the game of scripting and blogging about these scripts. There’s still so much to automate and so little time, right? ;)

Monitoring with PowerShell: Monitoring Acronis Backups

Intro

This is a monitoring script requested via Reddit, One of the reddit r/msp users wondered how they can monitor Acronis a little bit easier. I jumped on this because it happened pretty much at the same time that I was asked to speak at the Acronis CyberSummit so it kinda made sense to script this so I have something to demonstrate at my session there.

Monitoring with PowerShell: Monitoring VSS Snapshots

Intro

Wow! It’s been a while since I’ve blogged. I’ve just been so swamped with CIPP that I’ve just let the blogging go entirely. It’s a shame because I think out of all my hobbies it’s one I enjoy the most. It’s always nice helping others achieve their scripting target. I even got a couple of LinkedIn questions asking if I was done with blogging but I’m not. Writing always gives me some more piece of mind so I’ll try to catch up again. I know I’ve said that before but this time I’ll follow through. I’m sitting down right now and scheduling the release of 5 blogs in one go. No more whining and no more waiting.