2014-01-23 67 views
1

Powershell的命令行處理至少令人沮喪。Powershell使用字符串參數運行shell命令

我試圖像下面生成命令,並從PowerShell中執行它

type ".\id_rsa.pub" | ".\plink.exe" -ssh [email protected] -pw usepass "umask 077; test -d .ssh || mkdir .ssh; cat >> .ssh/authorized_keys; exit; " 

不過,我不斷收到對錯誤的,這取決於我如何努力去執行它(與調用表達或&) 。

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 [email protected] -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. 

我已經廣泛搜索並查看所有相關的計算器問題和答案。我嘗試過改變引號和命令,但目前爲止沒有運氣。

這是腳本。我叫它今天退出。我有一個批處理文件正在工作,但它的參數處理非常糟糕,使我很難從外部程序(如mremoteng)使用它。這取決於plink.exe,並在同一文件夾

<# 
.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 [email protected] password 
    .\Scriptname -i idtest.pub [email protected] password -Debug 
    .\ScriptName [email protected] 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)" 
} 

回答

2

--%從解析休息站PowerShell創建虛擬文件id_rsa.pub。這與不把plink.exe放在引號中結合起來可能會有用。

type ".\id_rsa.pub" | .\plink.exe --% -ssh [email protected] -pw usepass "umask 077; test -d .ssh || mkdir .ssh; cat >> .ssh/authorized_keys; exit; " 

更新

- %只能在PowerShell中3高。對於較低版本,您可以嘗試使用`(返回勾號)轉義所有衝突字符。請參閱here

+0

不是 - %只能[與v3]一起工作(https://blogs.technet.com/b/josebda/archive/2012/03/03/using-windows-powershell-to-run-old-命令行工具,和他們 - 最古怪的,parameters.aspx?重定向=真)?我正試圖保持腳本與v2兼容。 – Vijay

+0

是的,只有v3。對於較低版本,您需要使用' –