Recently I was working with a customer who was having issues with the latest version of the Dell CCTK configuration utility running on their older legacy systems during OS deployments. Dell have recently updated their CCTK tool to provide added functionality for their latest generation of systems, however in doing so they have dropped support for a number of machines which are still present in some enterprises.

In order to cater for these machines I wrote a small PowerShell script which works with the exit codes 140 and 141 as per the Dell documentation – http://en.community.dell.com/techcenter/enterprise-client/w/wiki/12220.dell-command-configure-error-codes. These error codes relate specifically to the availability of the new WMI-ACPI functions, thus providing a means of detecting if the machine running the CCTK is a legacy system.

Once the error codes have been flagged the script will set a task sequence variable with the path to either the new CCTK or a legacy version of the CCTK which should in this example be packaged into the same package in a “Legacy” folder, thus ensuring you have a supported version of the CCTK running.

To put this together, first of all download the most recent version and the latest 3.x version of the CCTK tool from the following;

CCTK 4.1 – https://www.dell.com/support/home/yu/en/yubsdt1/Drivers/DriversDetails?driverId=2KRXV
CCTK 3.3 – https://www.dell.com/support/home/yu/en/yubsdt1/Drivers/DriversDetails?driverId=FVGF9

Create a package with the extracted tools, putting the older version of the toolkit in a “Legacy” subfolder;

Now add the following PowerShell script into the root folder;

<#	
  .DESCRIPTION
    Used to detect the version of CCTK compatible with your Dell system during
    OS deployment tasks calling the CCTK BIOS applicaiton

  .NOTES
      FileName:    Invoke-DellCCTKCheck.ps1
      Author:      Maurice Daly
      Contact:     @MoDaly_IT
      Created:     2018-07-13
      Updated:     2018-07-18
#>

# Functions

BEGIN 
{
  try {
    $TSEnvironment = New-Object -ComObject Microsoft.SMS.TSEnvironment -ErrorAction Continue
  }
  catch [System.Exception] {
    Write-Warning -Message "Unable to construct Microsoft.SMS.TSEnvironment object"; break
  }
}
PROCESS {
  # Set Logs Directory
  $LogsDirectory = Join-Path -Path $TSEnvironment.Value("_SMSTSLogPath") -ChildPath "Temp"
  
  function Write-CMLogEntry {
    param (
      [parameter(Mandatory = $true, HelpMessage = "Value added to the log file.")]
      [ValidateNotNullOrEmpty()]
      [string]$Value,
      [parameter(Mandatory = $true, HelpMessage = "Severity for the log entry. 1 for Informational, 2 for Warning and 3 for Error.")]
      [ValidateNotNullOrEmpty()]
      [ValidateSet("1", "2", "3")]
      [string]$Severity,
      [parameter(Mandatory = $false, HelpMessage = "Name of the log file that the entry will written to.")]
      [ValidateNotNullOrEmpty()]
      [string]$FileName = "ApplyDellCCTK.log"
    )
    # Determine log file location
    $LogFilePath = Join-Path -Path $LogsDirectory -ChildPath $FileName
    
    # Construct time stamp for log entry
    $Time = -join @((Get-Date -Format "HH:mm:ss.fff"), "+", (Get-WmiObject -Class Win32_TimeZone | Select-Object -ExpandProperty Bias))
    
    # Construct date for log entry
    $Date = (Get-Date -Format "MM-dd-yyyy")
    
    # Construct context for log entry
    $Context = $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
    
    # Construct final log entry
    $LogText = "<![LOG[$($Value)]LOG]!><time=""$($Time)"" date=""$($Date)"" component=""ApplyDellCCTK"" context=""$($Context)"" type=""$($Severity)"" thread=""$($PID)"" file="""">"
    
    # Add value to log file
    try {
      Out-File -InputObject $LogText -Append -NoClobber -Encoding Default -FilePath $LogFilePath -ErrorAction Stop
    }
    catch [System.Exception] {
      Write-Warning -Message "Unable to append log entry to ApplyDellCCTK.log file. Error message at line $($_.InvocationInfo.ScriptLineNumber): $($_.Exception.Message)"
    }
  }
  
  Write-CMLogEntry -Value "Staritng Dell CCTK compatibility check" -Severity 1
  $CCTKVersion = (Get-ItemProperty .\CCTK.exe | select -ExpandProperty VersionInfo).ProductVersion
  Write-CMLogEntry -Value "Running Dell CCTK version $CCTKVersion on host system" -Severity 1
  $CCTKExitCode = (Start-Process cctk.exe -Wait -PassThru).ExitCode
  Write-CMLogEntry -Value "Reading Dell CCTK running output" -Severity 1
  if (($CCTKExitCode -eq "141") -or ($CCTKExitCode -eq "140")) {
    Write-CMLogEntry -Value "Non WMI-ACPI BIOS detected. Setting CCTK legacy mode" -Severity 2
    $CCTKPath = Join-Path -Path $((Get-Location).Path) -ChildPath "Legacy"
  }
  else {
    Write-CMLogEntry -Value "WMI-ACPI BIOS detected" -Severity 1
    $CCTKPath = (Get-Location).Path
  }
  Write-CMLogEntry -Value "Setting DellCCTKPath task sequence variable" -Severity 1
  $TSEnvironment.Value("DellCCTKPath") = $CCTKPath
  Write-CMLogEntry -Value "Dell CCTK will be access from $CCTKPath" -Severity 2
}



Create the package in ConfigMgr then edit your task sequence, then run the Invoke-DellCCTKCheck.ps1 prior to your CCTK steps to set the detected TS value. The next thing to do is update the path to your CCTK in each of the steps;

  1. Run the Invoke-DellCCTKCheck.ps1 script
  2. Update the Start In location with the variable %DellCCTKPath% for all of your CCTK steps
  3. Repeat the script run if you are formatting the drive prior to completing your CCTK steps

Your task sequence should now cater for new and legacy systems without having to duplicate your CCTK steps with specific WMI filters to control how the steps are run.

Thanks for reading.

(3245)

Maurice Daly

Maurice has been working in the IT industry for the past 18 years and currently working in the role of Principal Consultant with TrueSec. With a focus on OS deployment through SCCM/MDT, group policies, active directory, virtualisation and office 365, Maurice has been a Windows Server MCSE since 2008 and was awarded Enterprise Mobility MVP in March 2017.

comments
  • Chris
    Posted at 18:37 October 9, 2018
    Chris
    Reply
    Author

    Hi Maurice, thanks for this great script. Did you happen to also test with the x86 version of CCTK and a 32-bit OS? Just asking because I am getting different exit codes with them. In a 32-bit OS I am getting a code 50 from the 4.1 x86 CCTK version and code 136 from the 3.3 (legacy) x86 CCTK version.

  • Leave a Reply

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