Tuesday, March 22, 2011

How to assign a dynamic computername during OSD

With ConfigMgr 2007 there can be put many information in the Task Sequence used for OSD. With Windows XP, Vista or 7 there will be different files created for using a unattend installation. All information set in the Task Sequence will be used for creating that specific file. Only a dynamically computername is missing here! How to assign a dynamic computername during OSD, that's the question!

In a Task Sequence used for OSD, this information can be placed in "Apply Windows Settings" and "Apply Network Settings". In "Apply Windows Settings" the following information is (most of times) set:
  • User/Organization name
  • Product key
  • Local administrator password
  • Time zone
In "Apply Network Settings" the following information is (most of times) set:
  • Join a workgroup or domain
  • Set specific domain information
  • Account used for domain join
With this information a sysprep.inf file (for Windows XP) or a unattend.xml file (for Windows Vista or 7) is created at specific places. The sysprep.inf file will be created/placed at C:\Sysprep (with the deployment tools). The unattend.xml will be created/placed at C:\Windows\Panther\Unattend. Sysprep is already build-in for Windows Vista and 7.

During above steps ("Apply Windows Settings" and "Apply Network Settings") these files will be generated. During "Setup windows and ConfigMgr" these files will be used for having a unattend installation. The only information missing here is how to set the computername?


With MDT integration an additional step is used for making that possible. Then a Task Sequence variable can be used for dynamically assigning a computername. This is explained here: http://blog.coretech.dk/mip/wrong-pc-name-after-deployment/

With ConfigMgr only (without MDT integration) an additional script is needed for unattended installation, or the computername must be filled-in manually during OSD (not recommended). The additional script must have lines in it for recognizing the computername in the BIOS, and place that information in the sysprep.inf or unattend.xml file.


Most of times I disable both "Apply Windows Settings" and "Apply Network Settings" steps in the Task Sequence, and making use of the sysprep.inf and/or unattend.xml which is created by ConfigMgr during OSD. The only change I make then is to replace the Computername with an "*" sign, and create a separate package from this file.

Then I put that file (as package) at the "Apply Operating System" step. The package which contains the script (converted to executable) is put in an additional step, in this case: "Assettag To Unattend". The script I use is as follows (using the Asset Tag as computername):

Windows XP on HP devices:
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <File.au3>
#include <Array.au3>
RunWait("cmd.exe /c " & "wmic /node:localhost systemenclosure get smbiosassettag > c:\sysprep\assettag.txt", "",@SW_HIDE)
$file = FileOpen("C:\sysprep\assettag.txt", 0)
$assettag = FileReadLine($file,2)
FileClose($file)
ReplaceInFile('C:\sysprep\sysprep.inf', "*", $assettag)
Func ReplaceInFile($io_file, $io_word, $io_replacement)
    Dim $Records
    $Lines = _FileCountLines($io_File)
    If Not _FileReadToArray($io_file, $Records) Then
        ConsoleWriteError("There was an error reading > " & $io_file & @CRLF)
        Exit
    ElseIf _FileReadToArray($io_file, $Records) == "" Then
        ConsoleWriteError("File is empty!" & @CRLF)
    ElseIf Not @error Then
        ConsoleWrite("> File succeeded!" & @CRLF)
    EndIf
    $File = FileOpen($io_file, 2)
    For $ax = 1 To $Records[0]
        ConsoleWrite("+> " & $Records[$ax] & @CRLF)
        $Replace = StringReplace($Records[$ax], $io_word, $io_replacement)
        ConsoleWrite("+> " & $Replace & @CRLF)
        If _FileCountLines($io_file) < UBound($Lines) - 1 Then
            FileWrite($File, $Replace & @CRLF)
        Else
            FileWrite($File, $Replace & @CRLF)
        EndIf
    Next
    FileClose($File)
EndFunc


Windows XP on Dell devices:
Replace "systemenclosure get smbiosassettag" with
"systemenclosure get serialnumber". Then it works also on Dell devices.


Windows Vista or 7 on HP devices:
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <File.au3>
#include <Array.au3>
RunWait("cmd.exe /c " & "wmic /node:localhost systemenclosure get smbiosassettag > c:\_SMSTaskSequence\assettag.txt", "",@SW_HIDE)
$file = FileOpen("C:\_SMSTaskSequence\assettag.txt", 0)
$assettag = FileReadLine($file,2)
FileClose($file)
ReplaceInFile('C:\Windows\Panther\unattend\unattend.xml', "*", StringStripWS ($assettag,8))
Func ReplaceInFile($io_file, $io_word, $io_replacement)
    Dim $Records
    $Lines = _FileCountLines($io_File)
    If Not _FileReadToArray($io_file, $Records) Then
        ConsoleWriteError("There was an error reading > " & $io_file & @CRLF)
        Exit
    ElseIf _FileReadToArray($io_file, $Records) == "" Then
        ConsoleWriteError("File is empty!" & @CRLF)
    ElseIf Not @error Then
        ConsoleWrite("> File succeeded!" & @CRLF)
    EndIf
    $File = FileOpen($io_file, 2)
    For $ax = 1 To $Records[0]
        ConsoleWrite("+> " & $Records[$ax] & @CRLF)
        $Replace = StringReplace($Records[$ax], $io_word, $io_replacement)
        ConsoleWrite("+> " & $Replace & @CRLF)
        If _FileCountLines($io_file) < UBound($Lines) - 1 Then
            FileWrite($File, $Replace & @CRLF)
        Else
            FileWrite($File, $Replace & @CRLF)
        EndIf
    Next
    FileClose($File)
EndFunc


Windows Vista or 7 on Dell devices:
Replace "systemenclosure get smbiosassettag" with
"systemenclosure get serialnumber". Then it works also on Dell devices.


(thanks to Wilfred Hanekamp for sharing the script)

Download and install AutoIt for making changes to this script, and building a executable file from it. With this script, assigning a dynamic computername is possible, without using MDT integration!

ConfigMgr rocks again!


Update 15-11-2011: Because of some comments that the script isn't working I replaced the script with additional values. This time the script must be functional again.

Update 16-3-2012: Again I replaced the script with additional values. In my environment the script is running fine.

19 comments:

  1. Hi Henk,
    Thanks for sharing this information.
    I am a little confused by this part though:

    Most of times I disable both "Apply Windows Settings" and "Apply Network Settings" steps in the Task Sequence, and making use of the sysprep.inf and/or unattend.xml which is created by ConfigMgr during OSD. The only change I make then is to replace the Computername with an "*" sign, and create a separate package from this file.

    Could you elaborate on this?
    So, you disable the two steps in the TS.
    But then, what do you do next?

    Thanks,

    ReplyDelete
  2. Hi, it's true you can disable both steps in your task sequence. This because they will be used to create a sysprep.inf or unattend.xml which can be manually created and customized also.

    During deployment (when above steps are still enabled) an answer file will be created. Just copy that one before reboot in the "Setup windows and ConfigMgr" step. Then create a package from that (after customization) and place it in the "Apply Operating System" step.

    That way both steps can be disabled now, and a dynamic computername will be possible. Hope I make things clear with posts like this.

    ReplyDelete
  3. can you please let know what kind script language is, and how to save the sript, i am using it with sccm OSD

    ReplyDelete
  4. Download and install AutoIt for making changes to this script, and building a executable file from it.

    ReplyDelete
  5. I did install Autoit, when I convert to .exe it didn't work, I am not that familiar with scripting languages, once i copy the language what kind a file extension do I need to save the script, in order to work.

    ReplyDelete
  6. I am getting an error in compiled .exe
    "subscript used with non-array variable"
    seems to choke on line 14


    For $ax = 1 To $Records[0]

    ReplyDelete
  7. So all this is needed if you do not integrate MDT?
    During deployment (when above steps are still enabled) an answer file will be created. Just copy that one before reboot in the "Setup windows and ConfigMgr" step. Then create a package from that (after customization) and place it in the "Apply Operating System" step.

    Can I create an unattended.xml file using MDT or Windows System Image Manager and then create a package contatining just an .xml file and add it after Apply Operating System??

    ReplyDelete
  8. Yes, you can create a custom unattend.xml file with some settings in it. Than one can be used in the "Apply Operation System" step then. The settings used in your custom unattend.xml file will be merged with the one created by ConfigMgr then.

    ReplyDelete
  9. Is it possible to change the computername based on the chasis type? So L-SERIALNO if its a laptop and D-SERIALNo if its a desktop?

    ReplyDelete
  10. Yes, that's possible with TS variables. That way you can decide which chassis type receives a specific computername based on serialnumber.

    Have a look here for a overview of chassis types: http://blogs.technet.com/b/breben/archive/2009/07/21/chassis-type-values-in-sccm.aspx

    ReplyDelete
  11. Hi Henk,

    Testing your script first before integration into SCCM OSD Task Sequence. It appears that when I run the script, my unattend.xml is reset to 0 bytes (No replace of content in file, just a blank file)

    ReplyDelete
  12. Have you already tested it during OS deployment? Otherwise I will post an update again.

    ReplyDelete
  13. Hi Henk,

    I did the following:
    1 copy pasted my unattend.xml (7 KB) into C:\Windows\Panther\unattend
    2 created folder _SMSTaskSequence on %SYSTEMDRIVE%
    3 ran the script in an administrator console (CMD) on Windows 7
    4 a file assettag.txt is created in the folder _SMSTaskSequence with two lines of data. first line is smsbiosassettag, second line is the identification, which needs to replace the "*" in unattend.xml
    5 verified replacement but found unattend.xml is 0 KBytes, instead of 7 KB,

    ReplyDelete
  14. Hi Henk,

    How do I get the name "UMC" before the serialnumber?

    Best regards, Jet from the umcn

    ReplyDelete
  15. Hi Jet,

    You can import the devices with ConfigMgr manually or by csv file. That way UMC can be placed before the serialnumber (excel sheet + merge cells). The name imported in ConfigMgr will be the name used during OS deployment.

    Best regards, Henk

    ReplyDelete
  16. could you please what did you include in the unattended package and what is the package of the os deployment

    ReplyDelete
    Replies
    1. Hi, the code for this is included in the blogpost. Most of time I'm using a CSV import so the items are already in SCCM. That way the item name is used during OS deployment. Hope it helps.

      Delete
  17. hello and thanks for writing such good details on Computer name,
    we have about 1000 computers which we want to migrate to a new domain. wanted to know how can we change computer names to a new naming model based on our internal standard. the naming standard provided in an excel sheet containing old computer name, MAC and new computer name. is there any way to merge this type of data into OSD TS so when OS installed, its name gets changed based on its old name or mac address?

    ReplyDelete
    Replies
    1. Hello, never did that before, but there are some great blogposts about that too: http://blog-en.netvnext.com/2013/02/rename-pcs-during-sccm-osd-zti.html and http://www.david-obrien.net/2013/10/rename-machine-configmgr-osd/ Hope it helps!

      Delete