Files
Packer-Cn/powershell/hyperv/hyperv.go
T
Taliesin Sisson 010d171bec GuestAdditionsMode and GuestAdditionsPath can be set in config. If GuestAdditionsMode == "attach" it will mount the HyperV Integration Services ISO. If GuestAdditionsPath is set, then it will be used as an alternative to where the HyperV Integration Service ISO is.
Included the build step to download ISO, so iso_urls works properly now.
Online activation should be done via provisioner
Installation of integration services should be done via provisioner
Cleaned up the way dvd drives are mounted and unmounted (still need to implement feature to find unused drives before adding a new one)
Cleaned up the way floppies are mounted and unmounted
2016-12-12 22:44:27 +00:00

821 lines
22 KiB
Go

package hyperv
import (
"github.com/mitchellh/packer/powershell"
"strconv"
"strings"
)
func GetHostAdapterIpAddressForSwitch(switchName string) (string, error) {
var script = `
param([string]$switchName, [int]$addressIndex)
$HostVMAdapter = Get-VMNetworkAdapter -ManagementOS -SwitchName $switchName
if ($HostVMAdapter){
$HostNetAdapter = Get-NetAdapter | ?{ $_.DeviceID -eq $HostVMAdapter.DeviceId }
if ($HostNetAdapter){
$HostNetAdapterConfiguration = @(get-wmiobject win32_networkadapterconfiguration -filter "IPEnabled = 'TRUE' AND InterfaceIndex=$($HostNetAdapter.ifIndex)")
if ($HostNetAdapterConfiguration){
return @($HostNetAdapterConfiguration.IpAddress)[$addressIndex]
}
}
}
return $false
`
var ps powershell.PowerShellCmd
cmdOut, err := ps.Output(script, switchName, "0")
return cmdOut, err
}
func GetVirtualMachineNetworkAdapterAddress(vmName string) (string, error) {
var script = `
param([string]$vmName, [int]$addressIndex)
try {
$adapter = Get-VMNetworkAdapter -VMName $vmName -ErrorAction SilentlyContinue
$ip = $adapter.IPAddresses[$addressIndex]
if($ip -eq $null) {
return $false
}
} catch {
return $false
}
$ip
`
var ps powershell.PowerShellCmd
cmdOut, err := ps.Output(script, vmName, "0")
return cmdOut, err
}
func CreateDvdDrive(vmName string, generation uint) (uint, uint, error) {
var ps powershell.PowerShellCmd
var script string
var controllerNumber uint
controllerNumber = 0
if generation < 2 {
// get the controller number that the OS install disk is mounted on
// generation 1 requires dvd to be added to ide controller, generation 2 uses scsi for dvd drives
script = `
param([string]$vmName)
$dvdDrives = (Get-VMDvdDrive -VMName $vmName)
$lastControllerNumber = $dvdDrives | Sort-Object ControllerNumber | Select-Object -Last 1 | %{$_.ControllerNumber}
if (!$lastControllerNumber) {
$lastControllerNumber = 0
} elseif (!$lastControllerNumber -or ($dvdDrives | ?{ $_.ControllerNumber -eq $lastControllerNumber} | measure).count -gt 1) {
$lastControllerNumber += 1
}
$lastControllerNumber
`
cmdOut, err := ps.Output(script, vmName)
if err != nil {
return 0, 0, err
}
controllerNumberTemp, err := strconv.ParseUint(strings.TrimSpace(cmdOut), 10, 64)
if err != nil {
return 0, 0, err
}
controllerNumber = uint(controllerNumberTemp)
if controllerNumber != 0 && controllerNumber != 1 {
//There are only 2 ide controllers, try to use the one the hdd is attached too
controllerNumber = 0
}
}
script = `
param([string]$vmName,[int]$controllerNumber)
Add-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber
`
cmdOut, err := ps.Output(script, vmName)
if err != nil {
return controllerNumber, 0, err
}
// we could try to get the controller location and number in one call, but this way we do not
// need to parse the output
script = `
param([string]$vmName)
(Get-VMDvdDrive -VMName $vmName | Where-Object {$_.Path -eq $null}).ControllerLocation
`
cmdOut, err = ps.Output(script, vmName)
if err != nil {
return controllerNumber, 0, err
}
controllerLocationTemp, err := strconv.ParseUint(strings.TrimSpace(cmdOut), 10, 64)
if err != nil {
return controllerNumber, 0, err
}
controllerLocation := uint(controllerLocationTemp)
return controllerNumber, controllerLocation, err
}
func MountDvdDrive(vmName string, path string) error {
var script = `
param([string]$vmName,[string]$path)
Set-VMDvdDrive -VMName $vmName -Path $path
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, path)
return err
}
func MountDvdDriveByLocation(vmName string, path string, controllerNumber uint, controllerLocation uint) error {
var script = `
param([string]$vmName,[string]$path,[string]$controllerNumber,[string]$controllerLocation)
Set-VMDvdDrive -VMName $vmName -Path $path -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, path, strconv.FormatInt(int64(controllerNumber), 10), strconv.FormatInt(int64(controllerLocation), 10))
return err
}
func UnmountDvdDrive(vmName string) error {
var script = `
param([string]$vmName)
Get-VMDvdDrive -VMName $vmName | Set-VMDvdDrive -Path $null
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName)
return err
}
func SetBootDvdDrive(vmName string, controllerNumber uint, controllerLocation uint) error {
var script = `
param([string]$vmName,[int]$controllerNumber,[int]$controllerLocation)
$vmDvdDrive = Get-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation
if (!$vmDvdDrive) {throw 'unable to find dvd drive'}
Set-VMFirmware -VMName $vmName -FirstBootDevice $vmDvdDrive
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, strconv.FormatInt(int64(controllerNumber), 10), strconv.FormatInt(int64(controllerLocation), 10))
return err
}
func DeleteDvdDrive(vmName string, controllerNumber uint, controllerLocation uint) error {
var script = `
param([string]$vmName,[int]$controllerNumber,[int]$controllerLocation)
$vmDvdDrive = Get-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation
if (!$vmDvdDrive) {throw 'unable to find dvd drive'}
Remove-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, strconv.FormatInt(int64(controllerNumber), 10), strconv.FormatInt(int64(controllerLocation), 10))
return err
}
func MountFloppyDrive(vmName string, path string) error {
var script = `
param([string]$vmName, [string]$path)
Set-VMFloppyDiskDrive -VMName $vmName -Path $path
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, path)
return err
}
func UnmountFloppyDrive(vmName string) error {
var script = `
param([string]$vmName)
Set-VMFloppyDiskDrive -VMName $vmName -Path $null
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName)
return err
}
func CreateVirtualMachine(vmName string, path string, ram int64, diskSize int64, switchName string, generation uint) error {
if generation == 2 {
var script = `
param([string]$vmName, [string]$path, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [int]$generation)
$vhdx = $vmName + '.vhdx'
$vhdPath = Join-Path -Path $path -ChildPath $vhdx
New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName -Generation $generation
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, path, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatInt(int64(generation), 10))
return err
} else {
var script = `
param([string]$vmName, [string]$path, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName)
$vhdx = $vmName + '.vhdx'
$vhdPath = Join-Path -Path $path -ChildPath $vhdx
New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, path, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName)
return err
}
}
func SetVirtualMachineCpu(vmName string, cpu uint) error {
var script = `
param([string]$vmName, [int]$cpu)
Set-VMProcessor -VMName $vmName -Count $cpu
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, strconv.FormatInt(int64(cpu), 10))
return err
}
func SetSecureBoot(vmName string, enable bool) error {
var script = `
param([string]$vmName, $enableSecureBoot)
Set-VMFirmware -VMName $vmName -EnableSecureBoot $enableSecureBoot
`
var ps powershell.PowerShellCmd
enableSecureBoot := "Off"
if enable {
enableSecureBoot = "On"
}
err := ps.Run(script, vmName, enableSecureBoot)
return err
}
func DeleteVirtualMachine(vmName string) error {
var script = `
param([string]$vmName)
$vm = Get-VM -Name $vmName
if (($vm.State -ne [Microsoft.HyperV.PowerShell.VMState]::Off) -and ($vm.State -ne [Microsoft.HyperV.PowerShell.VMState]::OffCritical)) {
Stop-VM -VM $vm -TurnOff -Force -Confirm:$false
}
Remove-VM -Name $vmName -Force -Confirm:$false
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName)
return err
}
func ExportVirtualMachine(vmName string, path string) error {
var script = `
param([string]$vmName, [string]$path)
Export-VM -Name $vmName -Path $path
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, path)
return err
}
func CompactDisks(expPath string, vhdDir string) error {
var script = `
param([string]$srcPath, [string]$vhdDirName)
Get-ChildItem "$srcPath/$vhdDirName" -Filter *.vhd* | %{
Optimize-VHD -Path $_.FullName -Mode Full
}
`
var ps powershell.PowerShellCmd
err := ps.Run(script, expPath, vhdDir)
return err
}
func CopyExportedVirtualMachine(expPath string, outputPath string, vhdDir string, vmDir string) error {
var script = `
param([string]$srcPath, [string]$dstPath, [string]$vhdDirName, [string]$vmDir)
Move-Item -Path $srcPath/*.* -Destination $dstPath
Move-Item -Path $srcPath/$vhdDirName -Destination $dstPath
Move-Item -Path $srcPath/$vmDir -Destination $dstPath
`
var ps powershell.PowerShellCmd
err := ps.Run(script, expPath, outputPath, vhdDir, vmDir)
return err
}
func CreateVirtualSwitch(switchName string, switchType string) (bool, error) {
var script = `
param([string]$switchName,[string]$switchType)
$switches = Get-VMSwitch -Name $switchName -ErrorAction SilentlyContinue
if ($switches.Count -eq 0) {
New-VMSwitch -Name $switchName -SwitchType $switchType
return $true
}
return $false
`
var ps powershell.PowerShellCmd
cmdOut, err := ps.Output(script, switchName, switchType)
var created = strings.TrimSpace(cmdOut) == "True"
return created, err
}
func DeleteVirtualSwitch(switchName string) error {
var script = `
param([string]$switchName)
$switch = Get-VMSwitch -Name $switchName -ErrorAction SilentlyContinue
if ($switch -ne $null) {
$switch | Remove-VMSwitch -Force -Confirm:$false
}
`
var ps powershell.PowerShellCmd
err := ps.Run(script, switchName)
return err
}
func StartVirtualMachine(vmName string) error {
var script = `
param([string]$vmName)
$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue
if ($vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Off) {
Start-VM -Name $vmName -Confirm:$false
}
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName)
return err
}
func RestartVirtualMachine(vmName string) error {
var script = `
param([string]$vmName)
Restart-VM $vmName -Force -Confirm:$false
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName)
return err
}
func StopVirtualMachine(vmName string) error {
var script = `
param([string]$vmName)
$vm = Get-VM -Name $vmName
if ($vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Running) {
Stop-VM -VM $vm -Force -Confirm:$false
}
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName)
return err
}
func EnableVirtualMachineIntegrationService(vmName string, integrationServiceName string) error {
var script = `
param([string]$vmName,[string]$integrationServiceName)
Enable-VMIntegrationService -VMName $vmName -Name $integrationServiceName
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, integrationServiceName)
return err
}
func SetNetworkAdapterVlanId(switchName string, vlanId string) error {
var script = `
param([string]$networkAdapterName,[string]$vlanId)
Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName $networkAdapterName -Access -VlanId $vlanId
`
var ps powershell.PowerShellCmd
err := ps.Run(script, switchName, vlanId)
return err
}
func SetVirtualMachineVlanId(vmName string, vlanId string) error {
var script = `
param([string]$vmName,[string]$vlanId)
Set-VMNetworkAdapterVlan -VMName $vmName -Access -VlanId $vlanId
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, vlanId)
return err
}
func GetExternalOnlineVirtualSwitch() (string, error) {
var script = `
$adapters = Get-NetAdapter -Physical -ErrorAction SilentlyContinue | Where-Object { $_.Status -eq 'Up' } | Sort-Object -Descending -Property Speed
foreach ($adapter in $adapters) {
$switch = Get-VMSwitch -SwitchType External | Where-Object { $_.NetAdapterInterfaceDescription -eq $adapter.InterfaceDescription }
if ($switch -ne $null) {
$switch.Name
break
}
}
`
var ps powershell.PowerShellCmd
cmdOut, err := ps.Output(script)
if err != nil {
return "", err
}
var switchName = strings.TrimSpace(cmdOut)
return switchName, nil
}
func CreateExternalVirtualSwitch(vmName string, switchName string) error {
var script = `
param([string]$vmName,[string]$switchName)
$switch = $null
$names = @('ethernet','wi-fi','lan')
$adapters = foreach ($name in $names) {
Get-NetAdapter -Physical -Name $name -ErrorAction SilentlyContinue | where status -eq 'up'
}
foreach ($adapter in $adapters) {
$switch = Get-VMSwitch -SwitchType External | where { $_.NetAdapterInterfaceDescription -eq $adapter.InterfaceDescription }
if ($switch -eq $null) {
$switch = New-VMSwitch -Name $switchName -NetAdapterName $adapter.Name -AllowManagementOS $true -Notes 'Parent OS, VMs, WiFi'
}
if ($switch -ne $null) {
break
}
}
if($switch -ne $null) {
Get-VMNetworkAdapter -VMName $vmName | Connect-VMNetworkAdapter -VMSwitch $switch
} else {
Write-Error 'No internet adapters found'
}
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, switchName)
return err
}
func GetVirtualMachineSwitchName(vmName string) (string, error) {
var script = `
param([string]$vmName)
(Get-VMNetworkAdapter -VMName $vmName).SwitchName
`
var ps powershell.PowerShellCmd
cmdOut, err := ps.Output(script, vmName)
if err != nil {
return "", err
}
return strings.TrimSpace(cmdOut), nil
}
func ConnectVirtualMachineNetworkAdapterToSwitch(vmName string, switchName string) error {
var script = `
param([string]$vmName,[string]$switchName)
Get-VMNetworkAdapter -VMName $vmName | Connect-VMNetworkAdapter -SwitchName $switchName
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, switchName)
return err
}
func UntagVirtualMachineNetworkAdapterVlan(vmName string, switchName string) error {
var script = `
param([string]$vmName,[string]$switchName)
Set-VMNetworkAdapterVlan -VMName $vmName -Untagged
Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName $switchName -Untagged
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, switchName)
return err
}
func IsRunning(vmName string) (bool, error) {
var script = `
param([string]$vmName)
$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue
$vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Running
`
var ps powershell.PowerShellCmd
cmdOut, err := ps.Output(script, vmName)
if err != nil {
return false, err
}
var isRunning = strings.TrimSpace(cmdOut) == "True"
return isRunning, err
}
func IsOff(vmName string) (bool, error) {
var script = `
param([string]$vmName)
$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue
$vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Off
`
var ps powershell.PowerShellCmd
cmdOut, err := ps.Output(script, vmName)
if err != nil {
return false, err
}
var isRunning = strings.TrimSpace(cmdOut) == "True"
return isRunning, err
}
func Uptime(vmName string) (uint64, error) {
var script = `
param([string]$vmName)
$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue
$vm.Uptime.TotalSeconds
`
var ps powershell.PowerShellCmd
cmdOut, err := ps.Output(script, vmName)
if err != nil {
return 0, err
}
uptime, err := strconv.ParseUint(strings.TrimSpace(string(cmdOut)), 10, 64)
return uptime, err
}
func Mac(vmName string) (string, error) {
var script = `
param([string]$vmName, [int]$adapterIndex)
try {
$adapter = Get-VMNetworkAdapter -VMName $vmName -ErrorAction SilentlyContinue
$mac = $adapter[$adapterIndex].MacAddress
if($mac -eq $null) {
return ""
}
} catch {
return ""
}
$mac
`
var ps powershell.PowerShellCmd
cmdOut, err := ps.Output(script, vmName, "0")
return cmdOut, err
}
func IpAddress(mac string) (string, error) {
var script = `
param([string]$mac, [int]$addressIndex)
try {
$ip = Get-Vm | %{$_.NetworkAdapters} | ?{$_.MacAddress -eq $mac} | %{$_.IpAddresses[$addressIndex]}
if($ip -eq $null) {
return ""
}
} catch {
return ""
}
$ip
`
var ps powershell.PowerShellCmd
cmdOut, err := ps.Output(script, mac, "0")
return cmdOut, err
}
func TurnOff(vmName string) error {
var script = `
param([string]$vmName)
$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue
if ($vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Running) {
Stop-VM -Name $vmName -TurnOff -Force -Confirm:$false
}
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName)
return err
}
func ShutDown(vmName string) error {
var script = `
param([string]$vmName)
$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue
if ($vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Running) {
Stop-VM -Name $vmName -Force -Confirm:$false
}
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName)
return err
}
func TypeScanCodes(vmName string, scanCodes string) error {
var script = `
param([string]$vmName, [string]$scanCodes)
#Requires -Version 3
#Requires -RunAsAdministrator
function Get-VMConsole
{
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string] $VMName
)
$ErrorActionPreference = "Stop"
$vm = Get-CimInstance -ComputerName localhost -Namespace "root\virtualization\v2" -ClassName Msvm_ComputerSystem -ErrorAction Ignore -Verbose:$false | where ElementName -eq $VMName | select -first 1
if ($vm -eq $null){
Write-Error ("VirtualMachine({0}) is not found!" -f $VMName)
}
$vmKeyboard = $vm | Get-CimAssociatedInstance -ResultClassName "Msvm_Keyboard" -ErrorAction Ignore -Verbose:$false
if ($vmKeyboard -eq $null){
Write-Error ("VirtualMachine({0}) keyboard class is not found!" -f $VMName)
}
#TODO: It may be better using New-Module -AsCustomObject to return console object?
#Console object to return
$console = [pscustomobject] @{
Msvm_ComputerSystem = $vm
Msvm_Keyboard = $vmKeyboard
}
#Need to import assembly to use System.Windows.Input.Key
Add-Type -AssemblyName WindowsBase
#region Add Console Members
$console | Add-Member -MemberType ScriptMethod -Name TypeText -Value {
[OutputType([bool])]
param (
[ValidateNotNullOrEmpty()]
[Parameter(Mandatory)]
[string] $AsciiText
)
$result = $this.Msvm_Keyboard | Invoke-CimMethod -MethodName "TypeText" -Arguments @{ asciiText = $AsciiText }
return (0 -eq $result.ReturnValue)
}
#Define method:TypeCtrlAltDel
$console | Add-Member -MemberType ScriptMethod -Name TypeCtrlAltDel -Value {
$result = $this.Msvm_Keyboard | Invoke-CimMethod -MethodName "TypeCtrlAltDel"
return (0 -eq $result.ReturnValue)
}
#Define method:TypeKey
$console | Add-Member -MemberType ScriptMethod -Name TypeKey -Value {
[OutputType([bool])]
param (
[Parameter(Mandatory)]
[Windows.Input.Key] $Key,
[Windows.Input.ModifierKeys] $ModifierKey = [Windows.Input.ModifierKeys]::None
)
$keyCode = [Windows.Input.KeyInterop]::VirtualKeyFromKey($Key)
switch ($ModifierKey)
{
([Windows.Input.ModifierKeys]::Control){ $modifierKeyCode = [Windows.Input.KeyInterop]::VirtualKeyFromKey([Windows.Input.Key]::LeftCtrl)}
([Windows.Input.ModifierKeys]::Alt){ $modifierKeyCode = [Windows.Input.KeyInterop]::VirtualKeyFromKey([Windows.Input.Key]::LeftAlt)}
([Windows.Input.ModifierKeys]::Shift){ $modifierKeyCode = [Windows.Input.KeyInterop]::VirtualKeyFromKey([Windows.Input.Key]::LeftShift)}
([Windows.Input.ModifierKeys]::Windows){ $modifierKeyCode = [Windows.Input.KeyInterop]::VirtualKeyFromKey([Windows.Input.Key]::LWin)}
}
if ($ModifierKey -eq [Windows.Input.ModifierKeys]::None)
{
$result = $this.Msvm_Keyboard | Invoke-CimMethod -MethodName "TypeKey" -Arguments @{ keyCode = $keyCode }
}
else
{
$this.Msvm_Keyboard | Invoke-CimMethod -MethodName "PressKey" -Arguments @{ keyCode = $modifierKeyCode }
$result = $this.Msvm_Keyboard | Invoke-CimMethod -MethodName "TypeKey" -Arguments @{ keyCode = $keyCode }
$this.Msvm_Keyboard | Invoke-CimMethod -MethodName "ReleaseKey" -Arguments @{ keyCode = $modifierKeyCode }
}
$result = return (0 -eq $result.ReturnValue)
}
#Define method:Scancodes
$console | Add-Member -MemberType ScriptMethod -Name TypeScancodes -Value {
[OutputType([bool])]
param (
[Parameter(Mandatory)]
[byte[]] $ScanCodes
)
$result = $this.Msvm_Keyboard | Invoke-CimMethod -MethodName "TypeScancodes" -Arguments @{ ScanCodes = $ScanCodes }
return (0 -eq $result.ReturnValue)
}
#Define method:ExecCommand
$console | Add-Member -MemberType ScriptMethod -Name ExecCommand -Value {
param (
[Parameter(Mandatory)]
[string] $Command
)
if ([String]::IsNullOrEmpty($Command)){
return
}
$console.TypeText($Command) > $null
$console.TypeKey([Windows.Input.Key]::Enter) > $null
#sleep -Milliseconds 100
}
#Define method:Dispose
$console | Add-Member -MemberType ScriptMethod -Name Dispose -Value {
$this.Msvm_ComputerSystem.Dispose()
$this.Msvm_Keyboard.Dispose()
}
#endregion
return $console
}
$vmConsole = Get-VMConsole -VMName $vmName
$scanCodesToSend = ''
$scanCodes.Split(' ') | %{
$scanCode = $_
if ($scanCode.StartsWith('wait')){
$timeToWait = $scanCode.Substring(4)
if (!$timeToWait){
$timeToWait = "10"
}
Start-Sleep -s $timeToWait
if ($scanCodesToSend){
$scanCodesToSendByteArray = [byte[]]@($scanCodesToSend.Split(' ') | %{"0x$_"})
$scanCodesToSendByteArray | %{
$vmConsole.TypeScancodes($_)
}
}
$scanCodesToSend = ''
} else {
if ($scanCodesToSend){
$scanCodesToSend = "$scanCodesToSend $scanCode"
} else {
$scanCodesToSend = "$scanCode"
}
}
}
if ($scanCodesToSend){
$scanCodesToSendByteArray = [byte[]]@($scanCodesToSend.Split(' ') | %{"0x$_"})
$scanCodesToSendByteArray | %{
$vmConsole.TypeScancodes($_)
}
}
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, scanCodes)
return err
}