How to configure and run BIS-F in an SCCM task sequence

Learn how to configure and run BIS-F in an SCCM task sequence. This allows you to  build, optimize and seal your images 100% automated.

Table of Contents

Introduction

In this article, we will use a Microsoft SCCM task sequence in combination with BIS-F to build a 100% automated master target device. This master target device may be deployed using different technologies, such as Citrix Machine Creation Services (MCS) and Citrix Provisioning Server (PVS).
In case you use PVS, please make sure to install the PVS Target Device Software on the master target device. From version 6.1.0 of BIS-F, you are able to create a VHDX file directly on a UNC path.

BIS-F is an image optimization and sealing framework. The abbreviation stands for Base Image Script Framework and is one of our community’s great free tools. The company behind the tool is Login Consultants and it’s main developer is Matthias Schlimm. The framework supports Citrix XenApp/XenDesktop with MCS and PVS, VMware View and Microsoft RDS. What is also great is that BIS-F allows for the integration of third-party image optimization tools such as the Citrix Optimizer, the VMware OS Optimization Tool, CCleaner and more. BIS-F also optimizes a number of settings out-of-the-box.

The following link provides more information on the various features of BIS-F:
https://www.loginconsultants.com/en/news/all/item/base-image-script-framework-bis-f
Scroll to the bottom of the page to download the latest stable release. I also recommend to check out the website Eucweb.com.

Note: when following the steps in this article, please make sure to use BIS-F version 6.1.0 or higher.

Unattended installation of BIS-F

Before you can use BIS-F, you first have to download and extract the source file. After extracting the executable file you need to install BIS-F on your master target device. BIS-F supports a silent installation and offers a number of command line switches:

setup-BIS-F-X.X.X.exe /?

How to configure and run BIS-F in an SCCM task sequence - Setup command line switches

This is the complete command line I use for my installation:

setup-BIS-F-X.X.X.exe /verysilent /log:C:\Logs\BIS-F /norestart /noicons

In the following section you find a complete PowerShell script for installing BIS-F, including detailed logging and error handling.

By default, BIS-F is installed in the directory C:\Program Files (x86)\Base Image Script Framework (BIS-F). Also, the following shortcut is created during installation:

  • C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Base Image Script Framework (BIS-F).lnk

Another shortcut is created on the desktop of the administrator:

  • C:\Users\%UserName%\Desktop\PrepareBaseImage (BIS-F) Admin Only.lnk

These shortcuts enable an administrator to execute BIS-F. They trigger the main script PrepareBaseImage.cmd in the directory C:\Program Files (x86)\Base Image Script Framework (BIS-F).

In a 100% automated environment, these shortcuts are not required. The command line switch /NOICONS ensures that the shortcut PrepareBaseImage (BIS-F) Admin Only.lnk is not created on the desktop. However, the start menu shortcut Base Image Script Framework (BIS-F).lnk is still created during setup. The code in lines 305 to 315 in the complete installation script in the following paragraph checks the existence of both shortcuts and deletes them if found.

Complete script for installing BIS-F

The script below is based on my installation template and installs BIS-F. To start using this script, do the following:

  • Create an installation directory on the package source of your SCCM environment. For example: \\MyServer\PackageSource\LoginConsultants\BIS-F.
  • Create a subdirectory called Files.
  • Download the latest version of BIS-F. Extract the ZIP file and copy the executable to the folder Files in the installation directory.
  • Copy the script below to a new PS1 file (e.g. Install_BIS-F.ps1) and add this file to the root of your installation directory (not in the subdirectory Files).
    • Enter your preferred log directory in the variable $BaseLogDir in line 266.
    • Enter the name of the package in the variable $PackageName in line 267.
    • Enter the exact file name including file extension of the executable, for example setup-BIS-F-6.1.0.exe in the variable $FileName in line 291.
    • In case you would like to use different command line switches, please make sure to modify the value of the variable $Arguments in line 295.
  • The command line to add to your SCCM package is as follows:
    %WinDir%\Sysnative\WindowsPowershell\v1.0\powershell.exe -executionpolicy Bypass -file “Install_BIS-F.ps1”

By default, log files are created in the directory C:\Logs\BIS-F (unless you modified the directory in the variable $BaseLogDir in the script).

Note: this script was created for the operating systems Windows Server 2008 R2 and higher and Microsoft SCCM 2012. I have tested the above script on Windows Server 2008 R2 and Windows 10 version 1703.

Unattended configuration and execution of BIS-F

In the previous section, we dealt with the unattended installation of BIS-F on the master target device. In this section, we will execute BIS-F, but before we can do that, we first need to configure some settings and prepare for logging and error handling. All of this is described in the following sections:

At the end of this article, you find a complete PowerShell script that includes all of the aforementioned configurations.

Configure BIS-F group policy settings offline

The default and preferred method for configuring BIS-F settings is to use a Microsoft Group Policy. BIS-F comes with its own ADMX file containing BIS-F specific configuration settings. You can find the ADMX and ADML files in the installation directory:

C:\Program Files (x86)\Base Image Script Framework (BIS-F)\ADMX

You need to copy the ADMX and ADML files to your local or Active Directory Group Policy repository before you can use them. Afterwards, the BIS-F settings are available in your Group Policies.

How to configure and run BIS-F in an SCCM task sequence - BIS-F Group Policies

Note: for more information on how to implement ADMX/ADML files in your environment, please see the article Citrix ADMX files explained (deep dive) or the section Using Microsoft Group Policies (preferred) in the article Google Chrome on Citrix deep-dive.

When using SCCM to create your image, you may not want to or be able to rely on Group Policies. Here are a number of reasons why:

  • On some operating systems, Group Policies are only applied after the Microsoft SCCM task sequence is finished, which is too late.
    As per Microsoft: “The Setup Windows and ConfigMgr task sequence action is responsible for running Group Policy on the newly installed computer. The time at which Group Policy is applied during the task sequence action depends on the operating system being deployed. For example, with Windows XP and Windows Server 2003 Group Policy is applied after the Setup Windows and ConfigMgr task sequence action is completed. On Windows Vista and Windows Server 2008, Group Policy is applied after the task sequence is finished.” This also applies to all operating systems that came after Windows Server 2008.
  • You may not want to rely on Group Policies during the installation sequence, because you want to keep the image clean (no registry tattooing). When joining the computer to the domain, you may even choose to add the computer to an Organizational Unit with the Block Inheritance option configured.
  • During installation, you may choose to leave the computer in a workgroup instead of joining the computer to an Active Directory domain. In this case, no Group Policies are available.

In case you need to apply the BIS-F settings offline I suggest one of the following two methods:

Using the BIS-F Shared Configuration option

The BIS-F integrated way to configure settings offline is to use something called Shared Configuration.

Shared Configuration is a BIS-F policy setting. This setting enables an administrator to create an XML file which includes all BIS-F policy settings.

The way this works is as follows:

  • Configure the BIS-F Group Policies (as described in previous section).
  • Configure the BIS-F policy Global \ Shared Configuration.
    How to configure and run BIS-F in an SCCM task sequence - BIS-F Group Policies Shared Configuration
    Enter either a local or a UNC path where to save the XML file.
    How to configure and run BIS-F in an SCCM task sequence - BIS-F Group Policies Shared Configuration setting
  • Install BIS-F on a test machine on which the BIS-F Group Policies are applied.
  • Run the PowerShell script PrepBISF_Start.ps1 with the parameter -ExportSharedConfiguration. This script is located in the installation folder in the sub directory Framework. For example:
  • Two XML files should now be created in the directory as specified in the policy setting Global \ Shared Configuration.:
    • The file BISFconfig_Microsoft%OS%_%Architecture%-bit.xml contains the  exported BIS-F settings (e.g. BISFconfig_MicrosoftWindows10_64-bit.xml).
    • The file BISFSharedConfig.xml is only a reference file and contains the path to the BISFconfig_Microsoft%OS%_%Architecture%-bit.xml file.
  • During unattended installation, make sure to copy the XML file BISFSharedConfig.xml to the BIS-F installation directory. By default, this is the directory C:\Program Files (x86)\Base Image Script Framework (BIS-F). BIS-F will automatically detect the XML file and read the path to XML file that actually contains the BIS-F settings (BISFconfig_Microsoft%OS%_%Architecture%-bit.xml).
  • When running BIS-F in an SCCM task sequence please make sure that:
    • The XML file BISFconfig_Microsoft%OS%_%Architecture%-bit.xml is present in the directory as specified in the file BISFSharedConfig.xml.
    • The directory specified in the file BISFSharedConfig.xml is reachable from the master target device.
    • The system account has read access to this directory. If the master target device is in a workgroup, you must set the path NTFS rights to “Everyone read” to get access without prompting.

Please be aware that the complete configuration script below uses a Windows registry import to configure the offline BIS-F settings. If you want to use this script with the BIS-F Shared Configuration option you will have to:

  • Copy the file BISFSharedConfig.xml to the BIS-F installation directory. This is NOT included in the complete installation script above.
  • Disable lines 282 to 287 in the complete PowerShell script below. This prevents the script from trying to import a Windows registry file. The easiest way to disable these lines is to put <# before the first line and #> after the last line, like this:

Using a Windows registry export

Another method to configure BIS-F settings offline is to export the registry settings created by the BIS-F policies.

When BIS-F Group Policy settings are applied, they are written to the registry of the local computer. Here to be exact:

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Login Consultants\BISF

How to configure and run BIS-F in an SCCM task sequence - Group Policy registry settings

The approach I suggest is the following:

  • Configure all relevant BIS-F settings using Group Policy
  • Apply this Group Policy to a non-productive machine
  • Export the registry values of the non-productive machine to a *.reg file
    How to configure and run BIS-F in an SCCM task sequence - Export registry settings
  • Import the *.reg file on the master target device using a script
  • Run BIS-F

Lines 279 to 284 in the complete PowerShell script below contain the code that imports the registry file to the Windows registry of your master target device. The main code doing the actual importing can be found in the function DS_ImportRegFile in line 128:

So which settings should you configure? Well, this highly depends on your environment of course, but I can share some thoughts on the matter:

  • First of all, and most importantly, make sure to configure all settings that would otherwise prompt you during the sealing process. In an automated environment you do not want any “prompting” to occur.How to configure and run BIS-F in an SCCM task sequence - Prompt during sealing process
  • Defining a central log share will not do you much good (Global \ Configure Logging). This value will be overwritten by the task sequence log path variable (see the following section).
  • I recommend to enable at least some of the optimization tools, such as the Citrix Optimizer (Citrix \ Configure Citrix Optimizer) and CCleaner (3rd Party Tools \ Run CCleaner).
  • In case you are preparing an image for PVS, make sure to configure the settings under Citrix \ Configure Citrix PVS Target Device.
  • Decide whether or not you want to enable personalization on your image (Global \ Configure Personalization). If you enable this, a scheduled task is created which is included in your image and runs at system startup (every time, not only once).How to configure and run BIS-F in an SCCM task sequence - BIS-F personalization scheduled task
  • Enable the setting Microsoft \ Run Defrag. This will defragment your master target device. In case you are creating a VHDX file for PVS on a UNC path, an offline defragmentation is triggered as well. Defragmenting your image will give you some performance benefits. For more information, please see the article Automate VHD Offline Defrag for Citrix Provisioning Server.

I recommend you to go through each and every available setting and configure whatever is appropriate for your environment.

Set BIS-F log path using a task sequence variable

BIS-F is MDT and SCCM aware. During run time, BIS-F checks if it is currently running in an MDT or SCCM task sequence. If this is the case, BIS-F checks if the task sequence variable LogPath exists. If yes, the value of LogPath is used as the log path for the BIS-F log file (and overwrites the central log share if this has been configured).

You can specify a task sequence variable before running a script and during script execution time. This complete PowerShell script below can handle both options. Lines 290 to 342 make sure that BIS-F uses the same log path as all of your other installations. So how does it work?

First, the script needs to be able to read the existing task sequence variables. We need the COM object Microsoft.SMS.TSEnvironment for this.

The script then checks all available Task Sequence variables to see if the variable LogPath exists. For example, you may have added this variable to your SCCM collection.

How to configure and run BIS-F in an SCCM task sequence - SCCM LogPath collection variable

Using $TSenv.GetVariables, all existing task sequence variables are retrieved and stored in the array $TSVariables. The script then loops through each of the variables in the array to see if one of them matches the name LogPath. In case the variable LogPath exists, its value is stored in the variable $BISF_TS_LogPath and will be used later on in the script.

So what if you can only determine the log path at run time of the main script? How do you deal with the task sequence variable LogPath in this scenario? This is the issue that I face. I can only determine the exact log path when the main script is already running. Luckily, a task sequence variable can also be created during script execution, like this:

If you add some logging and error handling to this line of code, it looks something like this:

Now, it is important to understand the logic here. The above code snippet is only executed if no existing task sequence variable was found. For example, if you added the task sequence variable LogPath to your SCCM collection property, this value is used and that is it. The script looks no further.

In case you did not specify the LogPath task sequence variable before running the script, the script will use the same log directory as set in the variable $LogDir in line 262. If this still is not to your liking, than you can go to line 296 and add your log directory to the variable $BISFLogPath, for example $BISFLogPath = “C:\MyLogDir”.

How to configure and run BIS-F in an SCCM task sequence - LogPath variable using LogDir

The script also checks if the log directory actually exists and creates it in case it does not. Any existing BIS-F log files (*.bis) are deleted; this is needed, because of error handling as explained in the following section.

How to configure and run BIS-F in an SCCM task sequence - Create log directory and delete BIS log files

Execute BIS-F with PowerShell

Now that the BIS-F values have been imported in the registry and the log path has been set we can execute BIS-F.

Line 364 in the complete PowerShell script is responsible for installing BIS-F.

What happens under the hood is that the script PrepBISF_Start.ps1 in the directory C:\Program Files (x86)\Base Image Script Framework (BIS-F) is started.

Unfortunately, BIS-F does not return any exit codes to SCCM besides 0 (= success). Therefore, after BIS-F finishes, we need to examine the BIS-F log file to determine if any errors occurred or not. The complete error logging takes place in lines 370 to 413.

Note: if you are creating a VHDX file on a UNC path, please make sure that the local computer (the system account) has at minimum modify rights on the share (NTFS). SCCM always runs under the local system account. You can either assign the required access rights to individual computer objects ($MyComputerName) or you can use the Active Directory group Domain Computers. This group includes all computer objects within Active Directory.

Afterwards, an e-mail is sent to inform the administrator that the task sequence has finished. The reason for sending the mail is that the SCCM task sequence cannot finish properly and keeps hanging in the In Progress state. The task sequence cannot finish because in preparation of the image, BIS-F resets the SCCM client.

Make sure that the SMTP server can be reached from your master target device. The default port is 25. You can use telnet to test if the port answers:

telnet MySMTPServer.mydomain.com 25

If you want to perform a more comprehensive test to absolutely make sure that an SMTP message can be send, connect to the master target device, open a PowerShell window and execute the following command:

Enter the correct e-mail addresses as well as the IP address of your corporate SMTP server. See also the following section.

Complete script for configuring and running BIS-F

The script below is based on my installation template. The script configures and executes BIS-F and uses the registry import method as described in the section Using a Windows registry export. To start using this script, do the following:

  • Use the same installation directory on the package source of your SCCM environment as created in the section Complete script for installing BIS-F.
  • Copy the *.reg file to the folder Files in the installation directory.
  • Copy the script below to a new PS1 file (e.g. ConfigureAndRun_BIS-F.ps1) and add this file to the root of your installation directory (not in the subdirectory Files).
    • Enter your preferred log directory in the variable $BaseLogDir in line 254.
    • Enter the name of the package in the variable $PackageName in line 255.
    • Enter the exact file name including file extension of the *.reg file, for example MyRegSettings.reg in the variable $FileName in line 256.
    • In line 258, enter the e-mail address you want to send the e-mail from. This address does not have to exist (no actual mailbox is needed). For example: SCCM_TS_BIS-F@mycompany.com.
    • In line 259, enter one or more e-mail recipients you want to send the e-mail to. Separate multiple addresses using a comma, for example: “<name>@mycompany.com”, “<name>@mycompany.com”.
    • In line 260, enter the IP address of your internal SMTP server. Do not use the DNS name, because you will not be able to resolve it after BIS-F cleans your master target device!
  • The command line to add to your SCCM package is as follows:
    %WinDir%\Sysnative\WindowsPowershell\v1.0\powershell.exe -executionpolicy Bypass -file “ConfigureAndRun_BIS-F.ps1”

By default, log files are created in the directory C:\Logs\BIS-F (unless you modified the directory in the variable $BaseLogDir in the script).

Note: this script was created for the operating systems Windows Server 2008 R2 and higher and Microsoft SCCM 2012. I have tested the above script on Windows Server 2008 R2 and Windows 10 version 1703.

SCCM

In the previous sections, we prepared the package source directory and added all required source files and scripts. Now the SCCM package can be created. For an in-depth overview how to create an SCCM package, please see the article Deep dive creating SCCM packages for Citrix. This article also explains why the alias sysnative is used in the command line. For an explanation why I recommend using SCCM packages see the article Microsoft SCCM packages versus SCCM applications.

Do not be surprised or worried when the task sequence never truly seems to finish. During my tests, the task sequence never showed the Success state and always remained in the In Progress state. As explained before, an e-mail is send to the administrator that the task sequence has finished.

How to configure and run BIS-F in an SCCM task sequence - Task Sequence in progress

In the task sequence log files (including the *.bis from BIS-F) you will see that everything completed successfully.

The reason for the permanent In Progress state is the reset of the SCCM client by BIS-F. Resetting the SCCM client is necessary. It ensures that when the image is deployed, the SCCM agent on each individual target device receives a new identity from the SCCM server.

Create the SCCM package and programs

My recommendation is to create one SCCM package containing two programs.

  • SCCM package: BIS-F
    • Program 1: Install BIS-F
    • Program 2: Configure and run BIS-F

How to configure and run BIS-F in an SCCM task sequence - SCCM package and programs

Please set the maximum allowed run time for the program Configure and run BIS-F to an appropriate time to allow BIS-F to finish. The minimum run time allowed by SCCM is 15 minutes and when this time is up, SCCM ends the currently running program, effectively killing BIS-F. Especially when creating a VHDX file on a UNC path, BIS-F requires some time to finish. I therefore set the maximum allowed run time to 60 minutes. This should be sufficient for most scenarios.How to configure and run BIS-F in an SCCM task sequence - SCCM program maximum allowed run time

Prepare the SCCM task sequence

Add the two BIS-F programs to your task sequence. The installation of BIS-F is independent from the configuring and execution of BIS-F. You can install BIS-F at any time in the task sequence.

However, the configuration of BIS-F has to be the last step in the task sequence.

How to configure and run BIS-F in an SCCM task sequence - SCCM task sequence

One of the many configurations of BIS-F is to reset the SCCM client. The result of this is that afterwards, no other installation can run because the SCCM client no longer communicates with the SCCM server. So BIS-F can only be executed as the very last step in the task sequence.

Conclusion

BIS-F is a great image optimization and sealing tool. Image optimization and sealing is quite complicated in nowadays world with its many operating systems, deployment technologies, anti-virus vendors and so on. BIS-F saves us administrators a lot of time and potential headaches. It is a community tool managed by community leaders. SCCM and BIS-F is a powerful combination and allows you to create stable, optimized and 100% automated images.

13 thoughts on “How to configure and run BIS-F in an SCCM task sequence

  1. Pingback: Image Optimization Tools Comparison Matrix - Dennis Span

  2. Hi,

    Is there a way to disable the SCCM client reset? I am getting an SCCM error inside the base image script framework: “Status agent hasn’t been initialized yet. Attempting to create a pending event”, followed by some other stuff and then ending the program with “Failed to create an instance of COM progress UI object. Error code 0x80040154”.

    I am not worried about the sccm client talking to the image afterwards so i would like to see if disabling the SCCM reset fixes my error.

    • Hi Teodor,

      I would simply move the file “C:\Program Files (x86)\Base Image Script Framework (BIS-F)\Framework\SubCall\Preparation\10_PrepBISF_SCCM.ps1” to another location outside of the BIS-F installation directory and run BIS-F again. Perhaps also move the file “C:\Program Files (x86)\Base Image Script Framework (BIS-F)\Framework\SubCall\Personalization\10_PersBISF_SCCM.ps1” to prevent the reset of SCCM during personalization.

      Bye,

      Dennis

  3. Hi Dennis,

    I get a failure during the PVS P2V stage. This is presumably because the account I am running the ‘ConfigureAndRun_BIS-F’ do not have access to the remote PVS server to create a vDisk. Is there a way of specifying a account with correct permissions to create the vDisk?

    • Hi Yusuf,

      First of all, there is no need to create a vDisk. Using BIS-F version 6.1 and higher, you are able to directly create a VHDX file on a network share. You only have to make sure that the local machine has access rights on the network share. The easiest way how to do this is by assigning the group Domain Computers modify rights on the share. After the VHDX has been created you can than import it in PVS.

      That being said, if you really want to create a vDisk than, as you already said, the account executing BIS-F will need the appropriate permissions in PVS. In the last script in this article I execute BIS-F using the PowerShell cmdlet “start-process”. This cmdlet also supports the “credential” object, thus allowing you to run the process under a different user account (https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/start-process?view=powershell-6). In another article of mine, Encrypting password in a PowerShell script, I explain how to securely parse the password so you do not have to enter is in plain-text within your script.

      I hope this information answers your question.

  4. Hi Dennis,

    Can we use this tool for Horizon VDI ?
    My VMware Horizon VDI pool failed to update after windows patching. Also with new snapshot I am unable to create new fresh VDI pool too.

  5. Hi Dennis, nice work!

    Do you know if there is any way to stop the personalisation task from been created as a scheduled task? I am creating a VDP build and i am only looking to seal the image and shut down. For the life of me i can’t get the task not to be created.

    Any ideas?

    • Hi Mike,

      There is a good reason why the task is created. You can of course always disable the task using a Microsoft Group Policy Preference with an Item-Level Targeting filter (“if task exists then disable scheduled task”). Also, I would advise you to check the support section of the official BIS-F website https://eucweb.com or contact Matthias Schlimm, the developer of BIS-F, directly (https://eucweb.com/contact).

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.