I have seen a lot of scripts around for automatically generating the next available computer name for use with SCCM during the deployment stage, however I was looking for something that would read from Active Directory and find out if any gaps existed such as where an old machine was retired and then use the next sequence number. Example:

LT-DEMO-1000
LT-DEMO-1002
LT-DEMO-1003

Given that in the above example LT-DEMO-1001 is available.

Our existing SCCM/MDT solution already auto creates PC names based on their location, machine type and the last four digits of their serial number. I wanted to add functionality to take this information, query active directory and rename the machine using the next truly available name in our naming sequence. I created the below script based on a minimum sequence value of 1000 and an upper value of 1999, the original machine type and location/dept. in my naming convention is extracted and then the machine is renamed using the next number available:

$DC = $env:LOGONSERVER.Substring(2)
$ADPowerShell = New-PSSession -ComputerName $DC
Invoke-Command -Session $ADPowerShell -scriptblock {import-module ActiveDirectory}
Import-PSSession -Session $ADPowerShell -Module ActiveDirectory -AllowClobber -ErrorAction Stop
$TypeLocation = $env:COMPUTERNAME.Substring(0,$env:COMPUTERNAME.Length-4)
$UsedNumbers = Get-ADComputer -Filter * -Properties Name | Where-Object {$_.Name -like ("$TypeLocation" + "*")} | ForEach-Object {Write-Output $($_.Name.Substring($_.Name.length-4,4))}
$NextNumber = 1000
$values = 1000..1999
Do
{
$values[$NextNumber]
$NextNumber ++
} Until ($UsedNumbers.Contains("$NextNumber") -eq $false)
$ComputerName = ("$TypeLocation" + "$NextNumber")
Exit-PSSession
Rename-Computer -ComputerName $env:COMPUTERNAME -NewName $ComputerName -Restart

Obviously the script has to be run with an account with rights to rename the computer object in Active Directory. Note that this script can be run inside the Windows environment and not the task sequence.

UPDATE – 28/11/2014

After many hours of testing, I have modified the original rename script to run inside the task sequence.

The script requires sufficient rights to connect to a named domain controller via PowerShell and rename the workstation. For security purposes I am opting obviously not to embed the password in clear text so a secondary script is run to generate a text file with a secure string password first and uploaded to a file share.

It works by passing the local machine variables through to a PS session on your DC, finding the next available computer name and then issuing a rename-computer command to the machine being imaged. In order to achieve this the script also disables and re-enables the local Windows firewall on the machine being build in order for the WMI command to be issued from the DC.

To deploy the script, add it to a package, distribute it and then insert a Run PowerShell Script command within your task sequence (setting the execution policy to bypass) as per the screenshot below:

Machine Rename Task Sequence Command

Export Credential Script (run this to export the password to a secure string in a file on your file server share):

Script Download Link – https://gallery.technet.microsoft.com/scriptcenter/SCCM-MDT-Computer-Auto-7969a373

$key = (1..16)
$securepass = Read-Host -AsSecureString -Prompt "Please enter the required account password" | ConvertFrom-SecureString -Key $Key
$encrypted = $securepass | Out-File -FilePath '\\fileserver\yourshare\Required.txt'

Machine Rename Task Sequence Script:

$Username = 'yourdomain\useraccount'
$encrypted = Get-Content -Path '\\fileserver\yourshare\Required.txt'
$key = (1..16)
$Password = $encrypted | ConvertTo-SecureString -Key $key
$Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username, $Password
$DC = "YourDomainControllerName"
$ADPowerShell = New-PSSession -ComputerName $DC -Credential $Credentials
$CurrentName = $env:COMPUTERNAME
netsh advfirewall set allprofiles state off
Invoke-Command -Session $ADPowerShell -scriptblock {
    import-module ActiveDirectory
    $clientname = $($args[0])
    $Username = 'yourdomain\useraccount'
    $encrypted = Get-Content -Path '\\fileserver\yourshare\Required.txt'
    $key = (1..16)
    $password = $encrypted | ConvertTo-SecureString -Key $key
    $DomainCredentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username, $Password
    $TypeLocation = $ClientName.Substring(0, $ClientName.Length - 4)
    $UsedNumbers = Get-ADComputer -Filter * -Properties Name | Where-Object { $_.Name -like ("$TypeLocation" + "*") } | ForEach-Object { Write-Output $($_.Name.Substring($_.Name.length - 4, 4)) }
    $values = 1000..1999
    $adcheck = 0
    Do
    {
        # Set beginning of sequence number
        $NextNumber = 1000
        # Increment active directory check flag
        $adcheck++
        Do
        {
            $values[$NextNumber]
            $NextNumber++
        }
        Until ($UsedNumbers.Contains("$NextNumber") -eq $false)
        $ComputerName = ("$TypeLocation" + "$NextNumber")
        start-sleep -Seconds 2
    }
    while ($adcheck -le 3)
    Rename-Computer -ComputerName $ClientName -NewName $ComputerName -DomainCredential $DomainCredentials
    Exit-PSSession
} -ArgumentList $CurrentName
Remove-PSSession $ADPowerShell
# Re-enable the local firewall
netsh advfirewall set allprofiles state on

 

Maurice Daly
Maurice has been working in the IT industry since 1999 and was awarded his first MVP Enterprise Mobility award in 2017. Technology focus includes Active Directory, Group Policy, Hyper-V, Windows Deployment (SCCM & MDT) and Office 365.

(355)

There are no comments.

Leave a Reply