среда, 10 августа 2011 г.

Копипаст в виртуалку

В процессе работы понадобилось передать содержимое всяких текстовых файликов в виртуалки на основе hyperv. При этом очень хотелось не подключать их ни к общей сети ни к сети компьютера-хоста. В общем – без всяких там RDP и иже с ними. Просто скопировать и вставить. Для этих целей есть встроенная возможность:

typeText

Однако если попытаться вставить большой объем текста – получается следующее:typeTextErr


Собственно говоря, покопавшись в гуглах я обнаружил, что есть WMI Классы для работы с hyperv. Собственно на основе их родилась вот такая вот функция. Особенность функции в том, что тот метод, который зовется из WMI, принимает на вход только ascii строку – 7 бит. А значит, русский шрифт, как не прискорбно, передать не выйдет. Ну да и черт с ним, хотя, конечно, печалька.

К слову говоря, sleep тут нужен по причине того, что без него работает с некоторыми странностями.
<#
.SYNOPSIS
Отправка текста в буфере обмена в виртуальную машину hyper-v

.DESCRIPTION
Текст, находящийся в буфере обмена отправляется в виртуальную машину
методом TypeText wmi класса Msvm_Keyboard. Попросту говоря при передаче текста
внутри виртуальной машины эмулируется нажатие соответствующих клавиш.
Для использования функции необходимо наличие в буфере обмена текста, и открытое активное
окно редактора текста в виртуальной машине

.PARAMETER $VM
Имя виртуальной машины.

.PARAMETER $Server
Имя hyper-v сервера. Поумолчанию используется текущая машина

.EXAMPLE
PS C:\>send-clipboardtext -vm pkidemosubordinateca1

Пример вызова функции

.INPUTS
System.String,System.String
#>
function send-clipboardText {
[CmdletBinding()]
param(
[parameter(Position=0 , Mandatory = $true, ValueFromPipeline = $false)] $VM,
[String]$Server="."
)
begin {
try {
}
catch {
}
}
process {
try {
$text = ([System.Windows.Forms.Clipboard]::GetText()) -split "`n"
$ascii = [System.Text.Encoding]::ASCII

if ($VM -is [String]) {$VM=(Get-VM -Name $VM -Server $Server) }
if ($VM -is [System.Management.ManagementObject]) {
$VSMKB=($VM.getRelated("Msvm_Keyboard") | select-object)
if ($text -ne $null ) {
foreach ($line in $text){
$bytes = $ascii.getBytes($line)
$line = $ascii.getString($bytes)
$result = $VSMKB.TypeText($line)
if ($result.returnvalue -eq 0) {write-host "'$line' was successfully sent to $vm on $server"}
sleep -Milliseconds ($line.Length*10)
}
}
}
}
catch {
echo "oops!"
$Error
}
}
end {
try {
}
catch {
}
}
}

Ну и пример вызова
send-clipboardtext -vm contosoca1
Отправить комментарий