5 ways to manage computers securely and remotely using PowerShell

Being able to secure communications between remote resources is just as important as being able to access the device. Using PowerShell, IT can do both when accessing off-site devices cross-platform.

connected laptop

Image: iStock/metamorworks

The ability to access systems remotely has never been more important than it is today. For a variety of reasons—a global pandemic preventing many workers from physically accessing services, the growing number of users opting to go remote, or the growth of the threat landscape as the borders of the organization's network are expanded to allow for increased accessibility and availability.

SEE: TechRepublic Premium editorial calendar: IT policies, checklists, toolkits, and research for download  (TechRepublic Premium)

It's no secret that malicious actors are out there and actively seeking out new targets. Furthermore, the current state of the global Internet means that access is available to millions of users—which represents a never-ending list of targets to compromise and exploit. Like a perfect storm that places the burden of protecting data squarely on everyday users and the respective IT pros tasked with ensuring that data remains safe.

One of those tools that have come into the mainstream in recent years to facilitate remote access and management of systems is Microsoft's PowerShell (PS). Initially offered as a Windows-only application, PS was officially made open-source several versions back and offers support for the most popular operating systems, including various Linux distributions and macOS, alongside Windows to securely perform its tasks. And the methods below will illustrate various ways to do so without compromising system confidentiality or integrity.

Cmdlets using the -ComputerName argument

In general, PS cmdlets have additional arguments that are part of the syntax that allows for the additional specification of devices, variables, or additional parameters. Some are common to most cmdlets, others are unique to a specific cmdlet or branch of cmdlets.

The -ComputerName argument is available to many cmdlets and can be used to target a specific device when managing processes remotely. The parameter may also be paired with a file list, such as a CSV file with a list of computer hostnames so as to process cmdlets against the list of hostnames exclusively and recursively.

Get-Service -Name *SSH -ComputerName SAMPLE-PC01 | Start-Service
Input-CSV -Path \\server\share\computerlist.csv | Add-ADComputer -ComputerName {for each. $_.Computers }

Starting interactive session using Enter-PSSession

Beginning a PowerShell session with a device allows for a direct, secure connection to be established between your local PS console and a remote device. Similar to running cmdlets above, the PS session takes it one step forward and allows for binding that device directly to the console, so cmdlets executed in-session occur on the remote device only—until you exit the session. 

SEE: Identity theft protection policy (TechRepublic Premium)

For those familiar with SSH, a PS session works much like SSH, except it uses the PowerShell programming language as the encryption and communication protocols to remotely manage a device securely. Multiple sessions may be created at once, but that would require multiple instances of PS open. Like SSH mentioned before it may work better in one-to-one cases or scripted out to ensure each connection is created one at a time to process cmdlets, then terminated before moving on to the next connection. And just like SSH, PSRemoting—the service that allows PS sessions—is disabled by default and must be enabled prior to establishing a remote connection.

Enter-PSSession -Name PC02.local -Credential LOCAL\USER

Securing user accounts/passwords with Get-Credential

Another method that can be used to securely enter credentials is to utilize the Get-Credential cmdlet. By leveraging this, the command will prompt the user to interactively enter their credentials to provide the security context in which to execute the cmdlet. Often this is included as either a variable or piped directly to another cmdlet to ensure the credentials can be reused as necessary without requiring multiple prompts or worse still—displaying usernames or passwords in plaintext.

Get-Credential -Credential LOCAL\USER
$cred = Get-CredentialNew-ADComputer -Name "PC03" -SamAccountName "PC03" -Path "OU=Computers,DC=Local" -Credential $cred

Running any command remotely with Invoke-Command

As with many processes in Windows, there are often several ways to perform similar tasks. Executing commands remotely is one of those items with multiple methods to perform the same task. Using the Invoke-Command cmdlet, users are able to do just as in a dedicated PS session, without having to worry about enabling the service beforehand. In fact, the only requirement is that the user has permission to execute commands on the remote system for them to work.

The syntax on the Invoke-Command cmdlet adds a little complexity compared with the standard PS syntax, but once you get the hang of it, you'll find that this method allows for executing PowerShell and non-PowerShell commands with ease.

Invoke-Command -Filepath "\\server\share\script1.bat" -ComputerName "PC03.local" -Credential $cred 
Invoke-Command -ComputerName "PC03.local" -ScriptBlock { Test-ComputerSeureChannel -Repair }

Encrypting string values with ConvertTo-SecureString

Lastly, another contender for securing credentials—or any other piece of private data—is the ConvertTo-SecureString cmdlet, which serves to store private data temporarily on the computer as an encrypted file during the session or until deleted. By securing values in this manner, the user ensures that the value is both accessible throughout the session (such as when executing multiple commands that require the -Credential parameter), and keeps the values confidential so as to not be readable in plaintext.

SEE: Social engineering: A cheat sheet for business professionals (free PDF) (TechRepublic)

Often, this method lends itself perfectly to scripted or automated processes that are set to run on a schedule or if requiring that data be stored as a secure string value so that unauthorized parties cannot view the contents of a script to extract anything that you wouldn't want to fall into their hands, such as credentials, hostnames, IP addresses, and such.

$svrip = ConvertTo-SecureString "192.168.1.1" -AsPlainText -Force
(Get-Credential).Password | ConvertFrom-SecureString | Out-File "\\server\share\encryptcreds.txt"

Also see