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 – https://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;
<# .SYNOPSIS Detect the version of CCTK compatible with your Dell system during OS deployment tasks calling the CCTK BIOS application. .DESCRIPTION Detect the version of CCTK compatible with your Dell system during OS deployment tasks calling the CCTK BIOS application. .EXAMPLE .\Invoke-DellCCTKCheck.ps1 .NOTES FileName: Invoke-DellCCTKCheck.ps1 Author: Maurice Daly Contact: @MoDaly_IT Created: 2019-03-11 Updated: 2019-03-11 Version history: 1.0.0 - (2019-03-11) Script created #> Begin { # Load Microsoft.SMS.TSEnvironment COM object 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 { # Functions 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 = "ApplyDriverPackage.log" ) # Determine log file location $LogsDirectory = Join-Path -Path $TSEnvironment.Value("_SMSTSLogPath") -ChildPath "Temp" $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=""ApplyDriverPackage"" 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 ApplyDriverPackage.log file. Error message at line $($_.InvocationInfo.ScriptLineNumber): $($_.Exception.Message)" } } # Determine the CCTK version Write-CMLogEntry -Value "Starting Dell CCTK compatibility check" -Severity 1 $CCTKVersion = (Get-ItemProperty -Path ".\CCTK.exe" | Select-Object -ExpandProperty VersionInfo).ProductVersion # Call CCTK application to determine the exit code Write-CMLogEntry -Value "Running Dell CCTK version $($CCTKVersion) on host system" -Severity 1 $CCTKExitCode = (Start-Process -Path "CCTK.exe" -Wait -PassThru -WindowStyle Minimized).ExitCode # Determine the CCTK application path based on exit code Write-CMLogEntry -Value "Reading Dell CCTK running output" -Severity 1 if (($CCTKExitCode -like "141") -or ($CCTKExitCode -like "140")) { Write-CMLogEntry -Value "Non WMI-ACPI BIOS detected, setting CCTK legacy mode" -Severity 2 $CCTKPath = Join-Path -Path $((Get-Location).Path) -ChildPath "Legacy" $TSEnvironment.Value("DellNewCCTKCmds") = $false } else { Write-CMLogEntry -Value "WMI-ACPI BIOS detected" -Severity 1 $CCTKPath = (Get-Location).Path $TSEnvironment.Value("DellNewCCTKCmds") = $true } # Set task sequence variable with path for CCTK application Write-CMLogEntry -Value "Setting DellCCTKPath task sequence variable with the following value: $($CCTKPath)" -Severity 1 $TSEnvironment.Value("DellCCTKPath") = $CCTKPath }
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;
- Run the Invoke-DellCCTKCheck.ps1 script
- Update the Start In location with the variable %DellCCTKPath% for all of your CCTK steps
- 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.
Hi Maurice,
What a life saver!
Just what I needed in our environment – with a mix of older and brand new Dell hardware.
Initially had a little trouble getting it to work – until I realised that I had to remove my hardcoded paths to the X-drive in all the steps handling CCTK commands.
Thanks a bunch!
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.
Hi Chris,
According to the documentation these errors are due to formatting errors or invalid arguments (https://www.dell.com/support/article/ie/en/iedhs1/sln312535/dell-command-configure-error-codes?lang=en). This could be something in the 32bit version of PowerShell, I will have to look over the script in that environment to see what is happening.
Maurice