Отправить файлы через PSSession
Я просто сжег пару часов, ища решение для отправки файлов через активную PSSession. И в результате нада, ньенте. Я пытаюсь вызвать команду на удаленном компьютере через активный сеанс, который должен скопировать что-то из сетевого хранилища. Итак, в основном это он:
icm -Session $s {
Copy-Item $networkLocation $PCLocation }
Из-за проблемы "второго прыжка" я не могу сделать это напрямую, а потому, что я запускаю win server 2003, я не могу включить CredSSP. Я мог сначала скопировать файлы на свой компьютер, а затем отправить/направить их на удаленный компьютер, но как? Я пробовал PModem, но, как я понял, он может только извлекать данные и не нажимать.
Любая помощь может быть исправлена.
Ответы
Ответ 1
Если это был небольшой файл, вы можете отправить содержимое файла и имя файла в качестве параметров.
$f="the filename"
$c=Get-Content $f
invoke-command -session $s -script {param($filename,$contents) `
set-content -path $filename -value $contents} -argumentlist $f,$c
Если файл слишком длинный, чтобы соответствовать всем ограничениям для сеанса, вы можете прочитать файл в виде фрагментов и использовать аналогичный метод для добавления их в целевое местоположение
Ответ 2
Теперь это возможно в 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/
Ответ 3
Я столкнулся с той же проблемой некоторое время назад и собрал доказательство концепции отправки файлов по сеансу PS Remoting. Здесь вы найдете script:
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 не был предназначен для использования таким образом.
Ответ 4
$data = Get-Content 'C:\file.exe' -Raw
Invoke-Command -ComputerName 'server' -ScriptBlock { $using:data | Set-Content -Path 'D:\filecopy.exe' }
На самом деле не знаете, что такое ограничение максимального размера файла.
Ответ 5
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
ИЛИ
NET USE Z: \\RemoteSystem\ShareName /USER:Domain\UserName UserPassword
Если вы не предоставите учетные данные пользователя в той же строке, вам будет предложено:
>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 USE/?
>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.