Using plink to modify ESXi host configuration files via SSH from a PowerCLI script

I am a big advocate of automation and saving time with a good script. Whenever I can find a task that is fairly lengthy, and is likely to be repeated in future, I always consider scripting it. There are many way to configure an ESXi host when it comes to writing build or automation scripts. In fact, I often feel we are quite spoilt for choice. Here are just some of the tools we have available to use:

  • PowerCLI
  • esxcli
  • vMA
  • vCLI

I was working on a build configuration script the other day using PowerCLI and found the need to edit some configuration files on the hosts. I wanted to edit the configuration file /etc/vmware/config during the execution of a single PowerCLI script without needing to stop the script or have an additional step to do myself. The following is what I came up with to achieve this:

  • Configure host as normal using PowerCLI
  • Use PowerCLI to start SSH service on host
  • execute plink script to connect to host, run command via SSH, then disconnect
  • Use PowerCLI to stop SSH service on host
  • Continue with rest of PowerCLI script

 

Plink is a command line connection tool – essentially a command line version of PuTTy. You can call it from dos prompt and issue it with a single, (or list) of commands to run once connected to a specified host. You can download Plink over here.

 

So without further ado, let’s take a look at the script as I described above.

# At start of our script we ask for the host's IP or name (this could be automated if you like)
$hostIP = Read-Host "Enter ESX host IP/dns name: "
$vmhost = Get-VMHost $hostIP

# Start the SSH service
$sshService = Get-VmHostService -VMHost $vmhost | Where { $_.Key -eq “TSM-SSH”}
Start-VMHostService -HostService $sshService -Confirm:$false

# Use SSH / plink to configure host with some additional script
cmd /c "plink.exe -ssh -pw HOSTROOTPASSWORD -noagent -m commands.txt root@$hostIP"

# Stop SSH service
Stop-VMHostService -HostService $sshService -Confirm:$false

 

As you can see, we start off by asking for the host IP or name, this is the only bit of manual input, but even this could be automated. The script then finds the SSH service on the host, and starts it. After this, the script calls the plink.exe file via cmd /c and connects using the root user@ the host’s IP as we entered at the beginning of the script over SSH. Plink is pointed to a commands.txt file (previously placed in the script execution folder), which contains the actual lines of bash script to be executed on the ESXi host via SSH.

Here is the content of the commands.txt file that I refer plink.exe to use (as an example, this bit of script enables copy/paste operations on all VMs running on this host in the guest OS’ console, as per VMware KB 1026437), but could contain any other commands you wish to execute on the ESXi host over SSH.

echo 'isolation.tools.copy.disable="FALSE"' >> /etc/vmware/config
echo 'isolation.tools.paste.disable="FALSE"' >> /etc/vmware/config

 

* Note two very useful techniques show by Alan in the comments section below, showing how to automatically download plink.exe if it is not available when the script is run, and also how to accept the SSH fingerprint key request by piping Y to plink.exe via the script – check out Alan’s blog post here for more detail.

10 thoughts on “Using plink to modify ESXi host configuration files via SSH from a PowerCLI script”

  1. @Alan Renouf
    i got it working with a file that contains multiple esxi servers but

    How do you use the “echo y |” function:

    echo y | cmd /c “plink.exe -ssh -pw HOSTROOTPASSWORD -noagent -m commands.txt root@$hostIP”

    bcos i get a powercli error telling me root@$hostIP can’t be resolved bcos you cant use a variable when you echo Y | to a command… ?

  2. @Kelly

    Hi Kelly, would the user you are logging in as have SSH access? Once connected over SSH, you could perhaps sudo in the commands.txt file that the script references? i.e. just before the two echo commands. You will of course need to be a user that does have SSH access.

    The line would then be something like:

    cmd /c “plink.exe -ssh -pw THEPASSWORD -noagent -m commands.txt normaluser@$hostIP”

  3. Oh and if you want to truely automate this from end to end and havent made a connection to the host before with plink you can get it to send a Y to plink.exe basically telling it to add the authentication key using the following:

    echo y | plink.exe………

  4. Nice, you could also get it to download plink.exe automagically for you like this….

    $myDir = Split-Path -Parent $MyInvocation.MyCommand.Path
    $PlinkLocation = $myDir + “\Plink.exe”
    If (-not (Test-Path $PlinkLocation)){
    Write-Host “Plink.exe not found, trying to download…”
    $WC = new-object net.webclient
    $WC.DownloadFile(“http://the.earth.li/~sgtatham/putty/latest/x86/plink.exe”,$PlinkLocation)
    If (-not (Test-Path $PlinkLocation)){
    Write-Host “Unable to download plink.exe, please download from the following URL and add it to the same folder as this script: http://the.earth.li/~sgtatham/putty/latest/x86/plink.exe
    Exit
    } Else {
    $PlinkEXE = Get-ChildItem $PlinkLocation
    If ($PlinkEXE.Length -gt 0) {
    Write-Host “Plink.exe downloaded, continuing script”
    } Else {
    Write-Host “Unable to download plink.exe, please download from the following URL and add it to the same folder as this script: http://the.earth.li/~sgtatham/putty/latest/x86/plink.exe
    Exit
    }
    }
    }

Leave a Comment