This script is used within the SCCM task sequence and performs two functions.  Firstly it determines whether or not the machine is a Hyper-V VM, and if it is, it assigns a task sequence variable called “PSisVM”.  This is useful to hold in the TS as there are certain things that only need to be done on laptops and not VMs (such as Bitlocker, TPM etc).

Secondly, it assigns the “OSDComputerName” TS variable which SCCM will use to name the machine.  It does this by taking the dell service tag number, along with a sitecode and applying a ‘D’ for desktops or ‘L’ for laptops at the end.  It also has a failsafe in there if no serial number is picked up, so that the TS will succeed and the machine will get a unique name.

There is also extensive logging throughout to help with troubleshooting if the TS fails.


#Functions
BEGIN
{
  try {
    $TSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment -ErrorAction Stop
  }
  catch [System.Exception] {
    Write-Warning -Message "Unable to construct Microsoft.SMS.TSEnvironment object"; break
  }
}
PROCESS {
#Set Logs Directory
  $LogsDirectory = Join-Path -Path $TSEnv.Value("_SMSTSLogPath") -ChildPath ""
 
function Write-TSLogEntry {
    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 = "OSDCompName.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 = ""
   
#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 OSDCompName.log file. Error message at line $($_.InvocationInfo.ScriptLineNumber): $($_.Exception.Message)"
    }
}
 
#check whether the device is a laptop - this affects the naming
Write-TSLogEntry -Value "Checking for the presence of a battery in this device" -Severity 1
$BatteryExists = (Get-WmiObject -Class Win32_Battery | Select-Object BatteryStatus).BatteryStatus
Write-TSLogEntry -Value "Battery status is returned as $BatteryExists on host system" -Severity 1
 
#gather the service tag of the device which will form part of the name
Write-TSLogEntry -Value "Checking for the serial number of this device" -Severity 1
$ServiceTag = (Get-WmiObject -Class Win32_BIOS | Select-Object SerialNumber).SerialNumber
Write-TSLogEntry -Value "Serial number of this device is reported as $ServiceTag" -Severity 1
 
#if the service tag or serial number is blank, generate a random name so that the build can continue
if (!$ServiceTag) { $Namestring = ("ERR" + (Get-Random -Minimum 1000 -Maximum 9999))
       Write-TSLogEntry -Value "The serial number of this device was blank, using $Namestring instead" -Severity 2
       } ElseIf ($ServiceTag.length -gt 10) { $NameString = ($ServiceTag.substring(0, 10))
       Write-TSLogEntry -Value "Serial number of this device was $ServiceTag which was too long and was truncated to $NameString" -Severity 1
       } Else {
       $Namestring = $ServiceTag
       Write-TSLogEntry -Value "The serial number of this device is $Namestring" -Severity 1
       }
 
#determine whether device is a vm - we will handle naming these differently do to some issues with hyper-v
Write-TSLogEntry -Value "Checking if this is a virtual machine" -Severity 1
$sysMan = (Get-wmiobject -query "Select Manufacturer from Win32_SystemEnclosure") | select-object -expand Manufacturer
Write-TSLogEntry -Value "Query returned $sysMan" -Severity 1
 
if ($sysMan -like "Microsoft") {
       $PSisVM = "True"
       } Else {
       $PSisVM = "False"
       }
 
#check if the device is a laptop or desktop for naming purposes
if ($BatteryExists -gt 0) {
    $OSDComputerName = "YOR" + $Namestring + "L"
       Write-TSLogEntry -Value "This device was identified as a laptop and the device name was set to $OSDComputerName" -Severity 1
       } Else {
       Write-TSLogEntry -Value "This device was NOT identified as being a laptop" -Severity 1
       }
 
if ($BatteryExists -eq 0) {
    $OSDComputerName = "YOR" + $Namestring + "D"
       Write-TSLogEntry -Value "This device was identified as a desktop and the device name was set to $OSDComputerName" -Severity 1
       } Else {
       Write-TSLogEntry -Value "This device was NOT identified as being a desktop" -Severity 1
       }
 
#some virtual machines will return a null value so that is handled here
if (!$BatteryExists) {
       $FailSafe = ("VM" + (Get-Random -Minimum 1000 -Maximum 9999))
       Write-TSLogEntry -Value "Battery NULL Failsafe enacted" -Severity 2
       $OSDComputerName = "YOR" + $FailSafe + "D"
       Write-TSLogEntry -Value "BatteryExists variable was a null value so the name was set to $OSDComputerName" -Severity 1
       } Else {
       Write-TSLogEntry -Value "BatteryExists variable was not a null value" -Severity 1
       }
 
#create task sequence variables for the computer name and vm or physical
$TSEnv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$TSEnv.Value("PSisVM") = "$PSisVM"
$TSEnv.Value("OSDComputerName") = "$OSDComputerName"
}

Much of the logging part of the script was ‘borrowed’ from scripts over at scconfigmgr.com so thank you to them 👍🏼

You can see the detailed Task Sequence steps in this post.