2012-05-17 148 views
19

我刚刚烧了几个小时寻找解决方案,通过活动的PSSession发送文件。结果是nada,niente。我试图通过活动会话在远程计算机上调用命令,该命令应从网络存储中复制某些内容。所以,基本上,这是它:通过PSSession发送文件

icm -Session $s { 
Copy-Item $networkLocation $PCLocation } 

因为“第二跳”的问题,我不能直接这样做,因为我跑赢服务器2003年,我不能启用的CredSSP。我可以先将这些文件复制到我的电脑,然后发送/推送到远程机器,但是怎么做?我试过PModem,但正如我所看到的,它只能拉数据而不推。

任何帮助appreaciated。

+1

为什么你不使用网络共享tu复制你的文件? – JPBlanc

+1

不错,但上级主管部门不赞同:) –

+1

如果您可以在AD中启用远程计算机为“可信代理”,那么您可以在没有CredSSP的情况下执行第二跳。 –

回答

17

如果它是一个小文件,您可以发送文件的内容和文件名作为参数。

$f="the filename" 
$c=Get-Content $f 
invoke-command -session $s -script {param($filename,$contents) ` 
    set-content -path $filename -value $contents} -argumentlist $f,$c 

如果文件太长,无法在任何会话的限制是,你可以阅读的块中的文件,并在目标位置使用类似的技术来追加在一起

+1

'$ f == $ filename'和'$ c == $ contents'? –

+2

$ filename和$ contents是脚本块中参数的名称。 $ f和$ c是传递给scriptblock的变量。 –

2

我前一阵面临同样的问题,并且通过PS Remoting会话发送文件的概念验证。你会发现这里的脚本:

https://gist.github.com/791112

#requires -version 2.0 

[CmdletBinding()] 
param (
    [Parameter(Mandatory=$true)] 
    [string] 
    $ComputerName, 

    [Parameter(Mandatory=$true)] 
    [string] 
    $Path, 

    [Parameter(Mandatory=$true)] 
    [string] 
    $Destination, 

    [int] 
    $TransferChunkSize = 0x10000 
) 

function Initialize-TempScript ($Path) { 
    "<# DATA" | Set-Content -Path $Path 
} 

function Complete-Chunk() { 
@" 
DATA #> 
`$TransferPath = `$Env:TEMP | Join-Path -ChildPath '$TransferId' 
`$InData = `$false 
`$WriteStream = [IO.File]::OpenWrite(`$TransferPath) 
try { 
    `$WriteStream.Seek(0, 'End') | Out-Null 
    `$MyInvocation.MyCommand.Definition -split "``n" | ForEach-Object { 
     if (`$InData) { 
      `$InData = -not `$_.StartsWith('DATA #>') 
      if (`$InData) { 
       `$WriteBuffer = [Convert]::FromBase64String(`$_) 
       `$WriteStream.Write(`$WriteBuffer, 0, `$WriteBuffer.Length) 
      } 
     } else { 
      `$InData = `$_.StartsWith('<# DATA') 
     } 
    } 
} finally { 
    `$WriteStream.Close() 
} 
"@ 
} 

function Complete-FinalChunk ($Destination) { 
@" 
`$TransferPath | Move-Item -Destination '$Destination' -Force 
"@ 
} 

$ErrorActionPreference = 'Stop' 
Set-StrictMode -Version Latest 

$EncodingChunkSize = 57 * 100 
if ($EncodingChunkSize % 57 -ne 0) { 
    throw "EncodingChunkSize must be a multiple of 57" 
} 

$TransferId = [Guid]::NewGuid().ToString() 


$Path = ($Path | Resolve-Path).ProviderPath 
$ReadBuffer = New-Object -TypeName byte[] -ArgumentList $EncodingChunkSize 

$TempPath = ([IO.Path]::GetTempFileName() | % { $_ | Move-Item -Destination "$_.ps1" -PassThru}).FullName 
$Session = New-PSSession -ComputerName $ComputerName 
$ReadStream = [IO.File]::OpenRead($Path) 

$ChunkCount = 0 
Initialize-TempScript -Path $TempPath 

try { 
    do { 
     $ReadCount = $ReadStream.Read($ReadBuffer, 0, $EncodingChunkSize) 
     if ($ReadCount -gt 0) { 
      [Convert]::ToBase64String($ReadBuffer, 0, $ReadCount, 'InsertLineBreaks') | 
       Add-Content -Path $TempPath 
     } 
     $ChunkCount += $ReadCount 
     if ($ChunkCount -ge $TransferChunkSize -or $ReadCount -eq 0) { 
      # send 
      Write-Verbose "Sending chunk $TransferIndex" 
      Complete-Chunk | Add-Content -Path $TempPath 
      if ($ReadCount -eq 0) { 
       Complete-FinalChunk -Destination $Destination | Add-Content -Path $TempPath 
       Write-Verbose "Sending final chunk" 
      } 
      Invoke-Command -Session $Session -FilePath $TempPath 

      # reset 
      $ChunkCount = 0 
      Initialize-TempScript -Path $TempPath 
     } 
    } while ($ReadCount -gt 0) 
} finally { 
    if ($ReadStream) { $ReadStream.Close() } 
    $Session | Remove-PSSession 
    $TempPath | Remove-Item 
} 

一些小的改动将允许它接受一个会话开始一个新的参数,而不是它。我发现在传输大文件时,目标计算机上Remoting服务的内存消耗可能会变得非常大。我怀疑PS Remoting的设计并不是真正用于这种方式。

31

这是现在可以在PowerShell中/ WMF 5.0

Copy-Item具有-FromSession-toSession参数。您可以使用其中之一并传入会话变量。

例如。

$cs = New-PSSession -ComputerName 169.254.44.14 -Credential (Get-Credential) -Name SQL 
Copy-Item Northwind.* -Destination "C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL2008R2\MSSQL\DATA\" -ToSession $cs 

查看更多的例子在https://richardspowershellblog.wordpress.com/2015/05/28/copy-files-over-ps-remoting-sessions/

0
$data = Get-Content 'C:\file.exe' -Raw 
Invoke-Command -ComputerName 'server' -ScriptBlock { $using:data | Set-Content -Path 'D:\filecopy.exe' } 

真的不知道,最大文件大小限制是什么。

+0

什么是get-data? – Mark

+0

这将是我打字我的头顶powershell。本应该是'Get-Content' – mtnielsen

1

NET USE允许你添加一个本地驱动器号远程系统,然后再允许你使用你的PSSession中的驱动器盘符,或者即使没有PSSession的。如果您没有Powershell v5,这很有用。0,即使你做,

您可以使用远程计算机的名称或IP地址作为远程UNC路径的一部分,您可以指定在同一行上的用户名和密码凭据:

NET USE Z: \\192.168.1.50\ShareName /USER:192.168.1.50\UserName UserPassword 

又如:

NET USE Z: \\RemoteSystem\ShareName /USER:RemoteSystem\UserName UserPassword 

OR

NET USE Z: \\RemoteSystem\ShareName /USER:Domain\UserName UserPassword 

如果不提供用户CR在同一行edentials,系统将提示您为他们:

>NET USE Z: \\192.168.1.50\ShareName 
Enter the user name for '192.168.1.50': 192.168.1.50\UserName 
Enter the password for 192.168.1.50: ***** 
The command completed successfully. 

您可以删除驱动器号,当你用下面的完成:

NET USE Z: /delete 

你可以用NET完整的语法使用 /?

>net use /? 
The syntax of this command is: 

NET USE 
[devicename | *] [\\computername\sharename[\volume] [password | *]] 
     [/USER:[domainname\]username] 
     [/USER:[dotted domain name\]username] 
     [/USER:[[email protected] domain name] 
     [/SMARTCARD] 
     [/SAVECRED] 
     [[/DELETE] | [/PERSISTENT:{YES | NO}]] 

NET USE {devicename | *} [password | *] /HOME 

NET USE [/PERSISTENT:{YES | NO}] 

NET是系统文件夹中的标准外部的.exe命令,并在PowerShell中工作得很好。

+0

将PowerShell升级到v5 +不是很容易吗? – Liam