In the world of deployment a reference image is where all begins, basically we take the ISO/WIM from the vendor, install it, tweak it, patch it and on the other side we now a have a customized reference image that is more suitable for our needs. This applies to both clients and servers. There are two ways of doing this, the correct way and the incorrect way. The correct way is repeatable and as automated as possible. This blog is about the correct way and how to automate it just a bit more then usual. You can of coarse modify the script so it will do more, for example upload the images to the correct destination.
Acknowledgement goes to:
- Michael Niehaus for the post: http://blogs.technet.com/b/mniehaus/archive/2009/09/23/setting-up-an-image-factory-part-1-using-mdt-2010-lite-touch-with-scvmm-2008-r2.aspx
- Johan Arwidmark for http://www.deploymentresearch.com/Research/tabid/62/EntryId/60/MMS-2012-Running-Hyper-V-Data-Exchange-Service-in-WinPE-3-0.aspx
- Keith Garner for http://keithga.wordpress.com/2013/07/23/running-hyper-v-data-exchange-service-in-winpe-4-0-adk/
What do I need to get this working?
Step 1: Set up Microsoft Deployment Toolkit 2013 on a server
Step 2: Import Operating Systems, applications and create your task sequences
Step 3: Install Windows Server 2012 R2 (or Windows 8.1) with Hyper-V as your “creator”
Step 4: Download the script and enjoy the show
Note:
- The script is designed to run on the Hyper-V machine, but it is possible to run this remote either using Remote-Sessions or defining –Computer on every Commands that relates to Hyper-V
- The Solution is tested on Windows Server 2012 R2 with MDT 2013 and ADK 8.1 BUT should work just fine on Windows 8.1
How does the script work?
The PowerShell module has a couple of functions
New-AutoGenRefImages
This function will connect to your MDT server, grab the boot ISO, read all TaskSequences from Task Sequences\REF
And for each of them build a VM with the same name as the task sequence. When they are all built it will power them on one by one, booting from the ISO and then run the task sequence that corresponds to the name of the the VM. So if you have a TS with the ID of RW81.x86, it will build a VM with that name and run the TS with that ID on that VM.
You might ask your self how that is done?. I’m not using the database, not using GUID number or Mac’s. The main reason is that I want a solution with as little dependencies as possible, so it will work anytime at any customer (almost). Instead I’ loading the drivers for KVP (Key Value Pair Exchange) in WinPE, I grab the name of the VM before the customsettings.ini is read using a userexit script in bootstrap.ini so I have a Property called VMNameAlias wich then is used to control the deployment process, a neat solution IMHO (more on that later)
Remove-AutoGenRefImages
This function will destroy and remove all VMs, it does this by getting all task sequence ID’s from the MDT server, and find corresponding VM’s and then destroy and clean up.
New-RefImage
This is a manual process, you now need to KNOW the Task Sequence ID, since that is a validation in the CMDLET
Remove-RefImage
Also a manual process, it will destroy/delete/cleanup whatever VMname you type in, note that there will be NO questions, it just deletes them, so don’t type in DC01 or something like that.
Get-RefTaskSequence
A simple CMDLET that lists all task sequences that are in the \REF folder in MDT
The Details
Download the Scripts from here: http://sdrv.ms/1hqoJIh
Download devcon.exe from here: http://support.microsoft.com/kb/311272/en-us
Modify ImageFactoryV2.xml
This is my sample XML file and you need to modify it so it will work in your environment.
<Settings>
<DeploymentShare>\\SRVHOST555\MDTBuildLab$</DeploymentShare>
<HyperVHost>SRVHOST555</HyperVHost>
<HyperVHostNetwork>UplinkSwitch</HyperVHostNetwork>
<HyperVStorage>E:\VMs</HyperVStorage>
<HyperVISOFolder>E:\ISO</HyperVISOFolder>
<HardwareProfile>MDT 2010 Profile</HardwareProfile>
<TaskSequenceFolder>MDT:\Task Sequences\REF</TaskSequenceFolder>
<StartUpRAM>2</StartUpRAM>
<VLANID>0</VLANID>
<VHDSize>60</VHDSize>
</Settings>
Modify bootstrap.ini
Bootstrap.ini needs some modification (besides being silent). You need to add the following:
In text:
[Settings]
Priority=Default
[Default]
DeployRoot=\\SRVHOST555\MDTBuildLab$
UserDomain=NETWORK
UserID=Administrator
UserPassword=Password02
SkipBDDWelcome=YES
SubSection=ISVM-%IsVM%
[ISVM-True]
UserExit=LoadKVPInWinPE.vbs
This will load a userexit script that installs the driver for KVP and create a fake services that will allow it to load.
Modify customsettings.ini
You need to modify customsettings.ini so it will read in the values from the KVP correctly
In text:
[Settings]
Priority=Init,Default
Properties=VMNameAlias
[Init]
UserExit=ReadKVPData.vbs
VMNameAlias=#SetVMNameAlias()#
[Default]
TaskSequenceID=%VMNameAlias%
You need to add the Property VMNameAlias under the Settings Section
You need to create a new Section called Init that runs the UserExit
You need to set the TaskSequenceID to match the returned value from the UserExit script
Modify the boot image:
You need to make sure that those two scripts are added correctly and we also need the driver for KVP. One easy way is to use the “Extra” folder feature in MDT, whatever you put in that folder will end up on the boot image.
My deployment share is located in
E:\MDTBuildLab
so I created a folder called
E:\MDTBuildLab\Extra
In that Folder I two folders, Deploy and KVP. In the folder Deploy I have a subfolder called Scripts.
Like this:
Content of the KVP folder:
In the KVP folder you need to add the driver for KVP, and that you can do by searching for VMGuest.iso on your Hyper-V host, it is in C:\Windows\System32, mount that is and extract the drivers.
The driver you need is in the support\x86\Windows6.x-HyperVIntegrationServices-x86.cab and the folder is namned x86_wvmic.inf_31bf3856ad364e35_6.3.9600.16385_none_968283a5680527fe
(read Keith Garners blog for details, Note: In Keith’s blog it is 64 bit, I’m using the 32 bit driver, since I boot from the x86 boot image. Therefore the name is different of course.)
You also need to store devcon.exe in that folder
When you got them, it should look like this in the folder
Content of the Deploy\Scripts folder
In this folder you store the LoadKVPinWinPE.vbs script
Like this:
Update the BootImage:
In the Boot Image setting for WinPE, for the setting called Extra directory to add, browse to your folder, apply, update boot image.
The Scripts:
LoadKVPInWinPE.vbs
Mainly “borrowed” from Keith’s blog, just modified to use devcon.exe instead the method suggested by Keith
option explicit
function UserExit(sType,Swhen,Sdetail,bSkip)
oLogging.CreateEntry “USEREXIT:ModelAliasExit.vbs started: ” & sType & ” ” & sWhen & ” ” & sDetail, LogTypeInfo
If ucase(oEnvironment.Item(“ISVM”)) = “TRUE” and oEnvironment.Item(“OSVERSION”) = “WinPE” then
oLogging.CreateEntry “Load the Integration Components”, LogTypeInfo
oUtility.RunWithConsoleLogging “\KVP\devcon.exe /r install \KVP\wvmic.inf vmbus\{242ff919-07db-4180-9c2e-b86cb68c8c55}”
CreateFakeService “TermService”, “Remote Desktop Service”, “FakeService.exe”
GetObject(“winmgmts:root\cimv2”).Get(“Win32_Service.Name=’vmickvpexchange'”).StartService()
oUtility.SafeSleep 10000
LoadVariablesFromHyperV
End if
‘ Write back an unique number to the host to let them know that the variables have been loaded.
oUtility.RegWrite “HKLM\SOFTWARE\Microsoft\Virtual Machine\Auto\HydrationGuestStatus”,”eb471002-58aa-473a-850f-7b626613055f”
Userexit=success
end function
‘ ———————————————————
Function CreateFakeService (sName,sDisplayName,sPathName )
Dim objService
Dim objInParam
‘ Obtain the definition of the Win32_Service class.
Set objService = GetObject(“winmgmts:root\cimv2”).Get(“Win32_Service”)
‘ Obtain an InParameters object specific to the Win32_Service.Create method.
Set objInParam = objService.Methods_(“Create”).inParameters.SpawnInstance_()
‘ Add the input parameters.
objInParam.Properties_.item(“Name”) = sName
objInParam.Properties_.item(“DisplayName”) = sDisplayName
objInParam.Properties_.item(“PathName”) = sPathName
objInParam.Properties_.item(“ServiceType”) = 16
objInParam.Properties_.item(“ErrorControl”) = 0
objInParam.Properties_.item(“StartMode”) = “Manual”
objInParam.Properties_.item(“DesktopInteract”) = False
‘ Execute the method and obtain the return status.
CreateFakeService = objService.ExecMethod_(“Create”, objInParam).ReturnValue
End function
Function LoadVariablesFromHyperV
Dim objReg
Dim aSubValues
Dim aValues
Dim SubVal
oLogging.CreateEntry “Has MDT Environment Variables in Integration Components.”, LogTypeInfo
Set objReg=GetObject(“winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv”)
objReg.EnumValues &H80000002, “SOFTWARE\Microsoft\Virtual Machine\External”, aSubValues, aValues
If isArray(aSubValues) then
For Each SubVal in aSubValues
oLogging.CreateEntry “Found Key: [” & SubVal & “]”, LogTypeInfo
oEnvironment.Item(SubVal) = oUtility.RegRead(“HKLM\SOFTWARE\Microsoft\Virtual Machine\External\” & SubVal)
Next
End if
End Function
ReadKVPData.vbs
‘//—————————————————————————-
‘// Version: 1.0 – Jan 04, 2013 – Mikael Nystrom
‘// Twitter @mikael_nystrom
‘// Blog http://deploymentbunny.com
‘// This script is provided “AS IS” with no warranties, confers no rights and
‘// is not supported by the author
‘//—————————————————————————-
‘ //
‘ // Usage: Modify CustomSettings.ini similar to this:
‘ // [Settings]
‘ // Priority=SetAlias, Default
‘ // Properties=VMNameAlias
‘ //
‘ // [SetAlias]
‘ // VMNameAlias=#SetVMNameAlias()#
‘ // ***** End Header *****
Function UserExit(sType, sWhen, sDetail, bSkip)
oLogging.CreateEntry “UserExit: started: ” & sType & ” ” & sWhen & ” ” & sDetail, LogTypeInfo
UserExit = Success
End Function
Function SetVMNameAlias()
oLogging.CreateEntry “UserExit: Running function SetVMNameAlias “, LogTypeInfo
SetVMNameAlias = “”
SetVMNameAlias = oShell.RegRead(“HKLM\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters\VirtualMachineName”)
oLogging.CreateEntry “UserExit: SetVMNameAlias has been set to ” & SetVMNameAlias, LogTypeInfo
oLogging.CreateEntry “UserExit: Departing…”, LogTypeInfo
End Function
ImageFactoryV2.psm1
<#
.Synopsis
Short description
.DESCRIPTION
Long description
.EXAMPLE
Example of how to use this cmdlet
.EXAMPLE
Another example of how to use this cmdlet
.INPUTS
Inputs to this cmdlet (if any)
.OUTPUTS
Output from this cmdlet (if any)
.NOTES
General notes
.COMPONENT
The component this cmdlet belongs to
.ROLE
The role this cmdlet belongs to
.FUNCTIONALITY
The functionality that best describes this cmdlet
#>
<#
.Synopsis
Short description
.DESCRIPTION
Long description
.EXAMPLE
Example of how to use this cmdlet
.EXAMPLE
Another example of how to use this cmdlet
#>
# Read Settings from XML
[xml]$Global:Settings = Get-Content .\ImageFactoryV2.xml
$Global:DeploymentShare = $Global:Settings.Settings.DeploymentShare
$Global:StartUpRAM = 1024*1024*1024*$Global:Settings.Settings.StartUpRAM
$Global:VHDSize = 1024*1024*1024*$Global:Settings.Settings.VHDSize
$Global:SWitchName = $Global:Settings.Settings.HyperVHostNetwork
$Global:VMLocation = $Global:Settings.Settings.HyperVStorage
$Global:HyperVISOFolder = $Global:Settings.Settings.HyperVISOFolder
$Global:TaskSequenceFolder = $Global:Settings.Settings.TaskSequenceFolder
$Global:VLANID = $Global:Settings.Settings.VLANID
function New-AutoGenRefImages{
Process
{
#Connect to MDT:
Add-PSSnapIn Microsoft.BDD.PSSnapIn -ErrorAction Stop
Remove-PSDrive MDT -ErrorAction SilentlyContinue
$Null = New-PSDrive -Name MDT -PSProvider MDTProvider -Root $Global:DeploymentShare -Force
$MDTSettings = Get-ItemProperty MDT:
$ISO = $MDTSettings.’Boot.x86.LiteTouchISOName’
#Check if ISO exists
$ISOFileExist = Test-Path “$($Global:DeploymentShare)\Boot\$($ISO)” -ErrorAction SilentlyContinue
If($ISOFileExist -like ‘False’){
Write-Host “Unable to find ISO, exit”
BREAK
}
#Create Folders
$Null = New-Item -Path $HyperVISOFolder -ItemType Directory -Force -ErrorAction SilentlyContinue
#Copy the BootImage from MDTServer to Hyper-VHost
Copy-Item “$($Global:DeploymentShare)\Boot\$($ISO)” $Global:HyperVISOFolder\ -Container -Force -ErrorAction Stop
#Check if ISO exists
$ISOFileExist = Test-Path ($Global:HyperVISOFolder + “\” + $ISO) -ErrorAction Stop
If($ISOFileExist -like ‘False’){
Write-Host “Unable to find ISO, exit”
BREAK
}
#Check if VMSwitch on host exists
$VMSwitchExist = Get-VMSwitch -Name $Global:SWitchName -ErrorAction SilentlyContinue
If($VMSwitchExist.Name -ne $Global:SWitchName){
Write-Host “Unable to find VMSwitch, exit”
BREAK
}
#Create the VMs
$RefTS = Get-ChildItem $Global:TaskSequenceFolder -Recurse
Foreach($TS in $RefTS){
#Set VMName to ID
$VMName = $TS.ID
#Check if VM exists
$VMexist = Get-VM -Name $VMName -ErrorAction SilentlyContinue
If($VMexist.Name -like $VMName){
Write-Host “VM already exist, exit”
BREAK
}
$VM = New-VM –Name $VMname –MemoryStartupBytes $Global:StartUpRAM -SwitchName $Global:SWitchName -NewVHDPath “$Global:VMLocation\$VMName\Virtual Hard Disks\$VMName.vhdx” -NewVHDSizeBytes $Global:VHDSize -Path $Global:VMLocation
Add-VMDvdDrive -VM $VM -Path ($Global:HyperVISOFolder + “\” + $ISO)
#Set
Get-VM -Name $VMName | Set-VMProcessor -CompatibilityForMigrationEnabled $True
Get-VM -Name $VMName | Set-VMProcessor -Count 2
If($Global:VLANID -notlike “0”){
Get-VM -Name $VMName | Get-VMNetworkAdapter | Set-VMNetworkAdapterVlan -Access -VlanId $VLANID
}
}
Foreach($TS in $RefTS){
#Set VMName to ID
$VMName = $TS.ID
$VM = Get-VM -Name $VMName
$VM | Start-VM
Start-Sleep “10”
while($VM.State -like “Running”){
Write-Output “Waiting for $VMName to finish.”
Start-Sleep “120”}
Write-Output “$VMName is done, checking for more”
}
}
}
function Remove-AutoGenRefImages{
Process
{
#Connect to MDT:
$Null = Add-PSSnapIn Microsoft.BDD.PSSnapIn -ErrorAction SilentlyContinue
Remove-PSDrive MDT -ErrorAction SilentlyContinue
$Null = New-PSDrive -Name MDT -PSProvider MDTProvider -Root $Global:DeploymentShare -Force
$MDTSettings = Get-ItemProperty MDT:
$ISO = $MDTSettings.’Boot.x86.LiteTouchISOName’
#Remove the VMs
$RefTS = Get-ChildItem $Global:TaskSequenceFolder -Recurse
Foreach($TS in $RefTS){
#Set VMName to ID
$VMName = $TS.ID
#Check if VM exists
$VMexist = Get-VM -Name $VMName -ErrorAction SilentlyContinue
If($VMexist.Name -like $VMName){
Write-Host “Removing $VMName”
$VMToRemove = Get-VM -Name $VMName
$FolderPath = $VMToRemove.path
if($VMToRemove.state -like “Running”){Stop-VM $VMToRemove -Force}
$VMToRemove | Remove-VM -Force
$FolderPath | Remove-Item -Force -Recurse
}
}
}
}
function New-RefImage{
[CmdletBinding()]
[OutputType([int])]
Param
(
[Parameter(Mandatory=$false,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
ValueFromRemainingArguments=$false,
Position=0)]
[String]
$TaskSequenceID
)
Process
{
#Connect to MDT:
Add-PSSnapIn Microsoft.BDD.PSSnapIn -ErrorAction Stop
Remove-PSDrive MDT -ErrorAction SilentlyContinue
$Null = New-PSDrive -Name MDT -PSProvider MDTProvider -Root $Global:DeploymentShare -Force
$MDTSettings = Get-ItemProperty MDT:
$ISO = $MDTSettings.’Boot.x86.LiteTouchISOName’
#Check if ISO exists
$ISOFileExist = Test-Path “$($Global:DeploymentShare)\Boot\$($ISO)” -ErrorAction SilentlyContinue
If($ISOFileExist -like ‘False’){
Write-Host “Unable to find ISO, exit”
BREAK
}
#Create Folders
$null = New-Item -Path $HyperVISOFolder -ItemType Directory -Force -ErrorAction SilentlyContinue
#Copy the BootImage from MDTServer to Hyper-VHost
Copy-Item “$($Global:DeploymentShare)\Boot\$($ISO)” $Global:HyperVISOFolder\ -Container -Force -ErrorAction Stop
#Check if ISO exists
$ISOFileExist = Test-Path ($Global:HyperVISOFolder + “\” + $ISO) -ErrorAction Stop
If($ISOFileExist -like ‘False’){
Write-Host “Unable to find ISO, exit”
BREAK
}
#Check if VMSwitch on host exists
$VMSwitchExist = Get-VMSwitch -Name $Global:SWitchName -ErrorAction SilentlyContinue
If($VMSwitchExist.Name -ne $Global:SWitchName){
Write-Host “Unable to find VMSwitch, exit”
BREAK
}
#Check if VM exists
$VMexist = Get-VM -Name $VMName -ErrorAction SilentlyContinue
If($VMexist.Name -like $VMName){
Write-Host “VM already exist, exit”
BREAK
}
$VM = New-VM –Name $TaskSequenceID –MemoryStartupBytes $Global:StartUpRAM -SwitchName $Global:SWitchName -NewVHDPath “$Global:VMLocation\$TaskSequenceID\Virtual Hard Disks\$TaskSequenceID.vhdx” -NewVHDSizeBytes $Global:VHDSize -Path $Global:VMLocation
Add-VMDvdDrive -VM $VM -Path ($Global:HyperVISOFolder + “\” + $ISO)
#Set
Get-VM -Name $TaskSequenceID | Set-VMProcessor -CompatibilityForMigrationEnabled $True -VM $VM
#Set
Get-VM -Name $TaskSequenceID | Set-VMProcessor -Count 2
#Set
If($VLANID -notlike “0”){
Get-VM -Name $TaskSequenceID | Get-VMNetworkAdapter | Set-VMNetworkAdapterVlan -Access -VlanId $VLANID
}
}
}
function Remove-RefImage{
[CmdletBinding()]
[OutputType([int])]
Param
(
[Parameter(Mandatory=$false,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
ValueFromRemainingArguments=$false,
Position=0)]
[String]
$VMName
)
Process
{
#Check if VM exists
$VMexist = Get-VM -Name $VMName -ErrorAction SilentlyContinue
If($VMexist.Name -like $VMName){
Write-Host “Removing $VMName”
$VMToRemove = Get-VM -Name $VMName
$FolderPath = $VMToRemove.path
if($VMToRemove.state -like “Running”){Stop-VM $VMToRemove -Force}
$VMToRemove | Remove-VM -Force
$FolderPath | Remove-Item -Force -Recurse
}
}
}
function Get-RefTaskSequence{
Process
{
#Connect to MDT:
Add-PSSnapIn Microsoft.BDD.PSSnapIn -ErrorAction Stop
Remove-PSDrive MDT -ErrorAction SilentlyContinue
$Null = New-PSDrive -Name MDT -PSProvider MDTProvider -Root $Global:DeploymentShare -Force
$MDTSettings = Get-ItemProperty MDT:
$ISO = $MDTSettings.’Boot.x86.LiteTouchISOName’
#Get TS
$RefTS = Get-ChildItem $Global:TaskSequenceFolder -Recurse
Foreach($TS in $RefTS){
New-Object PSObject -Property @{
TaskSequenceID = $TS.ID
Name = $TS.Name
Comments = $TS.Comments
Version = $TS.Version
Enabled = $TS.enable
LastModified = $TS.LastModifiedTime
}
}
}
}
Export-ModuleMember -function *
/mike
Categories: Deployment, MDT, System Center 2012, System Center 2012 R2
Reblogged this on MDTGuy.WordPress.com and commented:
Great Post on Building Images!
Thanks :-)
Thanks for your great work. Can I also work with MDT2012 U1?
Yes, it will basically work. The difference is what version of WinPE you are using, diffreant versions are handled differently when it comes to loading the integration components. If possible I would recommend an upgrade to MST2013 if possible (MDT 2013 “needs” ADK for Win 8.1 to work correctly)
Hey Heard you talking about this at TechEd and was really impressed with it, but I am having a heck of a time trying to get it work. Are you offering any sort of assistance with it?
Yep, send me an email, firstname.lastname at truesec.se
Great guide…. put everything into a build with Server 2012 R2 running hyper v.
Running into a small issue… while MDT is processing the [default] rules (see the devcon window run twice) and then the whole vm resets and starts over. Any ideas what could be causing that?
Devcon runs once, but it then runs an other process, so you should see 2 windows. The most common reason for that is that it cannot find the Tasksequence. The easy fix is to see if the wizard is picking up the correct info. Set the SkipTaskSequenceID=No in customsettings.ini, that way the wizard stops and you can see if it has selected the correct TS. If not there is a problem with the integration components not setting the VMAlias to the name the TaskSequence have.
Thanks — i changed the setting and im not even getting that far.
Would it make a difference if i am using ‘Windows 8.1 ADK Update’ versus just the ‘8.1 ADK’?
Not sure, since don’t use the update (there is only one reason to use it and that is WIMboot, other then that it is not recommended to use that version) But that could be the reason. The problem in that case would be that it does not load the Integration Services or that the fake service can not start.
Well after a lot of troubleshooting, I narrowed it down to something between the vm itself and hyper-v. After the devcon commands run for some reason the VM then resets itself:
” was reset by the guest operating system. So I am a little perplexed.
ok, can you post the customsettings.ini file, the bootstrap.ini and bdd.log?
Update #2 — got it working!!!!!!
The pesky ‘/r’ on the devcon command is what was prompting the vm to restart itself over and over. Once I removed that the process works flawlessly.
Great, and thank you for the feedback!
From a hyper-v host that is domain-joined, is there any way to to connect using the MDT provider to an MDT server that is in a Workgroup? The MDT provider does not support the use of credentials. If I’m on the same domain, this tool works flawlessly. Thank you very much!
Working on a v2 of that solution, that will solve that problem, as well as others…
I know i must be dim, but: Where is the user Administrator created? It’s not a domain user? Created locally on the box where MDT is running?
Yes
Stupid question but got to ask: The user Administrator which is used in CustomSettings, is it created on the box that runs MDT?
Yes
Hi Mikael, Question for you. Using the Imaging Factory, notice that one of my reference images eats the entire Space on the HD when building. I am not sure if its hyper-V doing it or if its the OS itself, but all of the space is gone on the drive. Ideas?
Hi Mikael-
Would this process work for building a Windows 2008R2 reference image?
Thanks!
Zack
Yes, it works with Windows Server 2008 R2 images
Is this working on Windows 10?
Yes, it works
Hi Mikael, have you tested this with MDT 2013 update 1, ADK 10 and Windows 10 ?
Yes, it works
Would this work with Windows 10 Hyper-v?
Yes, it works with Windows 10 and on Windows 10
Thanks Mikael, will the hyper-v integration drivers from windows 8.1 be ok? or will I need to update this?
They work, no need to update
Hi Mikael.
Could not get this to work with a X64 WinPE 10 image. I tried to use the Windows6.x-HyperVIntegrationServices-x64.cab drivers from Windows 8.1 X64. So it looks like WinPE 10 X64 does not play well. (maybe I did something wrong…) I got the following error in WinPE: “The subsystem needed to support the image type is not present”
Worked as charm on WinPE 10 X86 with the drivers from Windows 8.1 so it really does not matter, but I thought you would like to know….
I love the post and I love the scripts! Great work.
I also had issues with x64 bit, but it does not matter when you do a ref image, since you are using Gen 1 BIOS based machines, it works anyway. Thanks for testing the new drivers btw, also, there is a new version of this coming up, one set of functions for the ref image factory using SCVMM and abetter version for Hyper-V
Good to know that I am not the only one that issue with X64. :-) Really looking forward to the new version. Will the new version have multithreading? It would be cool if it was possible to specify a maximum number of threads in the XML so that the script could start up multiple VMs at the same time. I tried to implement this in your script yesterday, but I was unsuccessfull. I tried to use workflow object in Powershell to achieve this. Seems that it is difficult to have a wait inside the workflow.
For the Image Factory that works against SCVMM it works that way and since everything is based on separate functions you can control/modify it anyway you want it :-)
Hi Mikael,
My lab is stuck in “Processing bootstrap settings. Processing rule: Default”. When I remove the bootstrap post “UserExit=LoadKVPInWinPE.vbs” the TS will start. Any ide of what could be wrong?
Best regards
Magnus
Hi, verify that you are using the x86 boot image with the modifications it needs to have to make the integration components work. It does work on WinPE 10.
Hi Mikael,
I am trying to run this on Windows 10 with MDT 2013 update 2. When booting off the ISO it hang’s on Processing rule: DEFAULT, It appears to be not running an exitscript.when looking at the BDD.log.
Hi, verify that you are using the x86 boot image with the modifications it needs to have to make the integration components work. It does work on WinPE 10.
Thanks, just got that part working my problem was using devcon from WDK 10, was the x64 bit version trying to use the x86 boot image.
Thanks For posting this.
For me, it’s Building the Virtual machine, booting the ISO, but stops and lists the 3 Task Sequences in the REF folder, it doesn’t start the one it’s assigned (Matching the Task Sequence ID) . Any idea what setting I need to tweak to kick off the Task Sequence?
Nevermind my last comment, I noticed I had a setting in the customsettings.ini default settings area that I needed to change from “NO” to “YES”
Gary, which setting was it you needed to modify? We are seeing the same issue. The image process stops at the Task Sequence selection screen instead of automatically selecting the correct one and proceeding to apply.
Hey Mike, Do I need to modify anything in the main PS script if I am only using x64 Boot Media to create my ref Images? What is this about?
$ISO = $MDTSettings.’Boot.x86.LiteTouchISOName’
In theory, yes, “but”, there is no value using a x64 boot image anyway, you should create the ref image on a BIOS based machine, not UEFI. Since BIOS based VM’s does support cross-boot there is no need and no benefit. You also need to have x64 based drivers for WinPE and you also need a devcon.exe that works in X64. So, short story, stick with x85 for boot, that works, no issues and it is plain and simple, it also supports x86 and x64.
Hey Mikael,
when is the multithreaded version going to be released? The one you mentioned above “For the Image Factory that works against SCVMM…”.
Instead of chasing around for the Hyper-V Integration Components (which I have). You can just go to https://support.microsoft.com/en-us/kb/3063109 and download it there.
In reading Michael Niehaus’ post on the “Image Factory” he has an option to select MaximumRunning VMs at a time. Is there a reason you did not include that in your solution? We are building reference images for all Microsoft supported OS and all languages so doing 300+ images in a serial fashion would take forever. I just wanted to understand if there was a technical reason not to have several VMs running at the same time if the HyperV system has the resources available to it.
The main reason is that i’m lazy, thanks for , i’ll post it as soon as I can
Hello!
Mikael, your scripts are fine!
I modified the Image Factory for the construction of images in parallel. See project on https://github.com/pvs043/winReferenceFactory
I’ve been unsuccessful in setting this up in my lab for the past two days. Can you please offer some assistance. I apologize for the length of this comment… but oh well here I go.
My Hyper-V host is a Windows 10 Enterprise machine
My Hyper-V guest/Task sequence is Windows 10
I obtained the following integration components from 2012 Hyper-V Server Evaluation.iso\Install.wim\Windows\system32\vmguest.iso\support\x86\Windows6.x-HyperVIntegrationServices-x86\x86_wvmic.inf_31bf3856ad364e35_6.2.9200.16385_none_fe8dcaff1dd25781
and copied to my deployment share at
D:\ONEDRIVE\OSDEV\DeploymentShare\Extra\KVP
• iccoinstall2.dll
• icsvc.dll
• vmapplicationhealthmonitorproxy.dll
• vmicres.dll
• vmictimeprovider.dll
• vmrdvcore.dll
• wvmic.inf
• devcon.exe
My DevCon.exe was obtained from “C:\Program Files (x86)\Windows Kits\10\Tools\x86\devcon.exe”
Likewise LoadKVPInWinPE.vbs was copied to
D:\ONEDRIVE\OSDEV\DeploymentShare\Extra\Deploy\Scripts\LoadKVPInWinPE.vbs
I updated my boot disk
Ran the following from elevated Powershell prompt
D:\ONEDRIVE\OSDEV\DeploymentShare\ImageFactoryV2Scripts> Import-Module .\ImageFactoryV2.psm1
D:\ONEDRIVE\OSDEV\DeploymentShare\ImageFactoryV2Scripts> New-AutoGenRefImages
The VM successfully was generated and booted with the x86 ISO
I then receive two Devcon.exe’s and a VM restart, with no task sequence run
If I set SkipTaskSequenceID=No in customsettings.ini the task sequence that matches the VM name is not automatically selected
If I open a command prompt via F8 and manually load the integration components using the same command below that I find in the “LoadKVPInWinPE.vbs” thusly
X:\KVP\devcon.exe install \KVP\wvmic.inf vmbus\{242ff919-07db-4180-9c2e-b86cb68c8c55}
The command runs and reports “…Drivers installed successfully”
I believe this indicates that I have the correct compatible integration components in my boot disk
Note: I removed the “/r” to prevent restarts, this might have been a mistake
X:\MININT\SMSOSD\OSDLOGS\BDD.log has the following entries
UserExit: started…
User exit \\\DeploymentShare\Scripts\ReadKVPData.vbs called successfully, skip = False
…
…UserExit: Running function SetVMNameAlias…
…UserExit:SetVMNameAlias has been set to Saved State
…UserExit: Departing…
Property VMNAMEALIAS is now = Saved State
My CustomSettings.ini reads
[Settings]
Priority=Init,Default
Properties=VMNameAlias
[Init]
UserExit=ReadKVPData.vbs
VMNameAlias=#SetVMNameAlias()#
[Default]
TaskSequenceID=%VMNameAlias%
_SMSTSORGNAME=Deploying %TaskSequenceID% to %Model%
UserDataLocation=NONE
DoCapture=SYSPREP
OSInstall=Y
AdminPassword=Password1
TimeZoneName=Pacific Standard Time
JoinWorkgroup=WORKGROUP
;HideShell=NO
;FinishAction=SHUTDOWN
ApplyGPOPack=NO
SkipAdminPassword=YES
SkipProductKey=YES
SkipComputerName=YES
SkipComputerBackup=YES
SkipDomainMembership=YES
SkipUserData=YES
SkipLocaleSelection=YES
SkipTimeZone=YES
SkipApplications=YES
SkipBitLocker=YES
SkipSummary=YES
SkipRoles=YES
SkipFinalSummary=NO
;SkipCapture=NO
;DoCapture=NO
SkipTaskSequence=YES
My Bootstrap.ini reads
[Settings]
Priority=Default
[Default]
DeployRoot=\\\DeploymentShare
UserDomain=WORKGROUP
UserID=MDTUser
UserPassword=Password1
SkipBDDWelcome=YES
SubSection=ISVM-%IsVM%
[ISVM-True]
UserExit=LoadKVPInWinPE.vbs
Thank you in advance
Use the new solution, https://github.com/DeploymentBunny/ImageFactoryV3ForHyper-V
I’m not having any luck with this.
This seems to be for remote Hyper-V VMHosts.
I am running my Hyper-V instance on my local Windows 10 Enterprise Client system with the Hyper-V feature installed.
If there is an up coming post, I’ll just wait for that.
Thank you for your time.
It works for a local Hyper-V as well, but there will e an updated post on the subject
mcgowanbl, this is a problem with devcon.exe from WDK10.
This factory work fine only with old devcon.exe (2012 year old) from link of this blog article. This link is broken now (no free download from Microsoft available).
Try my project cMDTBuildLab for build MDT server with worked boot ISO: https://github.com/pvs043/cMDTBuildLab/wiki.
Mikael Nystrom, what’s about extra.zip with devcon.exe from WDK10? Join to project at GitHub, and post Pull Requests!
“your” project, well, you “borrowed” the script I created and uploaded it to the PowerShell repo. :-)
Mikael, no!
This is a DSC module for build MDT service with your scripts (c), of course :-)
This does the same that is described in article http://deploymentresearch.com/Research/Post/540/Building-a-Windows-10-v1607-reference-image-using-MDT-2013-Update-2, but full automatic!
Please, try it and send comments.
Well, as you said, you used the scripts I did create, modified them to be DSC’s and now it is your solution, maybe you should have asked before you did that…
It’s free PowerShell Community World, isn’t it? (c) Jeffrey Snover
All links and copyrights to You and Johan Arwidmark are provided in documentation (https://github.com/pvs043/cMDTBuildLab/wiki/References)
Yes, it´s free, but so far I would say that almost 50% of everything I do ends up in a repository somewhere, slightly modified, someone saying “hey, I did this”, instead of either inventing something new, or getting back to me and say “Hey, I have a great idea”, but you are correct, it is free to do whatever you want to do. :-)
Thaks for comments, Mikael!
Added (c) to https://github.com/pvs043/cMDTBuildLab/wiki:
This project is constructed on the basis of developments of great enthusiasts of PowerShell and Windows build process:
(c) Peter Ericsson – Base idea
(c) Mikael Nystrom – Great PowerShell scripts and examples
(c) Johan Arwidmark – Step-By-Step instructions for build
At ignite this year I noticed that you were using an ImageFactoryv3 powershell script. Are there many changes between version 2 and version 3? I did not see v3 on your onedrive share.
No post on this yet, but here are the files https://github.com/DeploymentBunny/ImageFactoryV3ForHyper-V
Hey Mikael,
I’ve pretty much followed every step as far as preparation and still having issues executing. Was wondering if you could offer any assistance. Essentially generating an error when trying to execute New-AutoGenRefImages function of “Unable to Find ISO, exit” and I can confirm the iso to boot to the MDT is located there.
New solution, that works with a remote hyper-v host, no blogpost on that yet, but here is the link https://github.com/DeploymentBunny/ImageFactoryV3ForHyper-V the test part is not ready, but build is.
/mike
Hello, Mikael!
Can I include your script ImageFactoryV3-Build.ps1 to my project?
This will be a header:
Slow clap. Nodding head. Godfather style.
There is a new version of this, final testing in a production environment.