Enable RDP on a Remote Computer

Enable RDP on a Remote Computer

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.

Additional Reading

Run as an Administrator

Run as an Administrator

When building out scripts, we must consider different ways they will fail. One of the ways I have seen them fail is through the UAC of a computer. The script needs to be run by an administrator. The question is, How do you check if you are running as an Administrator? Here are the two ways I like doing this check.

The Comment Requires it

Powershell has a handy little feature called #Requires. The idea is simple, you place a #Requires at the top of your script. I suggest looking at the official documentation because there is a lot you can do. As of PowerShell 4, #Requires -RunAsAdministrator is a thing. Having this requirement at the start will tell the shell to fail out.

Powershell Checks

The next method is using PowerShell to check if the current shell is administrator through the security protocols of windows. This method only uses two lines of code to produce a true or false statement. Thus, it’s best to keep it inside a function for later use.

function Test-Administrator {  
    $user = [Security.Principal.WindowsIdentity]::GetCurrent();
    (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)  
}

The first part is grabbing the current user of the terminal. We store that information and then create a new object. We create a security principal windows Principal object. Here we can check what the user’s role was and if it was the built-in administrator role.

There we have it, how to test if a script is running as admin.

Taking it an additional step forward

Let’s take this script to the next level by adding a restart in admin mode. The following code can be used to restart any terminal session into admin mode. However, it breaks in vs code.

$CurrentProcess = [System.Diagnostics.Process]::GetCurrentProcess()
$CurrentProcessID = New-Object System.Diagnostics.ProcessStartInfo $CurrentProcess.Path
$CurrentProcessID.Arguments = '-file ' + $script:MyInvocation.MyCommand.Path
$CurrentProcessID.Verb = "runas"
[System.Diagnostics.Process]::Start($CurrentProcessID) | Out-Null
[Environment]::Exit(0)

The first part of this script catches the current process information. Then we pass that information into a new system diagnostic object to find the process start information. Next, we change the arguments to start a file and the current script’s name. We also set the verb to runas to trigger a run as administrator call. Then we start the process that we created and close to this current process. Afterward, the script will run as admin.

The Script – Run as an Administrator

function Test-Administrator {  
    $user = [Security.Principal.WindowsIdentity]::GetCurrent();
    (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)  
}

function Invoke-RunAsAdministrator {
    [cmdletbinding()]
    param (
        [parameter(Mandatory = $true)][boolean]$Admin
    )

    if (!$Admin) {
        $CurrentProcess = [System.Diagnostics.Process]::GetCurrentProcess()
        $CurrentProcessID = New-Object System.Diagnostics.ProcessStartInfo $CurrentProcess.Path
        $CurrentProcessID.Arguments = '-file ' + $script:MyInvocation.MyCommand.Path
        $CurrentProcessID.Verb = "runas"
        [System.Diagnostics.Process]::Start($CurrentProcessID) | Out-Null
        [Environment]::Exit(0)
    }
    else {
        Write-Verbose "Admin Rights Present"
    }
}

Invoke-RunAsAdministrator -Admin (Test-Administrator)
Read-Host "Press any key to continue"

Now to make this more practical. Add the above code to the Citrix Workspace Installer. Then wrap the script up into an EXE with the PS1toExe program. Finally, add the little script program to your toolbox for future use.

Image by MidJourney AI

Windows Updates With Powershell

Windows Updates With Powershell

At a previous company, we had to maintain windows updates without WSUS. This caused some unique complexities. Back then, all machines in question were Microsoft Surface Tablets. This means that driver updates were important. Thus, I created a one-liner to update windows. In today’s post, we will go over Windows Updates with PowerShell. Using PowerShell allows you to use tools like backstage or scripts to install updates on remote machines quickly. The first part of this post will be how to do it manually and then the final part is oneliners. PSWindowsupdate is the module we will be using.

Warnings

Today’s code has the ability to install all windows updates. This includes updates blocked by different software. Thus, reviewing the updates and being confident in what you are updating are essential to success.

The Manual Breakdown

Once you are connected to a machine that you want to do windows updates with PowerShell, start a PowerShell session. Each step from here own will help make a clear and clean method.

Execution Policy

Set-ExecutionPolicy - ExecutionPolicy Bypass

This command allows you to install modules and any other items in PowerShell. The PSWindowsUpdate will require the execution policy to be at least set to bypass. You can learn more about execution policies here. Note, you must be running PowerShell in an evaluated prompt for this code to work.

Nuget

Install-PackageProvider Nuget -Force

After setting the execution policy, we might need to update the package provider. Making a single-line script becomes a challenge because of this. With this knowledge, we want to force an installation of the newest package provider.

Install PSWindowsUpdate

Install-Module pswindowsupdate -force -confirm:$false

The next piece is to install the pswindowsupdate module. This module is the module that does our heavy lifting. Here is where we will need to use the force and confirm flags.

Import PSWindowsUpdate

Import-Module PSWindowsUpdate

Now we have the module. It is time to import the module. Importing a module does not need additional input.

Getting the Windows Update

Get-WindowsUpdate -MicrosoftUpdate

It’s time to get the updates.Here is where we grab the KB information. This is where Windows Updates with Powershell Happens. This is where you can find updates to research. It’s important to know what you are updating.

Windows Updates With PowerShell

Installing a KB

Get-WindowsUpdate -Install -KBArticleID "ID Number" -AcceptAll -IgnoreReboot

This command will install the KB that you wish without asking any questions. You will see a fancy update process bar during this time.

Windows Updates With PowerShell

One-Liner Commands to Install Windows Updates With PowerShell

The following are single-line commands. These commands will install all the updates according to their purpose. The following commands have the ability to break your system. One example of this is the BitLocker update that bricked machines recently. The following command will install all the KB updates.

KB Only

Set-ExecutionPolicy -ExecutionPolicy bypass; Install-PackageProvider Nuget -Force; Install-Module pswindowsupdate -force -confirm:$false; Import-Module pswindowsupdate; $Updates = Get-windowsupdate -MicrosoftUpdate; $Updates = $Updates | where-object {$_.KB -ne ""}; Get-WindowsUpdate -Install -KBArticleID $Updates.KB -IgnoreReboot -AcceptAll

All Updates

This command will install all updates on the machine. This includes the KB Microsoft and vendor updates. Please be aware of any dangerous updates that are in the wild. The following command will install those as well.

Set-ExecutionPolicy -ExecutionPolicy bypass; Install-PackageProvider Nuget -Force; Install-Module pswindowsupdate -force -confirm:$false; Import-Module pswindowsupdate; Get-windowsupdate -AcceptAll -MicrosoftUpdate -Install -IgnoreReboot

Troubleshooting

Here is a list of common problems that I have come across with this code:

  • Set-ExecutionPolicy an error when the policy is set to unrestricted.
  • Set-ExecutionPolicy can request additional prompting
  • PSWindowsUpdate module can be blocked.

Conclusion

Firstly, always do your research. Once you know what you are working with, pull the trigger. Let the script run and enjoy your tea.

Seriously though, always research. Always, research. In case you break something, look at this blog post to help fix some things.

Additional Resources:

Microsoft Safety Scanner Powershell One Liner

Microsoft Safety Scanner Powershell One Liner

A client called in and told me a line of information that made me concerned about security. I ran a webroot scan and wanted to give another level of the scan. I am partial to the Microsoft Safety Scanner. It runs well connectwise backstage. You can read more about the safety scanner here. So, lets look at this oneliner.

if (!(Test-Path "c:\Temp")) { New-Item -Path "c:\" -Name Temp -ItemType Directory }; invoke-webrequest -Uri https://go.microsoft.com/fwlink/?LinkId=212732 -OutFile c:\temp\mss.exe -UseBasicParsing; c:\temp\mss.exe /Q /F:Y

The first part of this little script is to test and create the folder that will hold our file. We are doing this by using test-path. Then if the file doesn’t exist, aka !. Then we create it with the new-item.

if (!(Test-Path "c:\Temp")) { New-Item -Path "c:\" -Name Temp -ItemType Directory }

The next part is we are going to download the Microsoft security scanner from Microsoft directly. The link is the direct download. We use invoke-webrequest to download the file. The -outfile flag is where we will download the file at and its name. In this case, we are going to name it something simple. Mss.exe inside our temp folder. We use the -usebasicparsing because most machines only have PowerShell 5.

invoke-webrequest -Uri https://go.microsoft.com/fwlink/?LinkId=212732 -OutFile c:\temp\mss.exe -UseBasicParsing

Then we run the command needed. We start the command with the path. C:\temp\mss.exe. We want it to be quiet and we want to force it. So we use the /Q to quiet, and /F:Y to force.

c:\temp\mss.exe /Q /F:Y

The system will not prompt for any kind of approval. It will run and delete what it needs to delete. This is a simple, deploy and walk away one-liner. So, add it to your deployment scripts and enjoy scanning with a Microsoft safety scanner.

Install Sentinel One with Intune

Install Sentinel One with Intune

It’s time to Install Sentinel One. In this blog, we are going to go through the process of installing Sentinel One through Intune. We are going to be using the IntuneWinAppUtil program, and the MSI download of Sentinel one that you can obtain from your Sentinel one login portal. I will not go over how to download the msi installer.

File/Folder Structure

The next item you will need is the Microsoft Win32 Content Prep Tool [Link]. Once you have downloaded this file, I suggest creating a file structure as follows

  • Intune
    • Files
    • IntuneWin

After that, Extract the intunewinapputil.exe file to the top level of your file structure, intune. Place the MSI inside the Files location. Then we should be ready to run intunewinapputil.exe. Before you do, I always suggest reading the help by using the /? command line prompt. Here is the command we are going to use to convert our file.

Intune Win App Util

.\IntuneWinAppUtil.exe -c c:\Intune\Files -s SentinelOneInstaller.msi - o c:\Intune\IntuneWin

Afterward, we use the command above to convert our file into a intune installer file. This will give us a large amount of control. Things like detection rules, custom msi inputs and more. Which we will be using.

Intune – Setting up the installer

Next, It’s time to crack open the intune process. Log in to https://endpoint.microsoft.com/ with an account with intune rights.

Once you have logged into the endpoint management system. Click the Apps on the left-hand side of the screen.

Since we are deploying sentinel one to windows machines, under by platform, click the windows icon.

Uploading the Installer

Now we are going to click the add button on the right-hand side of the screen. This will bring up the add dialog box. We are deploying out the final option. Click the Windows App (Win32) option.

You will be brought to an upload page. Here you select the app package file and click the blue button on the right-hand side of the screen. This is where we go to the file we created in the previous steps. We upload the file here. Once it uploads it will populate the information like name and other items. Click ok to move to the app information page.

Setting the rules

Here we can change the name. Add a unique, html, description. Update the publisher, the application version and more. The category we are going to select is computer management. They show this as a featured app in the company portal. You want to check that one. This allows people to download this version of perch. If you want to feel in any of the other information you are welcome to. Once you have the required information, click next to go to the Program page. Where we determine how to install this application.

Adding the Key

On this page, we want to show the install and uninstall commands. This is where research comes into play. If you don’t know the silent install command of your program then that’s a problem. If you don’t know how your program responds to installs and the error codes or success codes it produces. that’s also a problem. You will need to know these things for other applications. Sentinel One is unique as it’s commands is a little different. Here is the install command:

msiexec /i "SentinelInstalle.msi" /q SITE_TOKEN="YourSiteToken"

Keep the uninstall command the same. As the MSI installer of Sentinel One is the app code. The biggest problem with the uninstall command with S1 is that it doesn’t work without prior approval. You have to log into the S1 Portal and approve its uninstall. Keep the default and continue.

Another thing to point out, this kicked my tail, the SITE_TOKEN does not have a /, I repeat NO /.

On this page, we can scan the system to make sure we meet the requirements. So if you know this is a heavy application, you can say to have at least 8GB of ram. You can even have PowerShell scripts that can trigger. A good example would be a user. If user Bob is on this PC don’t install it. The required items are the OS Arch and the minimum os. Which is going to be windows 10 1607 as that is intune’s min. Don’t get this confused with the next item. These are the requirements. Not meeting the requirements will prevent the app from installing. Once you have added what you want, click next.

On this page, we are going to select any dependencies that the application may need. Something unique about Sentinel One is, it will capture all of your custom PowerShell deployments. It’s best to set those as dependencies on this installer. This way they will deploy before S1 does. S1, doesn’t need any additional dependencies from my current knowledge and testing.

Detection Rules

We are going to use a Powershell Script to validate the install. Click on the Rule Format and select Use Custom Detection script. Upload your script file using the blue folder icon.

$A = 0
do {
    try {
        $Services = Get-Service -name SentinelAgent
    }
    catch {
        $Services = $null
    }
    start-sleep -Seconds 30
    $A = $A + 30
} until (($null -ne $Services) -or ($A -ge 300))
if ($null -ne $Services) { Write-Host "Installed" } else { exit }

This script checks for the Sentinel Agent every 30 seconds after installation. Then it increases my timer, by 30. It finally stops at 300 seconds. If services are null, it just exits, and thus a failure is seen in intune. If it is installed, it exits with a string. This tells the system that the installation was successful. What I like about this part is, that if the edit needs to be done, it can be done at this point using PowerShell.

The next screen supersedence is where you can choose what will replace the application. This is a preview feature at the moment and the idea is for upgrades. The final section is the Assignment, this is where you will select a group of devices for S1 to deploy out to.

I hope this is helpful for everyone viewing this page.

Perch Log Shipper with Intune

Perch Log Shipper with Intune

Recently I covered how to install perch using PowerShell. Today we are going to Install Perch Log Shipper with Intune. This is very useful for tools like continuum where there is very few software deployment tools built-in. Intune is a powerful tool that you can use to deploy software for a client. Today we are going to be looking at how to deploy Perch through intune.

The first thing we need is a fresh perch installer. You can acquire one here. [link]. Once you have the installer, you will need to download the Microsoft Win32 Content Prep Tool [Link]. Let’s setup our directory like so. Top Folder = Intune. Two subfolders, one called Files and the other called intunewin. Extract the exe from the Microsoft win32 content prep tool to the intune folder. Copy the perch installer to the files folder. Now we have a setup that is easy to remember.

By default, you can not deploy EXE programs via intune. You must convert them to the win32 application or a .intunewin file. The tool you just downloaded can do just that. The Tools name is IntuneWinAppUtil.exe.

IntuneWinAppUtil.exe

Start a command prompt and navigate to your intune folder using the CD command. Run the intunewinapputil.exe /? command to view the help selection. Notice we are going to be using the -c -s and -o commands. Here is the following command you will use to convert the perch installer into a intunewin application.

IntuneWinAppUtil.exe -c c:\Intune\Files -s perch-log-shipper-latest.exe -o c:\Intune\intunewin

Now we have a perch installer for Intune. Lets move to intune and take a look.

Intune Apps

It’s time to crack open the Intune process. Log in to https://endpoint.microsoft.com/ with an account with intune rights.

Once you have logged into the endpoint management system. Click the Apps on the left-hand side of the screen.

Since we are deploying perch to windows machines, under by platform, click the windows icon.

Now we are going to click the add button on the right-hand side of the screen. This will bring up the add dialog box. We are deploying out the final option. Click the Windows App (Win32) option.

Upload the Package

Afterward, we are brought to the app page. Here you select the app package file and click the blue button on the right-hand side of the screen. This is where we go to the file we created in the previous steps. We upload the file here. Once it uploads it will populate the information like name and other items. Click ok to move to the app information page.

App Information

Here we can change the name. Add a unique, html, description. Update the publisher, the application version and more. The category we are going to select is computer management. The show this as a featured app in the company portal. You want to check that one. This allows people to download this version of perch. If you want to feel in any of the other information you are welcome to. Once you have the required information, click next to go to the Program page. Where we determine how to install this application.

Program Information

On this page we want to show the install and uninstall command. This is where research comes into play. If you don’t know the silent install command of your program then that’s a problem. If you don’t know how your program responds to installs and the error codes or success codes it produces. that’s also a problem. You will need to know these things for other applications. Thankfully perch follows the basic ones. Here is the installer command:

 perch-log-shipper-latest.exe /q OUTPUT="TOKEN" Value="YourSiteToken"

The uninstall command is as follows:

 perch-log-shipper-latest.exe /uninstall

Once you have the installer and uninstaller in place, click the next button to go to the requirement page.

Requirements

On this page, we can scan the system to make sure we meet the requirements. So if you know this is a heavy application, you can say to have at least 8GB of ram. You can even have PowerShell scripts that can trigger. A good example would be a user. If user Bob is on this PC don’t install. The required items are the OS Arch and the minimum os. Which is going to be windows 10 1607 as that is intunes min. Don’t get this confused with the next item. These are the requirements. Once you have added what you want, click next.

Dependencies

On this page, we are going to select any dependencies that the application may need. For example, let’s say your application needs 7-zip. Set up an install for 7 zip and make it a dependency and have it install the dependency. One hack I found is if you know the app is going to break other apps while installing as the ITS Platform does, then you can set the other applications as dependants and install them. Thankfully perch does not have any additional dependants. So, when it does it’s taxes, life is easier. (American joke).

Detection Rules

Detection is very important. if the rule doesn’t exist, then intune has no idea if it was installed. If the detection policy is incorrect, the same issue. It’s very wise to know what you are looking for. In this case perch always installs on c:\program files\perch. So we will select the manual to configure detection rule. Then select add. We will select a file from the drop-down list and enter the folder path of c:\program files and the folder name perch. Then click folder or existing file. That’s your detection policy.

Group Assignments

In like fashion, The next window of importance is the Assign. If you want the app to deploy with autopilot, you must select the app as required, or be tied into another application install dependency. Here we are adding a group of computers. This is very common. The other options are available for enrolled devices. If the computer has the company portal, they can download it without needing admin rights. The final option is to uninstall which would uninstall from the select computers.

Finally, the last page is to review all the settings. Once you click save the file will upload and it might take some time. The bigger the file the longer it will take. This is how you Install Perch Log Shipper with Intune.

Conclusion

Hopefully this guide helped you through the process of setting up an Install Perch Log Shipper with Intune