2012-05-17 29 views
19

Tôi vừa mới đốt vài giờ tìm kiếm giải pháp để gửi tệp qua PSSession đang hoạt động. Và kết quả là nada, niente. Tôi đang cố gắng để gọi một lệnh trên một máy tính từ xa qua một phiên hoạt động, mà nên sao chép một cái gì đó từ một lưu trữ mạng. Vì vậy, về cơ bản đây là:Gửi tệp qua PSSession

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

Vì vấn đề "thứ hai", tôi không thể làm điều đó trực tiếp và vì tôi đang chạy máy chủ giành chiến thắng 2003 Tôi không thể bật CredSSP. Trước tiên tôi có thể sao chép các tập tin vào máy tính của tôi và sau đó gửi/đẩy chúng vào máy từ xa, nhưng làm thế nào? Tôi đã thử PModem, nhưng như tôi thấy nó chỉ có thể kéo dữ liệu và không đẩy.

Bất kỳ trợ giúp nào đều được phân tích.

+1

Tại sao bạn không sử dụng chia sẻ mạng để sao chép các tệp của mình? – JPBlanc

+1

Đẹp, nhưng chính quyền cao hơn không chấp nhận điều đó :) –

+1

Nếu bạn có thể bật máy tính từ xa là "Đáng tin cậy để ủy quyền" trong AD thì bạn có thể thực hiện bước nhảy thứ hai mà không có CredSSP. –

Trả lời

17

Nếu đó là một tệp nhỏ, bạn có thể gửi nội dung của tệp và tên tệp dưới dạng tham số.

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

Nếu tập tin là quá dài để phù hợp trong bất cứ giới hạn cho phiên làm việc được, bạn có thể đọc các tập tin trong khi khối, và sử dụng một kỹ thuật tương tự để gắn chúng lại với nhau trong vị trí mục tiêu

+1

'$ f == $ filename' và' $ c == $ contents' ?? –

+2

$ filename và $ contents là tên của các tham số trong scriptblock. $ f và $ c là các biến được chuyển tới scriptblock. –

2

Tôi đã đối mặt với cùng một vấn đề một thời gian trước đây và đặt cùng một chứng minh-of-khái niệm để gửi các tập tin trên một phiên PS Remoting. Bạn sẽ tìm thấy kịch bản ở đây:

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 
} 

Một số thay đổi nhỏ sẽ cho phép nó để chấp nhận một phiên như một tham số thay vì nó bắt đầu một cái mới. Tôi thấy mức tiêu thụ bộ nhớ trên dịch vụ Remoting trên máy tính đích có thể phát triển khá lớn khi truyền các tệp lớn. Tôi nghi ngờ PS Remoting không thực sự được thiết kế để được sử dụng theo cách này.

31

này bây giờ là có thể trong PowerShell/WMF 5,0

Copy-Item-FromSession-toSession tham số. Bạn có thể sử dụng một trong số này và chuyển vào một biến phiên.

ví dụ:

$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 

Xem thêm ví dụ ở 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' } 

Đừng thực sự biết những gì các tập tin giới hạn kích thước tối đa là.

+0

'get-data' là gì? – Mark

+0

Điều đó sẽ khiến tôi gõ mạnh mẽ trên đỉnh đầu. Nên có được 'Get-Nội dung' rõ ràng là – mtnielsen

1

NET USE cho phép bạn thêm một ký tự ổ đĩa cục bộ cho các hệ thống từ xa, sau đó sau đó cho phép bạn sử dụng các ký tự ổ đĩa trong PSSession của bạn, hoặc thậm chí không có một PSSession. Điều này rất hữu ích nếu bạn không có Powershell v5.0, và thậm chí nếu bạn làm thế,

Bạn có thể sử dụng tên máy tính từ xa hoặc địa chỉ IP của nó như là một phần của con đường UNC từ xa và bạn có thể chỉ định tên người dùng và mật khẩu thông tin trên cùng một dòng:

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

Một ví dụ khác:

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

HOẶC

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

Nếu bạn không cung cấp cho người dùng cr edentials trên cùng một dòng, bạn sẽ được nhắc nhở cho họ:

>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. 

Bạn có thể loại bỏ các ký tự ổ đĩa khi bạn đã hoàn tất các nội dung sau:

NET USE Z: /delete 

Bạn có thể nhận được cú pháp đầy đủ với NET SỬ DỤNG /?

>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 là lệnh bên ngoài chuẩn .exe trong thư mục hệ thống và hoạt động trong Powershell.

+0

Không phải là nó dễ dàng hơn nhiều để chỉ cần nâng cấp quyền hạn của bạn để v5 +? – Liam