2015-06-21 07:36:07 -04:00
package hyperv
import (
"github.com/mitchellh/packer/powershell"
2015-10-30 04:23:30 -04:00
"strconv"
2015-06-21 07:36:07 -04:00
"strings"
)
2015-06-27 17:36:39 -04:00
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 ) {
2015-10-25 18:28:01 -04:00
return @ ( $ HostNetAdapterConfiguration . IpAddress ) [ $ addressIndex ]
2015-06-27 17:36:39 -04:00
}
}
}
return $ false
`
var ps powershell . PowerShellCmd
cmdOut , err := ps . Output ( script , switchName , "0" )
return cmdOut , err
}
2015-06-21 07:36:07 -04:00
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
}
2015-10-30 04:23:30 -04:00
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
}
2015-11-01 11:00:56 -05:00
func MountDvdDrive ( vmName string , path string , controllerNumber uint , controllerLocation uint ) error {
2015-10-30 04:23:30 -04:00
var script = `
param ( [ string ] $ vmName , [ string ] $ path , [ string ] $ controllerNumber , [ string ] $ controllerLocation )
2015-11-01 11:00:56 -05:00
$ vmDvdDrive = Get - VMDvdDrive - VMName $ vmName - ControllerNumber $ controllerNumber - ControllerLocation $ controllerLocation
if ( ! $ vmDvdDrive ) { throw ' unable to find dvd drive ' }
Set - VMDvdDrive - VMName $ vmName - ControllerNumber $ controllerNumber - ControllerLocation $ controllerLocation - Path $ path
2015-10-30 04:23:30 -04:00
`
var ps powershell . PowerShellCmd
err := ps . Run ( script , vmName , path , strconv . FormatInt ( int64 ( controllerNumber ) , 10 ) , strconv . FormatInt ( int64 ( controllerLocation ) , 10 ) )
return err
}
2015-11-01 11:00:56 -05:00
func UnmountDvdDrive ( vmName string , controllerNumber uint , controllerLocation uint ) error {
2015-06-21 07:36:07 -04:00
var script = `
2015-11-01 11:00:56 -05:00
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 - VMDvdDrive - VMName $ vmName - ControllerNumber $ controllerNumber - ControllerLocation $ controllerLocation - Path $ null
2015-06-21 07:36:07 -04:00
`
var ps powershell . PowerShellCmd
2015-11-01 11:00:56 -05:00
err := ps . Run ( script , vmName , strconv . FormatInt ( int64 ( controllerNumber ) , 10 ) , strconv . FormatInt ( int64 ( controllerLocation ) , 10 ) )
2015-06-21 07:36:07 -04:00
return err
}
2015-10-30 13:19:25 -04:00
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 {
2015-10-30 04:23:30 -04:00
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
2015-10-30 13:19:25 -04:00
err := ps . Run ( script , vmName , strconv . FormatInt ( int64 ( controllerNumber ) , 10 ) , strconv . FormatInt ( int64 ( controllerLocation ) , 10 ) )
2015-10-30 04:23:30 -04:00
return err
}
2015-06-21 07:36:07 -04:00
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
}
2015-10-30 04:23:30 -04:00
func CreateVirtualMachine ( vmName string , path string , ram int64 , diskSize int64 , switchName string , generation uint ) error {
2015-06-21 07:36:07 -04:00
2015-10-30 04:23:30 -04:00
if generation == 2 {
2015-06-29 16:18:25 -04:00
var script = `
2015-06-22 17:26:06 -04:00
param ( [ string ] $ vmName , [ string ] $ path , [ long ] $ memoryStartupBytes , [ long ] $ newVHDSizeBytes , [ string ] $ switchName , [ int ] $ generation )
2015-06-21 07:36:07 -04:00
$ vhdx = $ vmName + ' . vhdx '
$ vhdPath = Join - Path - Path $ path - ChildPath $ vhdx
2015-06-21 14:35:32 -04:00
New - VM - Name $ vmName - Path $ path - MemoryStartupBytes $ memoryStartupBytes - NewVHDPath $ vhdPath - NewVHDSizeBytes $ newVHDSizeBytes - SwitchName $ switchName - Generation $ generation
2015-06-21 07:36:07 -04:00
`
2015-06-29 16:18:25 -04:00
var ps powershell . PowerShellCmd
2015-10-30 04:23:30 -04:00
err := ps . Run ( script , vmName , path , strconv . FormatInt ( ram , 10 ) , strconv . FormatInt ( diskSize , 10 ) , switchName , strconv . FormatInt ( int64 ( generation ) , 10 ) )
2015-06-29 16:18:25 -04:00
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
2015-10-30 04:23:30 -04:00
err := ps . Run ( script , vmName , path , strconv . FormatInt ( ram , 10 ) , strconv . FormatInt ( diskSize , 10 ) , switchName )
2015-06-29 16:18:25 -04:00
return err
}
2015-06-21 14:35:32 -04:00
}
2015-10-30 04:23:30 -04:00
func SetVirtualMachineCpu ( vmName string , cpu uint ) error {
2015-06-21 14:35:32 -04:00
var script = `
2015-06-22 17:26:06 -04:00
param ( [ string ] $ vmName , [ int ] $ cpu )
Set - VMProcessor - VMName $ vmName - Count $ cpu
2015-06-21 14:35:32 -04:00
`
var ps powershell . PowerShellCmd
2015-10-30 04:23:30 -04:00
err := ps . Run ( script , vmName , strconv . FormatInt ( int64 ( cpu ) , 10 ) )
2015-06-21 07:36:07 -04:00
return err
}
2015-06-29 16:18:25 -04:00
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
}
2015-06-21 07:36:07 -04:00
func DeleteVirtualMachine ( vmName string ) error {
var script = `
param ( [ string ] $ vmName )
2015-06-24 14:52:42 -04:00
$ vm = Get - VM - Name $ vmName
if ( ( $ vm . State - ne [ Microsoft . HyperV . PowerShell . VMState ] : : Off ) - and ( $ vm . State - ne [ Microsoft . HyperV . PowerShell . VMState ] : : OffCritical ) ) {
2015-06-27 17:36:39 -04:00
Stop - VM - VM $ vm - TurnOff - Force - Confirm : $ false
2015-06-24 14:52:42 -04:00
}
2015-07-14 02:51:03 -04:00
Remove - VM - Name $ vmName - Force - Confirm : $ false
2015-06-21 07:36:07 -04:00
`
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
}
2015-06-27 17:36:39 -04:00
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
}
2015-06-21 07:36:07 -04:00
func CopyExportedVirtualMachine ( expPath string , outputPath string , vhdDir string , vmDir string ) error {
var script = `
param ( [ string ] $ srcPath , [ string ] $ dstPath , [ string ] $ vhdDirName , [ string ] $ vmDir )
2015-07-16 15:48:08 -04:00
Move - Item - Path $ srcPath / * . * - Destination $ dstPath
Move - Item - Path $ srcPath / $ vhdDirName - Destination $ dstPath
Move - Item - Path $ srcPath / $ vmDir - Destination $ dstPath
2015-06-21 07:36:07 -04:00
`
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 ) {
2015-07-14 02:51:03 -04:00
$ switch | Remove - VMSwitch - Force - Confirm : $ false
2015-06-21 07:36:07 -04:00
}
`
var ps powershell . PowerShellCmd
err := ps . Run ( script , switchName )
return err
}
func StartVirtualMachine ( vmName string ) error {
var script = `
param ( [ string ] $ vmName )
2015-06-27 17:36:39 -04:00
$ vm = Get - VM - Name $ vmName - ErrorAction SilentlyContinue
if ( $ vm . State - eq [ Microsoft . HyperV . PowerShell . VMState ] : : Off ) {
2015-07-14 02:51:03 -04:00
Start - VM - Name $ vmName - Confirm : $ false
2015-06-27 17:36:39 -04:00
}
2015-06-21 07:36:07 -04:00
`
var ps powershell . PowerShellCmd
err := ps . Run ( script , vmName )
return err
}
func RestartVirtualMachine ( vmName string ) error {
var script = `
param ( [ string ] $ vmName )
2015-07-14 02:51:03 -04:00
Restart - VM $ vmName - Force - Confirm : $ false
2015-06-21 07:36:07 -04:00
`
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 ) {
2015-10-26 20:12:41 -04:00
Stop - VM - VM $ vm - Force - Confirm : $ false
2015-06-21 07:36:07 -04:00
}
`
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 ) {
2015-06-27 17:36:39 -04:00
Get - VMNetworkAdapter - VMName $ vmName | Connect - VMNetworkAdapter - VMSwitch $ switch
2015-06-21 07:36:07 -04:00
} 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 )
2015-06-27 17:36:39 -04:00
Get - VMNetworkAdapter - VMName $ vmName | Connect - VMNetworkAdapter - SwitchName $ switchName
2015-06-21 07:36:07 -04:00
`
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 )
2015-10-30 04:23:30 -04:00
if err != nil {
return false , err
}
2015-06-21 07:36:07 -04:00
var isRunning = strings . TrimSpace ( cmdOut ) == "True"
return isRunning , err
}
2015-10-30 04:23:30 -04:00
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
}
2015-06-21 07:36:07 -04:00
func Mac ( vmName string ) ( string , error ) {
var script = `
2015-06-22 17:26:06 -04:00
param ( [ string ] $ vmName , [ int ] $ adapterIndex )
2015-06-21 07:36:07 -04:00
try {
$ adapter = Get - VMNetworkAdapter - VMName $ vmName - ErrorAction SilentlyContinue
2015-06-22 17:26:06 -04:00
$ mac = $ adapter [ $ adapterIndex ] . MacAddress
2015-06-21 07:36:07 -04:00
if ( $ mac - eq $ null ) {
2015-06-22 17:26:06 -04:00
return ""
2015-06-21 07:36:07 -04:00
}
} catch {
2015-06-22 17:26:06 -04:00
return ""
2015-06-21 07:36:07 -04:00
}
$ 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 ) {
2015-06-22 17:26:06 -04:00
return ""
2015-06-21 07:36:07 -04:00
}
} catch {
2015-06-22 17:26:06 -04:00
return ""
2015-06-21 07:36:07 -04:00
}
$ ip
`
var ps powershell . PowerShellCmd
cmdOut , err := ps . Output ( script , mac , "0" )
return cmdOut , err
}
2015-06-27 17:36:39 -04:00
func TurnOff ( vmName string ) error {
2015-06-21 07:36:07 -04:00
var script = `
param ( [ string ] $ vmName )
$ vm = Get - VM - Name $ vmName - ErrorAction SilentlyContinue
2015-06-27 17:36:39 -04:00
if ( $ vm . State - eq [ Microsoft . HyperV . PowerShell . VMState ] : : Running ) {
2015-10-26 20:12:41 -04:00
Stop - VM - Name $ vmName - TurnOff - Force - Confirm : $ false
2015-06-21 07:36:07 -04:00
}
`
var ps powershell . PowerShellCmd
err := ps . Run ( script , vmName )
return err
}
2015-06-27 17:36:39 -04:00
func ShutDown ( vmName string ) error {
2015-06-21 07:36:07 -04:00
var script = `
param ( [ string ] $ vmName )
$ vm = Get - VM - Name $ vmName - ErrorAction SilentlyContinue
if ( $ vm . State - eq [ Microsoft . HyperV . PowerShell . VMState ] : : Running ) {
2015-10-26 20:12:41 -04:00
Stop - VM - Name $ vmName - Force - Confirm : $ false
2015-06-21 07:36:07 -04:00
}
`
var ps powershell . PowerShellCmd
err := ps . Run ( script , vmName )
return err
}
2015-06-27 17:36:39 -04:00
func TypeScanCodes ( vmName string , scanCodes string ) error {
2015-06-21 07:36:07 -04:00
var script = `
2015-06-27 17:36:39 -04:00
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 ( $ _ )
}
}
2015-06-21 07:36:07 -04:00
`
var ps powershell . PowerShellCmd
2015-06-27 17:36:39 -04:00
err := ps . Run ( script , vmName , scanCodes )
2015-06-21 07:36:07 -04:00
return err
}