主机:Windows Server 2016
客人:Windows 10 x64 1903
VM版本:8.0
首先,此VM与主机位于不同的VLAN中,并且专用于该VLAN的NIC无法与主机共享。同样,来宾和主机之间的第二个仅主机的网络也不是可接受的解决方案。
如果我在每个文件的交互式会话中使用Copy-Item -FromSession
,则文件复制不会出现问题。但是,当我尝试在脚本中使用它时,收到一条错误消息,指出源文件的路径不存在,这是有道理的,因为该路径应该在来宾而不是主机上。尝试使用Get-ChildItem
时,我遇到了同样的问题,因为该操作是在Hyper-V主机而非来宾的上下文中执行的。但是,如果我尝试将Copy-Item -FromSession
包装在Invoke-Command
中并插入$Using:<var>
语法,则会收到一条错误消息,指出找不到参数
$VMRootDir = "Z:\vmshare\Completed\" <# On the guest #>
$DestDir = "D:\Encoding Work\VMshare\" <# Local to the host #>
# Setup Remote Session
$User = ".\psdirect"
$Pword = ConvertTo-SecureString -String "********" -AsPlainText -Force
$Cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $Pword
$VMName = "TranscodeBox"
$S = New-PSSession -Credential $Cred -VMName $VMName
Enter-PSSession -Session $S
# Get Files to Copy
$files = Invoke-Command -Session $S -ScriptBlock { Get-ChildItem $Using:VMRootDir -Recurse | Where-Object {!$_.PSIsContainer } | % { $_.FullName } }
# Copy Each File
Foreach ($file in $files) {
# Get the new name
$DestFileStr = $DestDir + $file.ToString().TrimStart($VMRootDir)
#tell 'em what's happening
write-host $file " -> " $DestFileStr
#Do the copying
<# This is were the error occurs #>
Copy-Item -FromSession $S -Path $file -Destination $DestFileStr -Force
Invoke-Command -Session $S -ScriptBlock { Copy-Item -FromSession $Using:S -Path $Using:file -Destination $Using:DestFileStr -Force}
# Cleanup if the new file exists
If (Test-Path $DestFileStr) {
#Remove-Item $file
Write-Host "Success " $DestFileStr
}
}
#Cleanup the Session
Exit-PSSession
Remove-PSSession -Session $S
错误消息(每个文件重复):
Copy-Item : Cannot find path 'Z:\vmshare\Completed\***\*****.mkv' because it does not exist.
At C:\Users\******\Desktop\cpTranscodeBox.ps1:23 char:5
+ Copy-Item -FromSession $S -Path $file -Destination $DestFileStr - ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (Z:\vmshare\Comp... *****.mkv:String) [Copy-Item], ArgumentException
+ FullyQualifiedErrorId : RemotePathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand
A parameter cannot be found that matches parameter name 'FromSession'.
+ CategoryInfo : InvalidArgument: (:) [Copy-Item], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.CopyItemCommand
+ PSComputerName : TranscodeBox
答案 0 :(得分:0)
在这种情况下,此问题是由源文件名中包含[
和]
引起的,我通过转义源文件名来解决了该问题
[Management.Automation.WildcardPattern]::Escape($<var>)
完整脚本:
$VMRootDir = "Z:\vmshare\Completed\" <# On the guest #>
$DestDir = "D:\Encoding Work\VMshare\" <# Local to the host #>
# Setup Remote Session
$User = ".\psdirect"
$Pword = ConvertTo-SecureString -String "********" -AsPlainText -Force
$Cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $Pword
$VMName = "TranscodeBox"
$S = New-PSSession -Credential $Cred -VMName $VMName
Enter-PSSession -Session $S
# Get Files to Copy
$files = Invoke-Command -Session $S -ScriptBlock { Get-ChildItem $Using:VMRootDir -Recurse | Where-Object {!$_.PSIsContainer } | % { $_.FullName } }
# Copy Each File
Foreach ($file in $files) {
# Get the new name
$DestFileStr = $DestDir + $file.TrimStart($VMRootDir)
#tell 'em what's happening
write-host $file " -> " $DestFileStr
#Create the Directory if it doesn't exist
$newDir = ([System.IO.Path]::GetDirectoryName($DestFileStr))
if (!(Test-Path([Management.Automation.WildcardPattern]::Escape($newDir)))) { mkdir $newDir }
#Do the copying
Copy-Item -FromSession $S -Path ([Management.Automation.WildcardPattern]::Escape($file)) -Destination $DestFileStr
# Cleanup if the new file exists
If (Test-Path ([Management.Automation.WildcardPattern]::Escape($DestFileStr))) {
invoke-Command -Session $S -ScriptBlock {Remove-Item ([Management.Automation.WildcardPattern]::Escape($Using:file))}
Write-Host "Success " $DestFileStr
}
}
#Cleanup the Session
Exit-PSSession
Remove-PSSession -Session $S