Powershell Script – Deploying Exported VM’s for training labs

In my previous job i had to deploy a lot of labs, and since i worked full time in there i didnt really both with beginning to automate the process, well i dont have the time anymore so i need to start 🙂

this is part 1 of the script which will deploy the lab which i store on a central share.....

basically the script is written for Windows 2008 R2

it should

1. Check for hyper-v and install if not present

2. prompt you for the share location of the exported VM's

3. prompt you for how many virtual networks you want to create

4. prompt you for the name of the virtual networks you want to create

5. prompt you for the location you want to store the vm's on the local host

6. check free disk space before attempting to copy the labs

7. copy the labs

8. create the virtual networks

9. import the VM's

part 2 will be around cleaning the host up which i will be posting in a few days 🙂


here is the code!


# Author: John McCabe
# Email: johm@microsoft.com
# Twitter: @mccabej

write-host "Please follow the prompts for the deployment script"

#Deployment Script

#Phase 1 Check if hyper-v is enabled

import-module servermanager
$isinstalled = Get-WindowsFeature |where {$_.Name -eq "Hyper-V"}

if ($isinstalled.installed -eq $False)

 write-warning "Hyper-V Not Installed -Installation will requier a reboot"
 $answer = read-host "Do you want to install now press Y/N and then enter"
 if ($answer = "y")
    Add-WindowsFeature -Name Hyper-V
        elseif ($answer = "n")
           write-error "Hyper-V Needs to be installed before continuing, script will exit...."
 write-host "Hyper-V Installed" -foregroundcolor green -backgroundcolor black



#Phase 2 Prompt For Location of the labs (UNC Path)

$Labloc = Read-host "Please Enter The Full UNC Path to the share where the exported VM's are located"

#Phase 3 Prompt for Virtual Networks required

$noofvtnet = Read-host "Please Enter the number of virtual networks you want to create and press enter"
write-verbose "`nAll Virtual Networks will be created as Internal"

for ($count=1;$count -le $noofvtnet;$count++)
 [array]$vtnetnames+= Read-host "Please Enter Network Name and press enter"


#Phase 4 Prompt for location on hyper-v server

$vmstoreloc = Read-host "Please Enter the path on the local machine you want to store the VM's"

write-verbose "Checking if specified path exists"
$testvmstoreloc = test-path $vmstoreloc

if ($testvmstoreloc -eq $true)
  write-host "Directory $vmstoreloc already exists"
  $checkspaceobj = new-object -com scripting.filesystemobject
  $size = "{0:N2}" -f (($checkspaceobj.Getfolder("$vmstoreloc").size) / 1MB)
  if ($size -gt 0)
 write-host "Directory is not empty"
 $deletedir= read-host "Do you wish to delete and re-initialize press Y or N and then Enter"
 if ($deletedir -eq "Y")
     write-host "Emptying Directory Contents....."
  get-childitem $vmstoreloc |remove-item -recurse -force
  write-error "Please Empty Directory before continuing. script will now exit"
  exit 0
 write-host "Creating Directory..."
 $createstore = new-item -type directory -path $vmstoreloc
 if ($? -eq $true)
  write-host "Directory Created Successfully"

#Phase 5 Check Share Size Versus Free Space on Disk

$Sharespaceobj = new-object -com scripting.filesystemobject
[int32]$sharesize = "{0:N2}" -f (($sharespaceobj.Getfolder("$labloc").size) / 1MB)

$vmstorelocdrive = $vmstoreloc.split("\")
$vmstorelocdrive = $vmstorelocdrive[0]
$driveFS = get-wmiobject -class Win32_LogicalDisk |where {$_.DeviceID -eq $vmstorelocdrive}
[int32]$freespace = "{0:N2}" -f (($drivefs.freespace)/1MB)

if ($sharesize -gt $freespace)
 write-error "there is not enough space on the harddrive, please clean up space... script exitings.."
 exit 0
 write-host "Free space is greater than lab size"


#phase 6 copy image to server

$files = get-childitem $labloc -recurse
$file = get-childitem $labloc -recurse -name


foreach ($file in $files)
 $status = "copy files {0} on {1}: {2}" -f $counter,$files.count,$file.name
 write-progress -activity "Copying..." $status -percentcomplete ($counter/$files.count*100)
 $temprestpath = $file.fullname.replace($labloc,"")
 $restpath = $labloc + $temprestpath
 [string]$destpath = $restpath
 $destpath = $destpath.trimstart("\")
 $destpath = $vmstoreloc + "\" + $destpath
 if($file.PSIsContainer -eq $true)  
         new-item -type directory ($vmstoreloc+$restpath)      
        Copy-Item $restpath $destpath -Force      
if ($counter = $files.count)
 write-host "Copy Completed"

#phase 7 create virtual nics

$HyperVServer = "localhost"

foreach ($vt in $vtnetnames)
 $SwitchFriendlyName = $vt
 $nternalEthernetPortFriendlyName = $SwitchFriendlyName
 $InternalSwitchPortFriendlyName = "InternalSwitchPort"
 $SwitchName = [guid]::NewGuid().ToString()
 $InternalSwitchPortName = [guid]::NewGuid().ToString()
 $InternalEthernetPortName = [guid]::NewGuid().ToString()
 $NumLearnableAddresses = 1024
 $ScopeOfResidence = ""
 $VirtualSwitchManagementService = gwmi Msvm_VirtualSwitchManagementService -namespace "root\virtualization" -computername $HyperVServer
 $Result = $VirtualSwitchManagementService.CreateSwitch($SwitchName, $SwitchFriendlyName, $NumLearnableAddresses, $ScopeOfResidence)
 $Switch = [WMI]$Result.CreatedVirtualSwitch
 $Result = $VirtualSwitchManagementService.CreateSwitchPort($Switch, $InternalSwitchPortName, $InternalSwitchPortFriendlyName, $ScopeOfResidence)
 $InternalSwitchPort = [WMI]$Result.CreatedSwitchPort
 $Result = $VirtualSwitchManagementService.CreateInternalEthernetPortDynamicMac($InternalEthernetPortName, $InternalEthernetPortFriendlyName)
 $InternalEthernetPort = [WMI]$Result.CreatedInternalEthernetPort
 $query = "Associators of {$InternalEthernetPort} Where ResultClass=CIM_LanEndpoint"
 $InternalLanEndPoint = gwmi -namespace root\virtualization -query $query -computername $HyperVServer
 $Result = $VirtualSwitchManagementService.ConnectSwitchPort($InternalSwitchPort, $InternalLanEndPoint)


#phase 8 import VM's

$labloc = $labloc.split("\")
$server = $labloc[2]
$share = $labloc[3]
$folder = $vmstoreloc + "\" + $server + "\" + $share
sleep 10
$importFolder = $folder

if ([IO.Directory]::Exists($importFolder) -eq $False)
     Write-Host -foregroundColor red "Import folder $($importFolder) does not exist. Please check the folder and ensure it exists";

$VMFolders = get-childitem -path $importFolder
$VM_Service = gwmi -namespace root\virtualization -class Msvm_VirtualSystemManagementService
foreach ($VMFolder in $VMFolders)
    Write-Host "Importing $($VMFolder) from $($VMFolder.FullName)...";
    $status = $VM_Service.ImportVirtualSystem($VMFolder.FullName, $False);





Comments (1)

  1. Patris_70 says:

    Hi John,

    Great job, you are awesome.


Skip to main content