My batch file code requires to run some shell commands on multiple servers using SSH. For that I'm using Plink from a for
loop.
I do not want to enter the password in plain text to the Plink command line using -pw
. Instead, due to security concerns, I want to use a password encryption for my password and store the password into a separate text file.
I tried using sshpass
, but that is not supported in batch. As request to run the code will be on multiple servers, so I don't want to generate SSH key pair for each server as it will not be possible for hundreds of servers in the environment.
@echo off
for /f "delims=" %%a in (path\to\servers.txt) DO (
plink -v -ssh user@%%a -pw MY_PASSWORD echo %%a ; cat /path/to/config_file
)
pause
I expect the batch script to run on all servers using encrypted password. But with current code, the output is displayed using plain password.
It's difficult to achieve this with a plain batch file.
But you can use PowerShell instead with its ConvertTo-SecureString
and ConvertFrom-SecureString
cmdlets.
To encrypt a password use:
Read-Host -AsSecureString | ConvertFrom-SecureString
Type the password and save the output to a file (encryptedpassword.txt
).
To use the encrypted password, use:
$encrypted = ConvertTo-SecureString(Get-Content ".\encryptedpassword.txt")
$bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($encrypted)
$password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
foreach ($hostname in (Get-Content ".\servers.txt"))
{
.\plink user@$hostname -pw "$password"
}
In PowerShell 7, you can simplify the code to:
$encrypted = ConvertTo-SecureString(Get-Content ".\encryptedpassword.txt")
$password = ConvertFrom-SecureString -SecureString $encrypted -AsPlainText
# ...
Based on:
Though I have to repeat that using a public key authentication would be a way better solution.