アクティブなPSSessionを介してファイルを送信するためのソリューションを探すために数時間を費やしました。そしてその結果は、nient、nienteです。ネットワークストレージから何かをコピーする必要があるアクティブなセッションを介してリモートコンピューターでコマンドを呼び出そうとしています。だから、基本的にはこれです:
icm -Session $s {
Copy-Item $networkLocation $PCLocation }
「セカンドホップ」の問題のため、直接実行することはできません。WinServer 2003を実行しているため、CredSSPを有効にできません。最初にファイルをコンピューターにコピーしてから、リモートマシンに送信/プッシュできますが、どうすればよいですか?私はPModemを試しましたが、見たとおり、データのプルのみが可能で、プッシュは不可能です。
どんな助けでも喜ばれます。
小さいファイルの場合は、ファイルの内容とファイル名をパラメータとして送信できます。
$f="the filename"
$c=Get-Content $f
invoke-command -session $s -script {param($filename,$contents) `
set-content -path $filename -value $contents} -argumentlist $f,$c
ファイルが長すぎてセッションの制限に収まらない場合は、ファイルをチャンクとして読み取り、同様の手法を使用してターゲットの場所にファイルを追加できます。
これは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/ で他の例を参照してください
私は少し前に同じ問題に直面し、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は実際にはこのように使用するように設計されていなかったと思います。
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
同じ行でユーザー資格情報を指定しない場合は、それらの入力を求められます。
>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:[username@dotted domain name]
[/SMARTCARD]
[/SAVECRED]
[[/DELETE] | [/PERSISTENT:{YES | NO}]]
Net Use {devicename | *} [password | *] /HOME
Net Use [/PERSISTENT:{YES | NO}]
NET
は、システムフォルダー内の標準の外部.exeコマンドであり、Powershellで正常に動作します。
$data = Get-Content 'C:\file.exe' -Raw
Invoke-Command -ComputerName 'server' -ScriptBlock { $using:data | Set-Content -Path 'D:\filecopy.exe' }
最大ファイルサイズの制限が実際には何であるかはわかりません。