Install-RemoteVM är ett script för att rulla ut VM’s på olika Hyper-V hostar, remote, automatiserat och med kopplingar till AD, WDS och MDT/MDTDB. Riktar även ett stort tack till Micke Nyström för inspirationen jag hämtat från hans Out Of Band install of Windows Server 2012 R2 Using MDT,WDS and PowerShell inlägg och tillhörande script som gör de samma med fysiska HP servrar. Powershell is king
Eller läsa här:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | <# ############################################################################# # Created: 2014-01-02 # version: v1.0 # Author: Henrik Toft, inspired by the deploymentbunny... # Homepage: http://www.toft.se/ # Disclaimer: This script is provided "AS IS" with no warranties ############################################################################# # # ############################ EXAMPELS ####################################### # Example 1: Script is generating static VM Physical Address Install-RemoteVM -VMName SRV133 -VMRam 2048MB -VMNetwork LAN -VMCpu 1 -VMDiskSize 100GB -VMHost LAB-VMHOST01 -MDTServer LAB-MDT01 -MDTDataBaseInstance ADK -MDTDataBase MDT -TaskSequence WS12R2-01 # Example 2: User specifies static VM Physical Address Install-RemoteVM -VMName SRV134 -VMRam 2048MB -VMNetwork LAN -VMCpu 1 -VMDiskSize 100GB -VMMacAddress "00:15:5A:AA:AA:11" -VMHost LAB-VMHOST01 -MDTServer LAB-MDT01 -MDTDataBaseInstance ADK -MDTDataBase MDT -TaskSequence WS12R2-01 ############################################################################# #> Function Install-RemoteVM{ Param( [parameter(mandatory=$true)][ValidateNotNullOrEmpty()]$VMHost, [parameter(mandatory=$true)][ValidateNotNullOrEmpty()]$VMName, [parameter(mandatory=$true)][ValidateNotNullOrEmpty()]$VMRam, [parameter(mandatory=$true)][ValidateNotNullOrEmpty()]$VMNetwork, [parameter(mandatory=$false)][ValidateNotNullOrEmpty()]$VMMacAddress, [parameter(mandatory=$true)][ValidateNotNullOrEmpty()]$VMCpu, [parameter(mandatory=$true)][ValidateNotNullOrEmpty()]$VMDiskSize, [parameter(mandatory=$true)][ValidateNotNullOrEmpty()]$MDTServer, [parameter(mandatory=$true)][ValidateNotNullOrEmpty()]$MDTDataBaseInstance, [parameter(mandatory=$true)][ValidateNotNullOrEmpty()]$MDTDataBase, [parameter(mandatory=$true)][ValidateNotNullOrEmpty()]$TaskSequence ) ## Check for Hyper-V PowerShell Module if ($(Get-WindowsFeature Hyper-V-PowerShell).InstallState -like "Available") {Install-WindowsFeature Hyper-V-PowerShell -Verbose} ## Check if VM exist $VM = Get-VM $VMName -ComputerName $VmHost -ErrorAction SilentlyContinue if ($VM) { Write-Verbose "$VMName already exist..." -Verbose break } ## Define New-PhysicalAddress Function Function New-PhysicalAddress{ param( [int] $len = 12, [string] $chars = "0123456789ABCFEF" ) $bytes = new-object "System.Byte[]" $len $rnd = new-object System.Security.Cryptography.RNGCryptoServiceProvider $rnd.GetBytes($bytes) $macraw = "" for( $i=0; $i -lt $len; $i++ ) {$macraw += $chars[ $bytes[$i] % $chars.Length ]} $PhysicalAddress = "0"+"0"+":"+"1"+"5"+":"+$macraw[4]+$macraw[5]+":"+$macraw[6]+$macraw[7]+":"+$macraw[8]+$macraw[9]+":"+$macraw[10]+$macraw[11] Write-Output $PhysicalAddress } ## Import modules try {Import-Module "C:\Scripts\MDTDB.psm1" -ErrorAction Stop} catch {Write-Warning "Error occured: $_"} try {Import-Module WDS -ErrorAction Stop} catch {Write-Warning "Error occured: $_"} ## Check if script static mac or user static mac should be used. if ($VMMacAddress) {Write-Host "Static MacAddress: $VMMacAddress was specified by user"} else { $VMMacAddress = New-PhysicalAddress Write-Host "Static MacAddress: $VMMacAddress was specified by script" } # Create VM $VmVhdLocation = (Get-VmHost -ComputerName $VmHost).VirtualHardDiskPath New-VHD -ComputerName $VmHost –Path "$VmVhdLocation\$($VMName).vhdx" -SizeBytes $VMDiskSize -Verbose New-VM -ComputerName $VmHost –Name $VMName –MemoryStartupBytes $VMRam –VHDPath "$VmVhdLocation\$($VMName).vhdx" -SwitchName $VMNetwork -Generation 2 -Verbose Set-VM -ComputerName $VmHost -VmName $VMName -DynamicMemory -ProcessorCount $VMCpu -MemoryMaximumBytes $VMRam -Verbose Set-VMNetworkAdapter -ComputerName $VmHost -VMName $VMName -StaticMacAddress $VMMacAddress -Verbose Write-Verbose "VM $VMName was created" -Verbose # Get/Set Vars $VMidGuid = $(Get-Vm $vmname -ComputerName $VMHost).Id $VMidMac = $VMMacAddress -replace ':','-' # Print Vars Write-Host "VMHost = $VMHost" Write-Host "VMName = $VMName" Write-Host "VMRam = $VMRam" Write-Host "VMNetwork = $VMNetwork" Write-Host "VMMacAddress = $VMMacAddress" Write-Host "VMCpu Count = $VMCpu" Write-Host "VMDiskSize = $VMDiskSize" Write-Host "MDTServer = $MDTServer" Write-Host "MDTDataBaseInstance = $MDTDataBaseInstance" Write-Host "MDTDataBase = $MDTDataBase" Write-Host "TaskSequence = $TaskSequence" Write-Host "GUID = $VMidGuid" Write-Host "VmVhdLocation = $VmVhdLocation" # PreStage in WDS # note to self.. do something about this if if mess.. $WDSComputer = Get-WdsClient -DeviceName $VMName if ($WDSComputer.DeviceName -EQ "$VMName"){ Write-Host "$VMName was found in WDS. Checking MacAddress" if ($WDSComputer.DeviceID -Match "$VMidMac") { Write-Host "Prestaged in WDS. DeviceName and MacAddress are correct" -ForegroundColor Yellow } else{ Write-Host "Reinstating in WDS, adding" -ForegroundColor Yellow Remove-WdsClient -DeviceName $VMName Sleep -Seconds 1 New-WdsClient -DeviceID $VMidMac -DeviceName $VMName -PxePromptPolicy OptOut -BootImagePath "Boot\x64\Images\LiteTouchPE_x64.wim" -ErrorAction Stop -JoinDomain $false } } else { Write-Host "$VMname is not prestaged in WDS, adding" New-WdsClient -DeviceID $VMidMac -DeviceName $VMName -PxePromptPolicy OptOut -BootImagePath "Boot\x64\Images\LiteTouchPE_x64.wim" -ErrorAction Stop -JoinDomain $false } # Prestage in MDT connect-mdtdatabase -sqlserver $MDTServer -instance $MDTDataBaseInstance -database $MDTDataBase -Verbose $MDTComputerSettings = @{OSInstall='YES';OSDComputerName="$VMName";TaskSequenceID="$TaskSequence";SkipTaskSequence='YES';SkipComputerName='YES';SkipApplications='YES';SkipDomainMembership='YES'} Write-Host "Checking $VMMacAddress" $MDTComputer = Get-MDTComputer | Where-Object -Property "MacAddress" -Like -Value $VMMacAddress if ($MDTComputer.MacAddress -EQ "$VMMacAddress") { Write-Host "Prestaged in DB" Write-Host "Update record" Set-MDTComputer -id $MDTComputer.ID -settings $MDTComputerSettings } else { Write-Host "Not Prestaged in DB" New-MDTComputer -macAddress $VMMacAddress -description $VMName -settings $MDTComputerSettings } # Start VM Start-Vm -ComputerName $vmhost -Name $vmname -Verbose } # SCRIPT MAC #Install-RemoteVM -VMName SRV133 -VMRam 1024MB -VMNetwork LAN -VMCpu 1 -VMDiskSize 100GB -VMHost LAB-VMHOST01 -MDTServer LAB-MDT01 -MDTDataBaseInstance ADK -MDTDataBase MDT -TaskSequence WS12R2-01 # USER MAC #Install-RemoteVM -VMName SRV134 -VMRam 2048MB -VMNetwork LAN -VMCpu 1 -VMDiskSize 100GB -VMMacAddress "00:15:5A:AA:AA:11" -VMHost LAB-VMHOST01 -MDTServer LAB-MDT01 -MDTDataBaseInstance ADK -MDTDataBase MDT -TaskSequence WS12R2-01 |