Last active
April 21, 2022 07:54
-
-
Save machv/1a5c6fa3f28b884412034c6554718971 to your computer and use it in GitHub Desktop.
vm ps
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$vmRootDir = "D:\Virtual Machines" | |
$LibraryPath = "C:\Data\Parent Disks" | |
$vSwitchName = "VM" | |
$MountDir = "C:\Data\MountDir" #cannot be CSV | |
$ServerName = ""hv01 | |
$VMs = @() | |
$VMs += @{ | |
VMName = "VM01" | |
MemoryStartupBytes = 512MB | |
DynamicMemory = $true | |
NumberOfCPUs = 2 | |
AdminPassword = "LS1setup!" | |
OUPath = "OU=Servers,DC=contoso,DC=com" | |
ImageName = "Win2019_G2.vhdx" | |
} | |
#region Provision | |
foreach ($VM in $VMs){ | |
#Copy VHD to destination | |
Invoke-Command -ComputerName $ServerName -ScriptBlock { | |
New-Item -Path "$using:vmRootDir\$($using:VM.VMName)\Virtual Hard Disks\" -ItemType Directory -Force | |
Copy-Item -Path "$using:LibraryPath\$($using:VM.ImageName)" -Destination "$using:vmRootDir\$($using:VM.VMName)\Virtual Hard Disks\$($using:VM.VMName).vhdx" | |
} | |
#Create Answer File | |
$djointemp=New-TemporaryFile | |
& djoin.exe /provision /domain $env:USERDOMAIN /machine $VM.VMName /savefile $djointemp.fullname /machineou $VM.Oupath | |
#extract blob blob from temp file | |
$Blob=get-content $djointemp | |
$Blob=$blob.Substring(0,$blob.Length-1) | |
#remove temp file | |
$djointemp | Remove-Item | |
#Generate Unattend file | |
$unattend = @" | |
<?xml version='1.0' encoding='utf-8'?> | |
<unattend xmlns="urn:schemas-microsoft-com:unattend" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | |
<settings pass="offlineServicing"> | |
<component name="Microsoft-Windows-UnattendedJoin" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> | |
<OfflineIdentification> | |
<Provisioning> | |
<AccountData>$Blob</AccountData> | |
</Provisioning> | |
</OfflineIdentification> | |
</component> | |
</settings> | |
<settings pass="oobeSystem"> | |
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> | |
<UserAccounts> | |
<AdministratorPassword> | |
<Value>$($VM.AdminPassword)</Value> | |
<PlainText>true</PlainText> | |
</AdministratorPassword> | |
</UserAccounts> | |
<OOBE> | |
<HideEULAPage>true</HideEULAPage> | |
<SkipMachineOOBE>true</SkipMachineOOBE> | |
<SkipUserOOBE>true</SkipUserOOBE> | |
</OOBE> | |
</component> | |
</settings> | |
<settings pass="specialize"> | |
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> | |
<RegisteredOwner>Owner</RegisteredOwner> | |
<RegisteredOrganization>Organization</RegisteredOrganization> | |
</component> | |
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | |
</component> | |
</settings> | |
</unattend> | |
"@ | |
#Mount VHD and Apply answer file | |
Invoke-Command -ComputerName $ServerName -ScriptBlock { | |
New-Item -Path "$using:Mountdir" -ItemType Directory -Force | |
Mount-WindowsImage -Path "$using:Mountdir" -ImagePath "$using:CSVPath\$($using:VM.VMName)\Virtual Hard Disks\$($using:VM.VMName).vhdx" -Index 1 | |
New-item -type directory "$using:Mountdir\Windows\Panther" | |
Set-Content -Value $using:unattend -Path "$using:Mountdir\Windows\Panther\Unattend.xml" | |
Use-WindowsUnattend -Path "$using:Mountdir" -UnattendPath "$using:Mountdir\Windows\Panther\Unattend.xml" | |
Dismount-WindowsImage -Path "$using:Mountdir" -Save | |
Remove-Item -Path "$using:Mountdir" | |
} | |
#Create VM | |
Invoke-Command -ComputerName ($ClusterNodes | Get-Random) -ScriptBlock { | |
Function Set-VMNetworkConfiguration { | |
#source:http://www.ravichaganti.com/blog/?p=2766 with some changes | |
#example use: Get-VMNetworkAdapter -VMName Demo-VM-1 -Name iSCSINet | Set-VMNetworkConfiguration -IPAddress 192.168.100.1 00 -Subnet 255.255.0.0 -DNSServer 192.168.100.101 -DefaultGateway 192.168.100.1 | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Mandatory=$true, | |
Position=1, | |
ParameterSetName='DHCP', | |
ValueFromPipeline=$true)] | |
[Parameter(Mandatory=$true, | |
Position=0, | |
ParameterSetName='Static', | |
ValueFromPipeline=$true)] | |
[Microsoft.HyperV.PowerShell.VMNetworkAdapter]$NetworkAdapter, | |
[Parameter(Mandatory=$true, | |
Position=1, | |
ParameterSetName='Static')] | |
[String[]]$IPAddress=@(), | |
[Parameter(Mandatory=$false, | |
Position=2, | |
ParameterSetName='Static')] | |
[String[]]$Subnet=@(), | |
[Parameter(Mandatory=$false, | |
Position=3, | |
ParameterSetName='Static')] | |
[String[]]$DefaultGateway = @(), | |
[Parameter(Mandatory=$false, | |
Position=4, | |
ParameterSetName='Static')] | |
[String[]]$DNSServer = @(), | |
[Parameter(Mandatory=$false, | |
Position=0, | |
ParameterSetName='DHCP')] | |
[Switch]$Dhcp | |
) | |
$VM = Get-WmiObject -Namespace 'root\virtualization\v2' -Class 'Msvm_ComputerSystem' | Where-Object { $_.ElementName -eq $NetworkAdapter.VMName } | |
$VMSettings = $vm.GetRelated('Msvm_VirtualSystemSettingData') | Where-Object { $_.VirtualSystemType -eq 'Microsoft:Hyper-V:System:Realized' } | |
$VMNetAdapters = $VMSettings.GetRelated('Msvm_SyntheticEthernetPortSettingData') | |
$NetworkSettings = @() | |
foreach ($NetAdapter in $VMNetAdapters) { | |
if ($NetAdapter.elementname -eq $NetworkAdapter.name) { | |
$NetworkSettings = $NetworkSettings + $NetAdapter.GetRelated("Msvm_GuestNetworkAdapterConfiguration") | |
} | |
} | |
$NetworkSettings[0].IPAddresses = $IPAddress | |
$NetworkSettings[0].Subnets = $Subnet | |
$NetworkSettings[0].DefaultGateways = $DefaultGateway | |
$NetworkSettings[0].DNSServers = $DNSServer | |
$NetworkSettings[0].ProtocolIFType = 4096 | |
if ($dhcp) { | |
$NetworkSettings[0].DHCPEnabled = $true | |
} else { | |
$NetworkSettings[0].DHCPEnabled = $false | |
} | |
$Service = Get-WmiObject -Class "Msvm_VirtualSystemManagementService" -Namespace "root\virtualization\v2" | |
$setIP = $Service.SetGuestNetworkAdapterConfiguration($VM, $NetworkSettings[0].GetText(1)) | |
if ($setip.ReturnValue -eq 4096) { | |
$job=[WMI]$setip.job | |
while ($job.JobState -eq 3 -or $job.JobState -eq 4) { | |
start-sleep 1 | |
$job=[WMI]$setip.job | |
} | |
if ($job.JobState -eq 7) { | |
Write-Host "`t Success" | |
}else { | |
$job.GetError() | |
} | |
}elseif($setip.ReturnValue -eq 0) { | |
Write-Host "`t Success" | |
} | |
} | |
$VM=$using:vm | |
$VMTemp=New-VM -Name $VM.VMName -MemoryStartupBytes $VM.MemoryStartupBytes -Generation 2 -Path "$Using:CSVPath" -VHDPath "$Using:CSVPath\$($VM.VMName)\Virtual Hard Disks\$($VM.VMName).vhdx" -SwitchName $Using:vSwitchName | |
$VMTemp | Set-VMProcessor -Count $VM.NumberOfCPUs | |
if ($VM.DynamicMemory){ | |
$VMTemp | Set-VM -DynamicMemory | |
} | |
if ($VM.IPAddress){ | |
$VMTemp | Get-VMNetworkAdapter | Set-VMNetworkConfiguration -IPAddress $VM.IPAddress -Subnet $VM.Subnet -DefaultGateway $VM.DefaultGateway -DNSServer $VM.DNSServer | |
} | |
if ($VM.VLAN){ | |
$VMTemp | Get-VMNetworkAdapter | Set-VMNetworkAdapterVlan -VlanId $VM.VLAN -Access | |
} | |
$VMTemp | Start-VM | |
} | |
} | |
#endregion |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment