PVS and MCS are designed for delivery of the gold image, they are not a replacement for automating the creation of that image. What’s going to happen in those environments where the gold image has been built manually and it either needs to be recreated or the delivery mechanism needs to be changed? That manual image has become a black box that will be difficult to reverse engineer.
My Automation Framework 3.0 was released last week, but unfornatly it doesn’t have support for Windows 10. The reason is that Microsoft have not yet released Microsoft Deployment Toolkit 2013 Update 1 (ETA August 2015) which will fully support Windows 10 deployments.
Now, while I wait for that I have some time to test the upcoming Citrix Provisioning Services 7.7 Tech Preview and something called Base Image Script Framework (BIS-F).
I was tipped about BISF at Citrix Synergy / E2EVC 2015 by Jonathan Pitre which is a customer and a big fan of the Automation Framework.
Like the amazing App-V Scheduler replaced my custom App-V Powershell script, I wanted to support BISF in my Automation Framework because it’s way more powerful, feature rich and has much better logging. Let’s get started!
First of, there’s a big bug with licensing so you need to install the Citrix Licensing Server on the Citrix Provisioning Server 7.7 itself. Thanks to Carl Webster for pointing that out.
Citrix PVS Server
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 |
Write-Verbose "Setting Arguments" -Verbose $startDTM = (Get-Date) $Vendor = "Citrix" $Product = "Provisioning Services" $PackageName = "PVS_Server_x64" $InstallerType = "exe" $Version = "7.7" $LogPS = "${env:SystemRoot}" + "\Temp\$Vendor $Product $PackageName $Version PS Wrapper.log" $LogApp = "${env:SystemRoot}" + "\Temp\$PackageName.log" $UnattendedArgs = '/s /v"/qn' Start-Transcript $LogPS CD $Version\Server Write-Verbose "Starting Installation of $Vendor $Product $PackageName $Version" -Verbose (Start-Process "$PackageName.$InstallerType" $UnattendedArgs -Wait -Passthru).ExitCode CD.. CD Console (Start-Process "PVS_Console_x64.exe" $UnattendedArgs -Wait -Passthru).ExitCode Write-Verbose "Customization" -Verbose Write-Verbose "Stop logging" -Verbose $EndDTM = (Get-Date) Write-Verbose "Elapsed Time: $(($EndDTM-$StartDTM).TotalSeconds) Seconds" -Verbose Write-Verbose "Elapsed Time: $(($EndDTM-$StartDTM).TotalMinutes) Minutes" -Verbose Stop-Transcript |
Citrix PVS Target Device
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 |
Write-Verbose "Setting Arguments" -Verbose $startDTM = (Get-Date) $Vendor = "Citrix" $Product = "Provisioning Services" $PackageName = "PVS_Device_x64" $InstallerType = "exe" $Version = "7.7" $LogPS = "${env:SystemRoot}" + "\Temp\$Vendor $Product $PackageName $Version PS Wrapper.log" $LogApp = "${env:SystemRoot}" + "\Temp\$PackageName.log" $UnattendedArgs = '/S /v/qn" ALLUSERS=TRUE REBOOT=SUPPRESS /l* $LogApp"' Start-Transcript $LogPS CD $Version\Device Write-Verbose "Starting Installation of $Vendor $Product $PackageName $Version" -Verbose (Start-Process "$PackageName.$InstallerType" $UnattendedArgs -Wait -Passthru).ExitCode Write-Verbose "Customization" -Verbose Write-Verbose "Stop logging" -Verbose $EndDTM = (Get-Date) Write-Verbose "Elapsed Time: $(($EndDTM-$StartDTM).TotalSeconds) Seconds" -Verbose Write-Verbose "Elapsed Time: $(($EndDTM-$StartDTM).TotalMinutes) Minutes" -Verbose Stop-Transcript |
Citrix XenConvert
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 |
Write-Verbose "Setting Arguments" -Verbose $startDTM = (Get-Date) $Vendor = "Citrix" $Product = "XenConvert" $PackageName = "Citrix_XenConvert_x64" $InstallerType = "msi" $Version = "2.5" $LogPS = "${env:SystemRoot}" + "\Temp\$Vendor $Product $PackageName $Version PS Wrapper.log" $LogApp = "${env:SystemRoot}" + "\Temp\$PackageName.log" $Destination = "${env:ChocoRepository}" + "\$Vendor\$Product\$Version\$packageName.$installerType" $UnattendedArgs = "/i $PackageName.$InstallerType ALLUSERS=1 /qn /liewa $LogApp" Start-Transcript $LogPS CD $Version Write-Verbose "Starting Installation of $Vendor $Product $Version" -Verbose (Start-Process msiexec.exe -ArgumentList $UnattendedArgs -Wait -Passthru).ExitCode Write-Verbose "Customization" -Verbose Write-Verbose "Stop logging" -Verbose $EndDTM = (Get-Date) Write-Verbose "Elapsed Time: $(($EndDTM-$StartDTM).TotalSeconds) Seconds" -Verbose Write-Verbose "Elapsed Time: $(($EndDTM-$StartDTM).TotalMinutes) Minutes" -Verbose Stop-Transcript |
BIFS
There´s currently a bug in BISF looking for XenConvert.exe in the Provisioning Services folder. Until this is fixed you simply copy the exe to that folder.
If you´re using the Windows 8 and Server 2012 Optimization Guide script you need to reenable some services required by XenConvert.
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 |
Write-Verbose "Setting Arguments" -Verbose $StartDTM = (Get-Date) $Vendor = "Misc" $Product = "BISF" $PackageName = "setup" $Version = "5.0.1" $InstallerType = "exe" $LogPS = "${env:SystemRoot}" + "\Temp\$Vendor $Product $Version PS Wrapper.log" $LogApp = "${env:SystemRoot}" + "\Temp\$PackageName.log" $Destination = "${env:ChocoRepository}" + "\$Vendor\$Product\$Version\$packageName.$installerType" $UnattendedArgs = '/install /quiet /norestart' Start-Transcript $LogPS CD $Version Write-Verbose "Starting Installation of $Vendor $Product $Version" -Verbose #(Start-Process "$PackageName.$InstallerType" $UnattendedArgs -Wait -Passthru).ExitCode Write-Verbose "Customization" -Verbose Format-Volume -DriveLetter E -FileSystem NTFS -NewFileSystemLabel "SYSTEM" -Confirm:$false copy-item "C:\Program Files\Citrix\XenConvert\XenConvert.exe" -Destination "C:\Program Files\Citrix\Provisioning Services\XenConvert.exe" -Recurse copy-item $PSScriptRoot\* -Destination C:\Scripts\ -Recurse sc.exe config vss start= auto cmd.exe /c "net start vss" sc.exe config swprv start= auto cmd.exe /c "net start swprv" Write-Verbose "Stop logging" -Verbose $EndDTM = (Get-Date) Write-Verbose "Elapsed Time: $(($EndDTM-$StartDTM).TotalSeconds) Seconds" -Verbose Write-Verbose "Elapsed Time: $(($EndDTM-$StartDTM).TotalMinutes) Minutes" -Verbose Stop-Transcript |
Edit PrepareBaseImage.cmd to configure silent mode.
1 2 3 4 5 6 7 8 9 10 |
PushD "%~dp0" mode con: cols=190 lines=60 echo initialize script environment... please wait SET Files.PT=%~dp0BISF_SCRIPTS Powershell.exe -command "set-executionpolicy RemoteSigned" >NUL REM Powershell.exe -file "%Files.PT%\10_XA_MAIN_PrepBISF.ps1" -SuppressPndReboot REM Example for CLI silentmode Powershell.exe -file "%Files.PT%\10_XA_MAIN_PrepBISF.ps1" -SuppressPndReboot -sDelete NO -defrag NO -AVFullScan NO -OSrearm NO -OFrearm NO -CtxPvd NO -CCleaner YES -VIEScan NO -RstPerfCnt YES PopD |
You also need to specify the path to your PVS Write Cache Disk. I prefer using Group Policy, simply set and forget.
Microsoft Deployment Toolkit Configuration
Now run a Command Line with Administrator permissions as per BISF documentation.
Automating Citrix PVS Image Creation
For VMware select to Boot to BIOS.
Set the Boot Order to 1st CD-Rom and 2nd to Network Boot.
Grab the MAC address and add it to PVS.
Make sure it’s set to Boot from Hard Disk.
Start the VM on the MDT Boot Image and select your Task Sequence.
After the deployment starts you need to change the ISO from the MDT Boot Image to your Citrix Provisioning Services BDM image.
If you’re using PXE boot I guess you don’t need to do anything, but this haven´t been tested in my lab though.
I prefer to use BDM instead of interferring with other PXE services.
You can automated it even more by adding the MACAddress to CustomSettings.
1 2 3 4 5 6 7 8 9 |
[Settings] Priority=MACAddress, ByVM, UUID, Default [00:0C:29:FD:AF:DC] SkipTaskSequence=YES SkipComputerName=YES TaskSequenceID=WS2012-045 SkipFinalSummary=YES FinishAction=SHUTDOWN |
That’s Automating Citrix PVS Image Creation with MDT and BISF.
All my blog posts about Automation is already part of my Automation Framework and are Ready To Go. You can now buy the Automation Framework as a standalone product.
I Support this message 😀 Thanks Eric for taking the time to integrate BIS-F into you’re automation framework, much appreciated.
Thank you for sharing 🙂
Thanks Eric to Integrate BIS-F in your automation framework, very nice. Working on the next version for BIS-F now …. regards Matthias
Thanks Matthias, will send over the bug report
Hey Trond.
Great post with a lot of goodies. I wanted to find out from you regarding the BISF installation in the task sequence. In you’re screenshot it appears that you have a file called setup.exe installing BISF, then in you’re task sequence folder you have a task sequence step called “Base Image Script Framework” followed by “Start BISF”.
Is the first on “Base Image Script Framework” just doing a copy to the C:\Scripts folder on the base image and then once that is done it starts the script?
Hi Gareth, this is the 10.000 feet overview, but there’s lot of more stuff going to it, out-of-the-box it will break MDT. So all this stuff will be available in Automation Framework 3.1. Just send me an email and I’ll share.
Cheers Trond. Will do.
If you run a P2PVS conversion from within a MDT task sequence won’t your BaseImage contain the MDT folders (MININT and _SMSTaskSequence)?
By default yes, but some custom code fixes that.
Echo Removing remnants of MDT from the PVS vDisk…
IF EXIST D:\MININT SET PVSvDisk=D
IF EXIST E:\MININT SET PVSvDisk=E
IF EXIST F:\MININT SET PVSvDisk=F
IF EXIST G:\MININT SET PVSvDisk=G
IF EXIST “%PVSvDisk%:\MININT” RD /Q /S “%PVSvDisk%:\MININT”
IF EXIST “%PVSvDisk%:\_SMSTaskSequence” RD /Q /S “%PVSvDisk%:\_SMSTaskSequence”
IF EXIST “%PVSvDisk%:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\LiteTouch.lnk” DEL /Q “%PVSvDisk%:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\LiteTouch.lnk”