Uma das coisas que eu acho entediante é montar laboratório para testes. Digo, no sentido de criar os servidores um a um, pois é uma tarefa demorada e trabalhosa. Muitos colegas utilizam o VMM (Virtual Machine Manager) em seus ambientes para facilitar nessa atividade e acho que é a solução ideal. Entretanto, nem sempre tenho disponível o VMM no ambiente do cliente e precisava de algo mais simples para montar várias máquinas virtuais de uma só vez. Então resolvi montar um script para facilitar a minha vida. Geralmente precisamos montar vários servidores de uma só vez. Dado isso, o script lê um arquivo CSV que define as configurações mínimas das máquinas virtuais que serão montadas.
IMPORTANTE - O script utiliza o modulo HyperV, que pode ser obtido em http://www.codeplex.com/psHyperV. Lá tem toda a informação de como instalar o módulo no computador onde o script vai rodar.
Abaixo a estrutura do arquivo CSV com três exemplos que irei comentar:
Name,CPU,Memory,NetName,IDEDisk,VHDParentLAB01,4,4096,Rede Dados,W7Test.VHD,,LAB02,1,1024,Rede Publica,new,,LAB03,2,2048,Rede Dados,new,G:\VMs\Parent\parent.vhd#LAB04,1,1024,Rede Dados,new,
O CSV tem 5 campos: Nome, CPU - quantidade de CPU, Memory - quantidade de memória em MB, NetName - nome da rede Hyper-V em que vai ser conectado, IDEDisk - Disco IDE que vai ser configurado na máquina virtual e por último VHDParent - o VHD do parente caso você escolha usar um diferential disk.
Analisando os registros do exemplo acima consigo explicar o funcionamento do script.
LAB01 – Quando fizer uma referência a um arquivo VHD explicitamente no campo IDEDisk, como na linha do LAB01, o mesmo deve existir no diretório padrão, dentro de um subdiretório com o mesmo nome da máquina virtual. Por exemplo, o VHD do LAB01, tendo como premissa o diretório padrão G:\VMs, deve estar em G:\VMs\LAB01\W7Test.VHD. Esse é o caso de quando você criar uma VM base, faz um sysprep e copia a VM para um ou vários diretórios. A ferramenta mais indicada para copiar arquivos grande é o robocopy. Eu fiz um .bat que copia tudo que eu preciso, mas a estrutura principal é a linha abaixo: robocopy [Diretório de Origem] [Diretório de Destino] *.vhd /mt:8
LAB02- Para criar um VHD novo basta colocar a palavra new no campo IDEDisk. Neste caso será criado o arquivo G:\VMs\LAB02\LAB-02-DriveC.VHD.
LAB03 – Quando for usar um disco diferencial, a referencia do VHDParent deve conter o caminho completo, pois muitas vezes os arquivos do tipo parente não ficam no mesmos discos que os arquivos das VMs. Caso o nome da rede não corresponda a uma já existente no servidor Hyper-V, ou o arquivo VHD referenciado ou do parent não existam, o script não processa aquele registro e emite uma mensagem de Warning.
LAB04 - Não vai ser processado pois o caracter # na frente do nome diz ao script para pular o registro
Abaixo o script que eu chamei CreateVMs.ps1. Espero que ajude.
Import-Module 'C:\Program Files\modules\HyperV\HyperV.psd1'
Function Check-SwitchName([string]$strName, [string]$strComputerName) {$VirtualServerSwitches = Get-WmiObject -NameSpace "root\virtualization" -Class "MsVM_VirtualSwitch" -ComputerName $strComputerNameforeach ($vmSwitch in $VirtualServerSwitches) { if ($vmSwitch.ElementName -eq $strName) { return $true } }return $false}
function Read-Default([string]$strmessage, [string]$strDefault) { Write-Host $strmessage -NoNewline -ForegroundColor White if ($strDefault.length -gt 0) { Write-Host " [$strDefault] : " -NoNewline -ForegroundColor Yellow } else { Write-Host ": " -NoNewline } $result = Read-Host if ($result.length -eq 0 ) {$result = $strDefault} $result }
[string]$defaultCSV = Get-Location$defaultCSV += "\VMs.csv"$csvFile = Read-Default "Please enter CSV file name" $defaultCSV$fTest = Test-Path $csvFileif ($fTest -eq $false) { Write-Host $csvFile " File not found" -ForegroundColor Red -BackgroundColor black Exit (1)}$strHostName = hostname$VMHost = Read-Default "Please enter Hyper-V hostname" $strHostName
$strMachines = Import-CSV $csvFile
foreach ($strVm in $strMachines){ $vmName = $strVm.Name $vmCPU = $strVm.CPU $vmMemory = $strVm.Memory $vmNetName = $strVm.NetName $vmIDEDisk = $strVm.IDEDisk $vmVHDParent = $strVm.VHDParent if ($vmName.substring(0,1) -eq "#") { continue } if ($vmName -eq $null -or $vmCPU -eq $null -or $vmMemory -eq $null -or $vmName -eq $null -or $vmIDEDisk -eq $null) { write-host -ForegroundColor yellow -BackgroundColor black "Missing information, skipping record." continue } if ($vmIDEDisk.contains(":")) { write-host write-host -ForegroundColor yellow -BackgroundColor black "Skipping $vmName - Do not specify full path name for IDE disks." continue } $bNew = $false if ($vmIDEDisk.ToLower() -eq "new" ) { $vmIDEDisk = $(get-VHDdefaultPath) + $vmName + "\" + $vmName + "-DriveC.VHD" if ((Test-Path $vmIDEDisk) -eq $true) { Remove-Item $vmIDEDisk } $bNew = $true} else { $vmIDEDisk = $(get-VHDdefaultPath) + $vmName + "\" + $vmIDEDisk if ((Test-Path $vmIDEDisk) -eq $false) { write-host -ForegroundColor yellow -BackgroundColor black "Skipping $vmName - Disk $vmIDEDisk not found" continue } } if ((Check-SwitchName $vmNetName $VMHost) -eq $false) { write-host -ForegroundColor yellow -BackgroundColor black "Skipping $vmName - VirtualSwitch $vmNetName does not exist" continue } $bParent = $false if ($vmVHDParent -ne "" ) { if ($vmVHDParent.IndexOf(":") -lt 1) { write-host -ForegroundColor yellow -BackgroundColor black "Skipping $vmName - Please, specify full path name for VHD parent disk." continue } else { if ((Test-Path $vmVHDParent) -eq $false) { write-host -ForegroundColor yellow -BackgroundColor black "Skipping $vmName - VHDParent $vmVHDParent not found." continue } } $bParent = $true } # create a new virtual machine $vm = New-VM $vmName -server $VMHost Set-VMCPUCount $vmName $vmCPU |Out-Null Set-VMMemory $vmName -Memory $vmMemory |Out-Null Add-vmNIC $vmName $vmNetName |Out-Null if ($bParent -and $bNew) { New-VHD -VHDPaths $vmIDEDisk -ParentVHDPath $vmVHDParent Add-VMDisk $vmName 0 0 -Path $vmIDEDisk } if ($bParent -eq $false -and $bNew) { New-VHD -VHDPaths $vmIDEDisk Add-VMDisk $vmName 0 0 -Path $vmIDEDisk } if ($bParent -eq $false -and $bNew -eq $false) { Add-VMDisk $vmName 0 0 $vmIDEDisk } #Adds a DVD drive to IDE O slot 1 Add-VMDRIVE $vmName -controllerID 0 -lun 1 -DVD }
Artur, show de bola!
Segue um outro link com "PowerShell management library for Hyper-V"
http://pshyperv.codeplex.com/
Abraços.