Creating Shortcuts on Redirected Read-Only Desktops

Recently, I had a customer request that their RDS servers have the desktop locked down. They didn’t want users to make any changes to the desktops. After some google searches, it was clear that most people redirected the desktop and then changed the user’s permissions to read only. This worked, but prevented us from using our standard practice of creating/refreshing shortcuts via GPO Preferences. Because the user had read only rights, the GPO couldn’t create the shortcuts. After some blood, sweat and tears, I developed a PowerShell script that would accomplish this task. To set it up, you have to populate the application information the same as you would the GPO, then tell the script what OU to look in for users (you could also set it to the domain root).

The script relies on Windows Scripting Host to create the shortcuts, so I created a function to do this. Its inputs are the shortcut target path, optional arguments, alternate icon path and AD Group Name if you have shortcuts that you want limited to specific users or for licensing purposes.

<#
TITLE: 		Create shortcuts on a roaming desktop based on AD membership
AUTHOR: 	Michael Kenning (https://powerscripter.wordpress.com)
VERSION: 	1.3 (release)
DATE:		2 AUG 2016
NOTE:		Change the variables to match your organization and the Application Definitions to match your apps. Also, add the Application variable to the $app Array!
#>

### VARIABLES ###
$userRoot = "\\SERVERFS1\Users$\"
$ou = "OU=Organization,DC=domain,DC=local"
$domainName = "domain"
$properties = "ProfilePath","HomeDrive","HomeDirectory","Enabled"
# Permission Levels: "R" = Read, "W" = Write, "M" = Modify, "RX" = Read and Execute, "F" = Full Control
$accessLevelModify = '(M,W,R,RX)'
$accessLevelRead = '(R,RX)'
$accessLevelFull = "F"
# Inheritance levels: (OI) - object inherit, (CI) - container inherit, (IO) - inherit only,(NP) - don’t propagate inherit
$inheritance = "(OI)(CI)"
$adminName = "BUILTIN\Administrators"
### END VARIABLES ###

### APPLICATION DEFINITIONS ###
$msWord = @{Name="Microsoft Word";Target="C:\Program Files (x86)\Microsoft Office\Office16\WINWORD.EXE";Arguments="";GroupName=""}
$msExcel = @{Name="Microsoft Excel";Target="C:\Program Files (x86)\Microsoft Office\Office16\EXCEL.EXE";Arguments="";GroupName=""}
$msPpnt = @{Name="Microsoft PowerPoint";Target="C:\Program Files (x86)\Microsoft Office\Office16\POWERPNT.EXE";Arguments="";GroupName=""}
$msOutlook = @{Name="Microsoft Outlook";Target="C:\Program Files (x86)\Microsoft Office\Office16\OUTLOOK.EXE";Arguments="";GroupName=""}
$msVisio = @{Name="Microsoft Visio";Target="C:\Program Files (x86)\Microsoft Office\Office16\VISIO.EXE";Arguments="";GroupName=""}
$msPub = @{Name="Microsoft Publisher";Target="C:\Program Files (x86)\Microsoft Office\Office16\MSPUB.EXE";Arguments="";GroupName=""}
$acrobatPro = @{Name="Adobe Acrobat Pro";Target="C:\Program Files (x86)\Adobe\Acrobat 2015\Acrobat\Acrobat.exe";Arguments="";GroupName="Adobe Acrobat Pro";WorkingDir="C:\Program Files (x86)\Adobe\Acrobat 2015\Acrobat\"}
$url1 = @{Name="URL Shortcut 1";Target="C:\Program Files (x86)\Internet Explorer\iexplore.exe";Arguments="https://website.com/sublevel/page.asp";GroupName="";IconPath="C:\icons\url1.ico"}

# -- Build the array of applications to create
$apps = $msWord,$msExcel,$msPpnt,$msOutlook,$msVisio,$msPub,$acrobatPro,$url1
### END APPLICATIONS DEFINITIONS ###

function Create-Shortcut {

	param (
        [Parameter(Mandatory=$true,Position=0)]
        [ValidateNotNullOrEmpty()]
        [String]
		$Path,
        [Parameter(Mandatory=$true,Position=1)]
        [ValidateNotNullOrEmpty()]
        [String]
        $Target,
        [Parameter(Mandatory=$false,Position=2)]
        [String]
        $IconPath,
        [Parameter(Mandatory=$false,Position=3)]
        [String]
        $Arguments,
        [Parameter(Mandatory=$false,Position=4)]
        [String]
        $WorkingDir
    )
     
	$WshShell = New-Object -comObject WScript.Shell
	$shortcut = $WshShell.CreateShortcut($path)
	$shortcut.TargetPath = $target
	$shortcut.Arguments = $arguments
	if ($iconPath -ne "") {
		$shortcut.IconLocation = $iconPath
	}
	$shortcut.WorkingDirectory = $workingDir
	$shortcut.Save()
}

# - Get a list of enabled users in the OU and sub-OUs specified above
$users = Get-ADUser -Filter * -SearchBase $ou -Properties $properties | where {$_.enabled -eq "True"}

# - Loop through each user and create the shortcuts
ForEach ($user in $users) {
	Write-Host "Working on user " $user.Name -ForegroundColor Green
	$userPath = $userRoot + $user.SamAccountName + "\Desktop"
	$userName = $domainName + "\" + $user.Name
	Write-Host $userName

	# - If the Desktop folder does not exists, create it and grant the correct permissions
	if (!(Test-Path $userPath)) {
		New-Item -Path $userPath -Type Directory
		# -- Reset Folder Permissions and Inheritance on the Home Folder
		$command1 = "ICACLS.exe " + "`"" + $userPath + "`" /RESET /T"
		$command2 = "ICACLS.exe " + "`"" + $userPath + "`" /inheritance:d /inheritance:r"
		# -- Grant permissions to the Administrator User/Group and the SYSTEM account
		$command3 = "ICACLS.exe " + "`"" + $userPath + "`" /GRANT:r " + "`"" + $adminName + "`":" + $inheritance + $accessLevelFull
		$command4 = "ICACLS.exe " + "`"" + $userPath + "`" /GRANT:r " + "`"" + "SYSTEM" + "`":" + $inheritance + $accessLevelFull
		# -- Grant permissions to the user
		$command5 = "ICACLS.exe " + "`"" + $userPath + "`" /GRANT:r " + "`"" + $userName + "`":" + $inheritance + $accessLevelRead
		
		cmd /c $command1
		cmd /c $command2
		cmd /c $command3
		cmd /c $command4
		cmd /c $command5
	}

	# -- Delete what's already in the Desktop (Optional)
	# Remove-Item $userPath\*.* -Confirm:$false
	
	# -- Loop through each app and create shortcuts
	ForEach ($app in $apps) {
		Write-Host "Working on app " $app.Name -Foregroundcolor Green
		# -- All Users get these shortcuts
		If ($app.GroupName -eq "") {
			$path = $userPath + "\" + $app.Name + ".lnk"
			Write-Host "Creating Shortcut for " $app.Name -Foregroundcolor Yellow
			Create-Shortcut -Path $path -Target $app.Target -IconPath $app.IconPath -Arguments $app.arguments -WorkingDir $app.workingDir
		}
		# -- AD Group Specific shortcuts
		If ($app.GroupName -ne "") {
			If ($app.GroupName -eq "Application1") {
			}
			Else {
				If ((Get-ADGroupMember -Identity $app.GroupName -Recursive | Select -ExpandProperty Name) -contains $user.Name) {
					Write-Host "Creating Shortcut for " $app.Name -Foregroundcolor Yellow
					$path = $userPath + "\" + $app.Name + ".lnk"
					Create-Shortcut -Path $path -Target $app.Target -IconPath $app.IconPath -Arguments $app.arguments -WorkingDir $app.workingDir
				}
			}
		}
		If ($app.GroupName -eq "Application 1") {
			If ((Get-ADGroupMember -Identity $app.GroupName -Recursive | Select -ExpandProperty Name) -contains $user.Name) {
				Write-Host "Creating Shortcut for " $app.Name -Foregroundcolor Yellow
				Copy-Item \\SERVERFS1\Shortcuts$\Application1.lnk $userPath
			}
		}
	}
}

Advertisements
Tagged with: , ,
Posted in Powershell

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: