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
cls
write-host "Please follow the prompts for the deployment script"
#Deployment Script
start-transcript
#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...."
}
}
else
{
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
}
else
{
write-error "Please Empty Directory before continuing. script will now exit"
exit 0
}
}
}
else
{
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
}
else
{
write-host "Free space is greater than lab size"
}
cls
#phase 6 copy image to server
$files = get-childitem $labloc -recurse
$file = get-childitem $labloc -recurse -name
$counter=0
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)
}
else
{
Copy-Item $restpath $destpath -Force
}
$counter++
}
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
$folder
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";
exit;
}
$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);
}
stop-transcript
Comments
- Anonymous
November 23, 2011
Hi John, Great job, you are awesome. Thanks!