21

アクティブなPSSessionを介してファイルを送信するための解決策を探して、数時間燃焼しました。そして結果は灘、nienteです。アクティブなセッションを介してリモートコンピューターでコマンドを呼び出そうとしています。これにより、ネットワークストレージから何かがコピーされます。だから、基本的にこれはそれです:

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

「セカンドホップ」の問題のため、直接それを行うことはできません。また、win server 2003を実行しているため、CredSSPを有効にできません。最初にファイルを自分のコンピューターにコピーしてから、リモートマシンに送信/プッシュすることもできますが、どうすればよいでしょうか。PModemを試しましたが、見たようにデータをプルすることしかできず、プッシュすることはできません。

どんな助けでも感謝されます。

4

5 に答える 5

44

これは、PowerShell /WMF5.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

ここで他の例を参照するか、公式ドキュメントをチェックアウトできます。

于 2016-02-29T04:52:13.037 に答える
21

小さなファイルの場合は、ファイルの内容とファイル名をパラメータとして送信できます。

$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 5+には、これを行うための組み込みのサポートがあります。これについては、 Davidの回答で説明されています。

于 2012-05-17T19:22:33.547 に答える
4

私はしばらく前に同じ問題に直面し、PSRemotingセッションを介してファイルを送信するための概念実証をまとめました。スクリプトはここにあります:

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は、実際にはこのように使用するように設計されていなかったと思います。

于 2012-05-18T01:00:51.873 に答える
1
$data = Get-Content 'C:\file.exe' -Raw
Invoke-Command -ComputerName 'server' -ScriptBlock { $using:data | Set-Content -Path 'D:\filecopy.exe' }

最大ファイルサイズの制限が実際に何であるかわからない。

于 2016-08-19T09:30:33.123 に答える
1

NET USEリモートシステムのローカルドライブ文字を追加できます。これにより、PSSessionで、またはPSSessionなしでドライブ文字を使用できます。これは、Powershell v5.0をお持ちでない場合に役立ちます。お持ちの場合でも、

リモートUNCパスの一部としてリモートマシン名またはそのIPアドレスを使用でき、同じ行でユーザー名とパスワードのクレデンシャルを指定できます。

    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:[username@dotted domain name]
        [/SMARTCARD]
        [/SAVECRED]
        [[/DELETE] | [/PERSISTENT:{YES | NO}]]

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

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

NETはシステムフォルダー内の標準の外部.exeコマンドであり、Powershellで正常に機能します。

于 2017-04-11T12:36:12.433 に答える