puTTY CLI - Copying a file from multiple servers to one location

This was an interesting one, the goal here was to, using puTTY copy some files from the remote location to the local destination using the putty command line interface, sounds pretty simple but we have some issues with this as we do not want to be storing the username and password in plain text in a script - that is a bad idea.

Generate Credentials File

This is very simple and only requires two lines of code, this will prompt you for your username and password and then store those encrypted in a xml files:

$Credential = Get-Credential
$Credential | Export-Clixml -Path "credentials.xml"

When you run this command you will be asked for those credentials:


That will then be saved to a file called credentials.xml as below:


Files to Transfer

We now need to know the files to move in the format of remote path and local path, the remote path is the location on the remote servers and the local path is the location on the server where this command is being executed from, in this example I am using my profile path on the remote server:

Remote Path : /Users/$Username/
Local Path : C:\MacReports

We then need the file(s) we wish to transfer with this variable:

$Files = @("cache_health_report.html")

Then finally we then need a variable to cycle though all the servers as below of which we have two:

$Servers = @{
    "12.10.55.1" = "hq_"
    "12.10.56.1" = "_newyork"
}

Script : PuttyTransfer.ps1

$PuttyPath = "C:\Program Files\PuTTY\pscp.exe"
$CredentialFile = "credentials.xml"

Remove-Item -Path "C:\MacReports\*" -Force -ErrorAction SilentlyContinue

# Import credentials from XML
$Credential = Import-Clixml -Path $CredentialFile
$Username = $Credential.UserName
$Password = $Credential.GetNetworkCredential().Password

# Define list of remote hosts and their corresponding filename prefixes
$Servers = @{
    "12.10.55.1" = "hq_"
    "12.10.56.1" = "_newyork"
}

# List of files to copy
$Files = @("cache_health_report.html")
$LocalPath = "C:\MacReports\"

# Step 1: Delete existing local copies before downloading
foreach ($File in $Files) {
    $LocalFile = "$LocalPath$File"
    if (Test-Path $LocalFile) {
        Write-Host "Deleting old local file: $LocalFile"
        Remove-Item -Path $LocalFile -Force
    }
}

# Step 2: Loop through each server and download files
foreach ($RemoteHost in $Servers.Keys) {
    $Prefix = $Servers[$RemoteHost]
    $RemotePath = "/Users/$Username/"
    foreach ($File in $Files) {
        $LocalFile = "$LocalPath$File"
        $RenamedFile = "$LocalPath$Prefix$File"
        Write-Host "Transferring $File from $RemoteHost to $LocalFile..."
        & $PuttyPath -q -scp -l $Username -pw $Password $RemoteHost`:$RemotePath$File $LocalFile

        # Ensure the transfer was successful before renaming
        if (Test-Path $LocalFile) {
            Write-Host "Renaming $LocalFile to $RenamedFile"
            Rename-Item -Path $LocalFile -NewName $RenamedFile -Force
        } else {
            Write-Host "ERROR: Transfer failed for $File from $RemoteHost"
        }
    }

}
Write-Host "All transfers completed successfully."

Previous Post Next Post

نموذج الاتصال