+# 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
+ [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
+ ShowMessage 'Need to select file' 'Please, select public key file for upload to remote host' 'OK';
+$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"
+$plinkExecutable = Join-Path (Get-ScriptDirectory) "plink.exe";
+ foreach ($arg in $args) {
+ & $plinkExecutable -ssh $arg "umask 077; test -d ~/.ssh || mkdir ~/.ssh ; echo `"$pubKey`" >> ~/.ssh/authorized_keys"
+ $hostname = Read-Host "Please enter target hostname (user@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")