예제 #1
0
파일: hyperv.go 프로젝트: vvchik/packer
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
}
예제 #2
0
파일: hyperv.go 프로젝트: vvchik/packer
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
}
예제 #3
0
파일: hyperv.go 프로젝트: vvchik/packer
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
}
예제 #4
0
파일: hyperv.go 프로젝트: vvchik/packer
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
}
예제 #5
0
파일: hyperv.go 프로젝트: vvchik/packer
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
}
예제 #6
0
파일: hyperv.go 프로젝트: vvchik/packer
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
}
예제 #7
0
파일: hyperv.go 프로젝트: vvchik/packer
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
}
예제 #8
0
파일: hyperv.go 프로젝트: vvchik/packer
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
}
예제 #9
0
파일: hyperv.go 프로젝트: vvchik/packer
func SetVirtualMachineCpu(vmName string, cpu string) error {

	var script = `
param([string]$vmName, [int]$cpu)
Set-VMProcessor -VMName $vmName -Count $cpu
`

	var ps powershell.PowerShellCmd
	err := ps.Run(script, vmName, cpu)
	return err
}
예제 #10
0
파일: hyperv.go 프로젝트: vvchik/packer
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
}
예제 #11
0
파일: hyperv.go 프로젝트: vvchik/packer
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
}
예제 #12
0
파일: hyperv.go 프로젝트: vvchik/packer
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
}
예제 #13
0
파일: hyperv.go 프로젝트: vvchik/packer
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
}
예제 #14
0
파일: hyperv.go 프로젝트: vvchik/packer
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 -Confirm:$false
}
`

	var ps powershell.PowerShellCmd
	err := ps.Run(script, vmName)
	return err
}
예제 #15
0
파일: hyperv.go 프로젝트: vvchik/packer
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 -Confirm:$false
}
`

	var ps powershell.PowerShellCmd
	err := ps.Run(script, vmName)
	return err
}
예제 #16
0
파일: hyperv.go 프로젝트: vvchik/packer
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
}
예제 #17
0
파일: hyperv.go 프로젝트: vvchik/packer
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 (s *StepUnmountSecondaryDvdImages) Run(state multistep.StateBag) multistep.StepAction {
	ui := state.Get("ui").(packer.Ui)
	ui.Say("Unmounting Integration Services Setup Disk...")

	vmName := state.Get("vmName").(string)

	// todo: should this message say removing the dvd?

	dvdProperties := state.Get("secondary.dvd.properties").([]DvdControllerProperties)

	log.Println(fmt.Sprintf("Found DVD properties %s", len(dvdProperties)))

	for _, dvdProperty := range dvdProperties {
		controllerNumber := dvdProperty.ControllerNumber
		controllerLocation := dvdProperty.ControllerLocation

		var script powershell.ScriptBuilder
		powershell := new(powershell.PowerShellCmd)

		script.WriteLine("param([string]$vmName,[int]$controllerNumber,[int]$controllerLocation)")
		script.WriteLine("$vmDvdDrive = Get-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation")
		script.WriteLine("if (!$vmDvdDrive) {throw 'unable to find dvd drive'}")
		script.WriteLine("Remove-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation")
		err := powershell.Run(script.String(), vmName, controllerNumber, controllerLocation)
		if err != nil {
			state.Put("error", err)
			ui.Error(err.Error())
			return multistep.ActionHalt
		}
	}

	return multistep.ActionContinue
}
func (s *StepUpdateIntegrationServices) mountIntegrationServicesSetupDisk(vmName string) (dvdDriveProperties, error) {

	var dvdProperties dvdDriveProperties

	var script powershell.ScriptBuilder
	script.WriteLine("param([string]$vmName)")
	script.WriteLine("Add-VMDvdDrive -VMName $vmName")

	powershell := new(powershell.PowerShellCmd)
	err := powershell.Run(script.String(), vmName)
	if err != nil {
		return dvdProperties, err
	}

	script.Reset()
	script.WriteLine("param([string]$vmName)")
	script.WriteLine("(Get-VMDvdDrive -VMName $vmName | Where-Object {$_.Path -eq $null}).ControllerLocation")
	controllerLocation, err := powershell.Output(script.String(), vmName)
	if err != nil {
		return dvdProperties, err
	}

	script.Reset()
	script.WriteLine("param([string]$vmName)")
	script.WriteLine("(Get-VMDvdDrive -VMName $vmName | Where-Object {$_.Path -eq $null}).ControllerNumber")
	controllerNumber, err := powershell.Output(script.String(), vmName)
	if err != nil {
		return dvdProperties, err
	}

	isoPath := os.Getenv("WINDIR") + "\\system32\\vmguest.iso"

	script.Reset()
	script.WriteLine("param([string]$vmName,[string]$path,[string]$controllerNumber,[string]$controllerLocation)")
	script.WriteLine("Set-VMDvdDrive -VMName $vmName -Path $path -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation")

	err = powershell.Run(script.String(), vmName, isoPath, controllerNumber, controllerLocation)
	if err != nil {
		return dvdProperties, err
	}

	dvdProperties.ControllerNumber = controllerNumber
	dvdProperties.ControllerLocation = controllerLocation

	return dvdProperties, err
}
예제 #20
0
파일: hyperv.go 프로젝트: vvchik/packer
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 (s *StepUpdateIntegrationServices) Cleanup(state multistep.StateBag) {
	vmName := state.Get("vmName").(string)

	var script powershell.ScriptBuilder
	script.WriteLine("param([string]$vmName)")
	script.WriteLine("Set-VMDvdDrive -VMName $vmName -Path $null")

	powershell := new(powershell.PowerShellCmd)
	_ = powershell.Run(script.String(), vmName)
}
예제 #22
0
func (s *StepMountDvdDrive) Run(state multistep.StateBag) multistep.StepAction {
	//driver := state.Get("driver").(Driver)
	ui := state.Get("ui").(packer.Ui)

	errorMsg := "Error mounting dvd drive: %s"
	vmName := state.Get("vmName").(string)
	isoPath := s.RawSingleISOUrl

	// Check that there is a virtual dvd drive
	var script powershell.ScriptBuilder
	powershell := new(powershell.PowerShellCmd)

	script.Reset()
	script.WriteLine("param([string]$vmName)")
	script.WriteLine("(Get-VMDvdDrive -VMName $vmName).ControllerNumber")
	controllerNumber, err := powershell.Output(script.String(), vmName)
	if err != nil {
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}

	if controllerNumber == "" {
		// Add a virtual dvd drive as there is none
		script.Reset()
		script.WriteLine("param([string]$vmName)")
		script.WriteLine("Add-VMDvdDrive -VMName $vmName")
		script.WriteLine("$dvdDrive = Get-VMDvdDrive -VMName $vmName | Select-Object -first 1")
		script.WriteLine("Set-VMFirmware -VMName $vmName -FirstBootDevice $dvdDrive")
		err = powershell.Run(script.String(), vmName)
		if err != nil {
			state.Put("error", err)
			ui.Error(err.Error())
			return multistep.ActionHalt
		}
	}

	ui.Say("Mounting dvd drive...")

	err = hyperv.MountDvdDrive(vmName, isoPath)
	if err != nil {
		err := fmt.Errorf(errorMsg, err)
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}

	s.path = isoPath

	return multistep.ActionContinue
}
예제 #23
0
파일: hyperv.go 프로젝트: vvchik/packer
func CreateVirtualMachine(vmName string, path string, ram string, diskSize string, switchName string, generation string) 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, ram, diskSize, switchName, generation)
		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, ram, diskSize, switchName)
		return err
	}
}
func (s *StepMountSecondaryDvdImages) addAndMountDvdDisk(vmName string, isoPath string) (DvdControllerProperties, error) {

	var properties DvdControllerProperties
	var script powershell.ScriptBuilder
	powershell := new(powershell.PowerShellCmd)

	controllerNumber := "0"
	if s.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.Reset()
		script.WriteLine("param([string]$vmName)")
		script.WriteLine("$dvdDrives = (Get-VMDvdDrive -VMName $vmName)")
		script.WriteLine("$lastControllerNumber = $dvdDrives | Sort-Object ControllerNumber | Select-Object -Last 1 | %{$_.ControllerNumber}")
		script.WriteLine("if (!$lastControllerNumber) {")
		script.WriteLine("	$lastControllerNumber = 0")
		script.WriteLine("} elseif (!$lastControllerNumber -or ($dvdDrives | ?{ $_.ControllerNumber -eq $lastControllerNumber} | measure).count -gt 1) {")
		script.WriteLine("	$lastControllerNumber += 1")
		script.WriteLine("}")
		script.WriteLine("$lastControllerNumber")
		controllerNumber, err := powershell.Output(script.String(), vmName)
		if err != nil {
			return properties, err
		}

		if controllerNumber != "0" || controllerNumber != "1" {
			//There are only 2 ide controllers, try to use the one the hdd is attached too
			controllerNumber = "0"
		}
	}

	script.Reset()
	script.WriteLine("param([string]$vmName,[int]$controllerNumber)")
	script.WriteLine("Add-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber")
	err := powershell.Run(script.String(), vmName, controllerNumber)
	if err != nil {
		return properties, 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.Reset()
	script.WriteLine("param([string]$vmName)")
	script.WriteLine("(Get-VMDvdDrive -VMName $vmName | Where-Object {$_.Path -eq $null}).ControllerLocation")
	controllerLocation, err := powershell.Output(script.String(), vmName)
	if err != nil {
		return properties, err
	}

	script.Reset()
	script.WriteLine("param([string]$vmName,[string]$path,[string]$controllerNumber,[string]$controllerLocation)")
	script.WriteLine("Set-VMDvdDrive -VMName $vmName -Path $path -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation")

	err = powershell.Run(script.String(), vmName, isoPath, controllerNumber, controllerLocation)
	if err != nil {
		return properties, err
	}

	log.Println(fmt.Sprintf("ISO %s mounted on DVD controller %v, location %v", isoPath, controllerNumber, controllerLocation))

	properties.ControllerNumber = controllerNumber
	properties.ControllerLocation = controllerLocation

	return properties, nil
}
예제 #25
0
파일: hyperv.go 프로젝트: vvchik/packer
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
}