There has been a few times where I have needed to enable Remote Desktop Protocal on Remote computers. So, I built out a simple but powerful tool to help me with just this. It uses the Invoke-Command command to enable the RDP. So, lets dig in.
The Script – Enable RDP on a Remote Computer
function Enable-SHDComputerRDP {
<#
.SYNOPSIS
Enables target computer's RDP
.DESCRIPTION
Enables taget Computer's RDP
.PARAMETER Computername
[String[]] - Target Computers you wish to enable RDP on.
.PARAMETER Credential
Optional credentials switch that allows you to use another credential.
.EXAMPLE
Enable-SHDComputerRDP -computername <computer1>,<computer2> -Credential (Get-credential)
Enables RDP on computer1 and on computer 2 using the supplied credentials.
.EXAMPLE
Enable-SHDComputerRDP -computername <computer1>,<computer2>
Enables RDP on computer1 and on computer 2 using the current credentials.
.OUTPUTS
[None]
.NOTES
Author: David Bolding
.LINK
https://therandomadmin.com
#>
[cmdletbinding()]
param (
[Parameter(
ValueFromPipeline = $True,
ValueFromPipelineByPropertyName = $True,
HelpMessage = "Provide the target hostname",
Mandatory = $true)][Alias('Hostname', 'cn')][String[]]$Computername,
[Parameter(HelpMessage = "Allows for custom Credential.")][System.Management.Automation.PSCredential]$Credential
)
$parameters = @{
ComputerName = $ComputerName
ScriptBlock = {
Enable-NetFirewallRule -DisplayGroup 'Remote Desktop'
Set-ItemProperty ‘HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\‘ -Name “fDenyTSConnections” -Value 0
Set-ItemProperty ‘HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\‘ -Name “UserAuthentication” -Value 1
}
}
if ($PSBoundParameters.ContainsKey('Credential')) { $parameters += @{Credential = $Credential } }
Invoke-Command @parameters
}
The breakdown
Comments/Documentation
The first part of this tool is the in-house Documentation. Here is where you can give an overview, description, parameters, examples, and more. Using the command Get-help will produce the needed information above. On a personal level, I like adding the type inside the parameters. I also like putting the author and date inside the Notes field.
Parameters
We are using two parameters. A computer name parameter and a credential parameter. The ComputerName parameter contains a few parameter flags. The first is the Value from Pipeline flags. This allows us to pipe data to the function. The next is the Value From Pipeline by Property name. This allows us to pass the “ComputerName” Value. Thus we can pull from an excel spreadsheet or a list of computer names. Next, we have the Help Message which is just like it sounds. It’s a small help message that can be useful to the end user. Finally, we have the Mandatory flag. As this command is dependent on that input, we need to make this mandatory. The next item in computername is the Alias. This allows us to use other names. In this example, we are using the hostname or the CN. This is just a little something that helps the end user. Finally, we have the type. This is a list of strings which means we can target more than one computer at a time.
The next parameter is the Credential Parameter. This one is unique. The only flag we have here is the Hel message. The type is a little different. The type is a System Management Automation PSCredential. And yes, it’s complex. A simple run down is, use Get-Credentials here. This function is designed to be automated with this feature. If you are using a domain admin account, you may not need to use this. However, if you are working on computers in a different domain, and don’t have rights, you can trigger this parameter.
param (
[Parameter(
ValueFromPipeline = $True,
ValueFromPipelineByPropertyName = $True,
HelpMessage = "Provide the target hostname",
Mandatory = $true)][Alias('Hostname', 'cn')][String[]]$Computername,
[Parameter(HelpMessage = "Allows for custom Credential.")][System.Management.Automation.PSCredential]$Credential
)
The Script Block
Now we need to create the script block that will be used inside the invoke-command. We are going to build out a splat. We build splats with @{}. The Information will be inside here. When we push a splat into a command we need to add each flag from that command that is required. Here we are going to be adding the computer name and script block. The computer name flag is a list of strings for our invoke-command. Thus, we can drop the Computername into the ComputerName. Yeah, that’s not confusing. The script block is where the action is.
$parameters = @{
ComputerName = $ComputerName
ScriptBlock = {
#Do something
}
}
Let’s open up some knowledge. The first thing we need to do is enable the remote desktop firewall rules. This will allow the remote desktop through the firewall.
Enable-NetFirewallRule -DisplayGroup 'Remote Desktop'
Next, we need to add the registry keys. The first key is to disable the deny TS connection keys. Next, we need to enable the User Authentication key.
Set-ItemProperty ‘HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\‘ -Name “fDenyTSConnections” -Value 0
Set-ItemProperty ‘HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\‘ -Name “UserAuthentication” -Value 1
Adding Credentials
Now we have created the Parameter, it’s time to add credentials when needed. We do this by asking if the parameter credentials was added. This is done through the PSBoundParameters variable. We search the Contains Key method and to see if Credential is set. If it is, Then we add the credentials.
if ($PSBoundParameters.ContainsKey('Credential')) { $parameters += @{Credential = $Credential } }
Finally, we invoke the command. We are using the splat which is the @parameters variable instead of the $parameter.
Invoke-Command @parameters
And that’s how you can quickly Enable RDP on a Remote Computer using PowerShell within your domain.