# ssh-copy-id analog for Windows systems # Script to install your public key on a remote machine # The remote machine must accept password authentication, # or one of the other keys in your Putty Agent, for this to work. # # (c) soar - http://soar.name # Dialog for public key selection Function Select-File() { [void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms"); $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog; $OpenFileDialog.Filter = "Public Keys (*.pub) | *.pub"; $OpenFileDialog.ShowHelp = $true; # Without this line - dialog not appears.. I don't understand why. [void] $OpenFileDialog.ShowDialog(); $OpenFileDialog.filename; } Function ShowMessage($title, $content, $type) { [void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms"); [void][Windows.Forms.Messagebox]::show($content, $title, $type); } # Returns current script directory, plink.exe must be in same place Function Get-ScriptDirectory { $Invocation = (Get-Variable MyInvocation -Scope 1).Value; Split-Path $Invocation.MyCommand.Path; } $pubKeyFile = Select-File if (! $pubKeyFile) { ShowMessage 'Need to select file' 'Please, select public key file for upload to remote host' 'OK'; Exit; } $pubKey = Get-Content -LiteralPath $pubKeyFile; if (! ($pubKey -is [string]) -or ! $pubKey.StartsWith("ssh-")) { ShowMessage "Wrong file?" "Selected file not looks like valid SSH public key. It must starts with `"ssh-`" and contain one line." "OK" Exit; } $plinkExecutable = "plink.exe"; if ($args.Length) { foreach ($arg in $args) { & $plinkExecutable -ssh $arg "umask 077; test -d ~/.ssh || mkdir ~/.ssh ; echo `"$pubKey`" >> ~/.ssh/authorized_keys" } } else { $hostname = Read-Host "Please enter target hostname (user@hostname):"; if ($hostname) { & $plinkExecutable -ssh $hostname "umask 077; test -d ~/.ssh || mkdir ~/.ssh ; echo `"$pubKey`" >> ~/.ssh/authorized_keys" } } Write-Host "Press any key to continue …" $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")