Powershell的命令行处理至少可以说令人沮丧。
我正在尝试生成如下命令并从powershell
执行它type ".\id_rsa.pub" | ".\plink.exe" -ssh user@example.com -pw usepass "umask 077; test -d .ssh || mkdir .ssh; cat >> .ssh/authorized_keys; exit; "
但是我不断得到这对错误,具体取决于我尝试执行它的方式(使用Invoke-Expression或&)。
ERROR: You must provide a value expression on the right-hand side of the '-' operator.
ERROR: The term 'type ".\id_rsa.pub" | ".\plink.exe" -ssh user@example.com -pw usepass "umask 077; test -d .ssh || mkdir .ssh; cat >> .ssh/authorized_keys; exit; "' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
我已经广泛搜索并查看了所有相关的stackoverflow问题和答案。我试过改变引号和命令,但到目前为止没有运气。
这是脚本。我今天叫它退出。我有一个正在运行的批处理文件,但它的参数处理非常糟糕,因此我很难从外部程序(如mremoteng)中使用它。它取决于plink.exe并在同一文件夹中创建一个虚拟文件id_rsa.pub
<#
.NAME
ssh-copy-id.ps1
.SYNOPSIS
Copy public key to remote hosts
.DESCRIPTION
See Synopsis
.SYNTAX
Invoke directly from the powershell command line
.EXAMPLES
.\Scriptname -i idtest.pub user@example.com password
.\Scriptname -i idtest.pub user@example.com password -Debug
.\ScriptName user@example.com password
.NOTES
AUTHOR: VijayS
DATE: 2014-01-23
COMMENT:
DEPENDENCIES:
plink.exe
type
.HELPURL
http://stackoverflow.com
.SEEALSO
.REFERNCE
http://www.christowles.com/2011/06/how-to-ssh-from-powershell-using.html
#>
Param(
[Parameter(Position=0,Mandatory=$true)]
[String]$user_at_hostname,
[Parameter(Position=1)]
[String]$Password,
[Parameter(HelpMessage="The public key file to copy")]
[ValidateScript({Test-Path $_})]
[Alias("i")]
[String]$identity="id_rsa.pub",
[switch]$ConnectOnceToAcceptHostKey=$false
)
####################################
Function Get-SSHCommands {
Param($Target,$Password, $CommandArray,
$PlinkAndPath,
$ConnectOnceToAcceptHostKey = $true)
$plinkoptions = "-ssh $Target"
if ($Password) { $plinkoptions += " -pw $Password " }
#Build ssh Commands
$CommandArray += "exit"
$remoteCommand = ""
$CommandArray | % {
$remoteCommand += [string]::Format('{0}; ', $_)
}
#plist prompts to accept client host key. This section will
#login and accept the host key then logout.
if($ConnectOnceToAcceptHostKey)
{
$PlinkCommand = [string]::Format("echo y | & '{0}' {1} exit",
$PlinkAndPath, $plinkoptions )
#Write-Host $PlinkCommand
$msg = Invoke-Expression $PlinkCommand
}
#format plist command
# $PlinkCommand = [string]::Format("'{0}' {1} '{2}'",
# $PlinkAndPath, $plinkoptions , $remoteCommand)
$PlinkCommand = [string]::Format('"{0}" {1} "{2}"',
$PlinkAndPath, $plinkoptions , $remoteCommand)
#ready to run the following command
#Write-Debug $PlinkCommand
return $PlinkCommand
#$msg = Invoke-Expression $PlinkCommand
#$msg
}
##################
$ErrorActionPreference = "Stop" # "Continue" "SilentlyContinue" "Stop" "Inquire"
$DebugPreference = "Continue"
trap { #Stop on all errors
Write-Error "ERROR: $_"
}
$PlinkAndPath = '.\plink.exe'
#from http://serverfault.com/questions/224810/is-there-an-equivalent-to-ssh-copy-id-for-windows
$Commands = @()
$Commands += "umask 077" #change permissions to be restrictive
$Commands += "test -d .ssh || mkdir .ssh" #test and create .ssh director if it doesn't exist
$Commands += "cat >> .ssh/authorized_keys" #append the public key to file
#Write-Debug $Password
#Write-Debug $identity
Try {
$tmp = Get-ItemProperty -Path $identity
$tmp = Get-ItemProperty -Path $PlinkAndPath
$cmd = Get-SSHCommands -Target $user_at_hostname `
-Password $Password `
-PlinkAndPath $PlinkAndPath `
-CommandArray $Commands `
-ConnectOnceToAcceptHostKey $ConnectOnceToAcceptHostKey
# pipe the public key to the plink session to get it appended in the right place
$cmd = "type ""$identity"" | " + $cmd
Write-Debug $cmd
#Invoke-Expression $cmd
& $cmd
}
Catch {
Write-Error "$($_.Exception.Message)"
}