2014-01-23 2 views
1

Управление командной строкой Powershell, по меньшей мере, разочаровывает.Powershell запускает команду оболочки с аргументами из строки

Я пытаюсь создать команду, как показано ниже, и выполнить его из PowerShell

type ".\id_rsa.pub" | ".\plink.exe" -ssh [email protected] -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 [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 и создать фиктивный файл 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 [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 из анализа остальные. Это в сочетании с не помещением 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 и выше. Для более низких версий вы можете попытаться избежать всех конфликтующих символов с помощью `(back tick). См. here.

+0

Не работает -% работает только [с v3] (https://blogs.technet.com/b/josebda/archive/2012/03/03/using-windows-powershell-to-run-old- командная строка-инструменты-и-их-странный-parameters.aspx? Redirected = истина)? Я пытаюсь сохранить скрипт совместимым с v2. – Vijay

+0

Да, только v3. Для более низкой версии вам нужно использовать ' –

Смежные вопросы