Skip to main content

Introduction and Background

When creating an image template from Citrix App Layering using the Machine Creation Services (MCS) Connector, the images will be created and presented on the domain as the name used within the Platform Layer being they’re non-generalized initially. In many circumstances, this may not pose a problem, as the image may likely be promptly attached to a machine catalog.

There are situations in enterprise environments, however, where this may pose a problem. Chief among them are instances where an administrator must perform some sealing steps on the image which can only be done once the various layers are composed into a complete template. Examples of this are antivirus and security tools that require “blessing” or inventorying of the system to improve performance and reduce risks associated with excessive MCSIO or PVS write cache growth and VDA failures, including but not limited to:

  • Symantec Endpoint Protection (SEP) and the VIETOOL
  • Tanium VDI sealing steps (which also benefit from time to inventory/scan the system once brought online)
  • Carbon Black (which VMware recommends undergo a full scan prior to sealing the image)
  • TrendMicro OfficeScan / ApexOne VDI pre-scanning with TCacheGen

In enterprise environments where various image templates need to undergo post-provisioning sealing steps before being attached to a catalog, the inheritance of the computer name from the Platform Layer inhibits parallel processing of different images due to the shared name and can impact the operation of some tools. Working through this requires more manual effort to modify machine names (being multiple devices can’t be on the domain with the same name at a given time) or processing each image in a linear manner which adds significant administrative effort.

There is, however, an option to better deal with this challenge and work around it with some automation.

Scripts and Tasks

We’ve had the opportunity to work with a large client heavily invested in App Layering who was encountering this challenge with their MCS image deployments in Azure. Working with some smart people in Citrix Support (thank you Richard Buffone) alongside the minds and inputs of Rob Zylowski (Sr. Architect, Citrix) and Dan Lazar (App Layering PM, Citrix) a workaround was developed and roadmap considerations were discussed. The workaround was then defined by the customer to streamline the process.

Essentially the process works like so:

  1. Keep the Platform Layer off the domain (this layer is where we join the VM to the domain, we’ll need to skip that step)
  2. Run a script in OS or Platform Layer to save credentials for use by a script that will join it to domain (avoids admin intervention)
  3. Create an App Layer that runs the domain join script (which will join as LMMDDhhmm with prefix AL) as a scheduled task as the SYSTEM account
  4. Create the image template, boot the image, and it’ll join the domain as a unique entity

SaveCreds.ps1

Use the following script to create the creds code. Run this in an OS or Platform Layer version. Note the file location path C:\temp needs to exist or the process will fail.

$File = "C:\temp\creds.txt"

$pass = Read-Host "Enter Password" -AsSecureString | ConvertFrom-SecureString | Out-File $File

The customer made a custom version of this script to store the PassKey in the registry vs. the script to enhance security by making this more obscure. The key is written to a custom registry path.

$File = "C:\temp\creds.txt"
 
$PassKey = New-Object Byte[] 32
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($PassKey)
 
New-Item -Path 'HKLM:\SOFTWARE\ALDomainJoin'
New-ItemProperty -Path 'HKLM:\SOFTWARE\ALDomainJoin' -Name PassKey -Value $PassKey
$pass = Read-Host "Enter Password" -AsSecureString | ConvertFrom-SecureString -Key $PassKey | Out-File $File

RenameAndJoin.ps1

Configure the following script in an App Layer to run as a startup task under the context of SYSTEM. Note the C:\temp path. If running this as a scheduled task, there is a line item to delete the scheduled task (placeholder name used in the reference) so it only runs once.

# Change the below options as needed.
# File - Where do you want the encrypted password to be saved?
# User - A user with domain join prevledges.
# Prefix - Machine name prefix. The date and current miliseconds are used to generate a psudo random name.
# Domain - Enter FQDN of the domain to join.

$File = "C:\temp\creds.txt"
$User = "administrator"
$Prefix = "AL"
$Domain = "fqdn"
# ^^ Edit Above ^^


$date = Get-Date -Format o | ForEach-Object {$_ -replace ":", "" ` -replace "-", "" ` -replace "\.", ""}

$MonthDay = $date.SubString(4,4)
$Time = $date.SubString(9,4)
$Seconds = $date.SubString(13,5)

$sub = $date.SubString(15,7)
$sub2 = $date.SubString(4,4)

$name = $Prefix + $MonthDay + $Time + $Seconds

$MyCredential=New-Object -TypeName System.Management.Automation.PSCredential `
 -ArgumentList $User, (Get-Content $File | ConvertTo-SecureString)

Add-Computer -NewName $name -Domain $Domain -Credential $MyCredential

# Once the computer name changes, this file will no longer be valid. As an extra layer of security it will be deleted before we reboot.
Remove-Item $File

Unregister-ScheduledTask -TaskName 'DomainJoinTask'

Restart-Computer

The following script snippet was created by the customer as a modified version of the above that handles the following:

  • Calls the PassKey from registry (see the alternative SaveCreds script above) and uses a non-human identity for the domain join
  • Uses Azure VM parameters to generate the unique computer name on domain
  • Sets a specific OU path to place the computer accounts in

The alternative script parameters are being included for consideration should there be any pieces of interest worthy of including in your configuration.

#Rename and add VM to domain
 $File = PasswordFile
 $MarkerFile = MarkerFile
 $User = NHID
 $Domain = Domain
 $OUPath = OUPath
 
 If(Test-Path -Path $MarkerFile){
     #Get VM name from Azure
     $Proxy=New-object System.Net.WebProxy
     $WebSession=new-object Microsoft.PowerShell.Commands.WebRequestSession
     $WebSession.Proxy=$Proxy
 
     $AzureVMInfo = Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri http://169.254.169.254/metadata/instance?api-version=2021-02-01 -WebSession $WebSession
     $Name = $AzureVMInfo.compute.name
 
     $PassKey = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\ALDomainJoin' -Name PassKey).PassKey
     $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, (Get-Content $File | ConvertTo-SecureString -Key $PassKey)
 }
 
 Add-Computer -NewName $Name -Domain $Domain -Credential $Credential -OUPath $OUPath

Unregister-ScheduledTask -TaskName 'DomainJoinTask'

Restart-Computer

Conclusion

If all goes well, each image template that is created via the App Layering appliance using an MCS connector should appear on the domain as a unique computer and should get around some of the challenges with MCS connectors when performing numerous App Layering image updates in parallel. The logic presented is extensible and could be expanded to kick off various sealing scripts for security tools, etc. to further automate the process and reduce administrator involvement.

 

 

DISCLAIMER: THIS SOFTWARE OR SCRIPT IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

Redefine Your Approach to Technology and Innovation

Schedule a call to discover how customized solutions crafted for your success can drive exceptional outcomes, with Ferroque as your strategic ally.