Help - Search - Members - Calendar
Full Version: Renaming computer based on Serial number AND chassis Type
MSFN Forums > Coding, Scripting and Servers > Programming (C++, Delphi, VB, etc.)

   
Google Internet Forums Unattended CD/DVD Guide
Covert Ops
Hello

I am trying to rename a bunch of workstations based on their serial number, and then a "D-" at the beginning if it is a workstation, and a "M-" if it is a notebook/laptop

For example a workstation would be renamed to D-SN12345 and a laptop would be renamed to M-SN12345

So far I have this:
CODE
Set objNetwork = CreateObject("WScript.Network")
    strComputer = objNetwork.ComputerName

Set objComputer = GetObject("winmgmts:{impersonationLevel=Impersonate}!\\" & _
    strComputer & "\root\cimv2:Win32_ComputerSystem.Name='" & _
        strComputer & "'")

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
For Each objItem in colItems
    strMsg = objItem.Caption
    If strMsg = "Microsoft Windows XP Professional" Then

        winmgmt1 = "winmgmts:{impersonationLevel=impersonate}!//."
        'WScript.Echo winmgmt1
            Set SNSet = GetObject( winmgmt1 ).InstancesOf ("Win32_BIOS")
            for each SN in SNSet

                If SN.SerialNumber = strComputer Then
                    MsgBox "Computer name already set! Name is: "& strComputer
                    Wscript.Quit
                End If

                If SN.SerialNumber = "" Then
                    MsgBox "Problem with computer naming!"
                    Wscript.Quit
                End If

                ErrCode = objComputer.Rename(SN.SerialNumber, strPassword, strUser)

                If ErrCode = 0 Then
                    MsgBox "Computer renamed successfully to: "& SN.SerialNumber
                End If

            Next

    End If
Next


This works well, but I am not sure how to go about determining if the computer is a workstation or a notebook, and then how to go about adding it to the beginning of the computer name

I did not write the script above, and I have very limited scripting knowledge

Any help would be GREATLY appreciated
Mijzelf
QUOTE
I am not sure how to go about determining if the computer is a workstation or a notebook

Maybe you can check the battery status?
gunsmokingman
Here is a script that based on the link from Microsoft, I have it so it show type and takes the first letter.

QUOTE
CODE
Option Explicit
Dim ColItems, ComType, ObjItem, strType, Wmi

Set Wmi= GetObject("winmgmts:\\.\root\CIMV2")
Set ColItems = Wmi.ExecQuery("SELECT * FROM Win32_SystemEnclosure",,48)

For Each ObjItem in ColItems
  For  Each strType in ObjItem.ChassisTypes
  Select Case strType
   Case 1 ComType = "Other"
   Case 2 ComType = "Unknown"
   Case 3 ComType = "Desktop"
   Case 4 ComType = "Low Profile Desktop"
   Case 5 ComType = "Pizza Box"
   Case 6 ComType = "Mini Tower"
   Case 7 ComType = "Tower"
   Case 8 ComType = "Portable"
   Case 9 ComType = "Laptop"
   Case 10 ComType = "Notebook"
   Case 11 ComType = "Handheld"
   Case 12 ComType = "Docking Station"
   Case 13 ComType = "All-in-One"
   Case 14 ComType = "Sub-Notebook"
   Case 15 ComType = "Space Saving"
   Case 16 ComType = "Lunch Box"
   Case 17 ComType = "Main System Chassis"
   Case 18 ComType = "Expansion Chassis"
   Case 19 ComType = "Sub-Chassis"
   Case 20 ComType = "Bus Expansion Chassis"
   Case 21 ComType = "Peripheral Chassis"
   Case 22 ComType = "Storage Chassis"
   Case 23 ComType = "Rack Mount Chassis"
   Case 24 ComType = "Sealed-Case PC"
   Case Else ComType = "Unknown"
  End Select
Next
Next  
WScript.Echo ComType & vbTab & Left(ComType,1)
Covert Ops
Great! Thanks for the help guys.

I think this will work well:
CODE
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colChassis = objWMIService.ExecQuery _
    ("Select * from Win32_SystemEnclosure")
For Each objChassis in colChassis
    For  Each strChassisType in objChassis.ChassisTypes
        Wscript.Echo strChassisType
    Next
Next


But I am not sure how to incorporate it into my previous script, and then have it enter a D- or M- at the beginning of the computer name
gunsmokingman
Try this script it should do what you want it to do.

QUOTE
CODE
Option Explicit
Dim ColItems, ComType, ErrCode, Net, ObjItem, ObjReName, ObjSN, SerialNum
Dim StrComputer, StrPassword, StrType, StrUser, Wmi, WmiVar, Var1

  Set Net = CreateObject("WScript.Network")
      StrComputer = Net.ComputerName
  Set Wmi= GetObject("winmgmts:\\" & StrComputer & "\root\CIMV2")
'/-> Start The Script
  ComputerType()
'/-> Get Pc Type
   Function ComputerType()
    Set ColItems = Wmi.ExecQuery("SELECT * FROM Win32_SystemEnclosure",,48)
     For Each ObjItem in ColItems
      For Each StrType in ObjItem.ChassisTypes
       Select Case StrType
        Case 1 ComType = "Other"
        Case 2 ComType = "Unknown"
        Case 3 ComType = "Desktop"
        Case 4 ComType = "Low Profile Desktop"
        Case 5 ComType = "Pizza Box"
        Case 6 ComType = "Mini Tower"
        Case 7 ComType = "Tower"
        Case 8 ComType = "Portable"
        Case 9 ComType = "Laptop"
        Case 10 ComType = "Notebook"
        Case 11 ComType = "Handheld"
        Case 12 ComType = "Docking Station"
        Case 13 ComType = "All-in-One"
        Case 14 ComType = "Sub-Notebook"
        Case 15 ComType = "Space Saving"
        Case 16 ComType = "Lunch Box"
        Case 17 ComType = "Main System Chassis"
        Case 18 ComType = "Expansion Chassis"
        Case 19 ComType = "Sub-Chassis"
        Case 20 ComType = "Bus Expansion Chassis"
        Case 21 ComType = "Peripheral Chassis"
        Case 22 ComType = "Storage Chassis"
        Case 23 ComType = "Rack Mount Chassis"
        Case 24 ComType = "Sealed-Case PC"
        Case Else ComType = "Unknown"
      End Select
     Next
    Next
'/-> Get The Computer Serial Number
    ComputerSerialNumber()
   End Function
'/-> Get Serial Number
   Function ComputerSerialNumber()
    Set ColItems = Wmi.ExecQuery("Select * from Win32_OperatingSystem",,48)
    For Each ObjItem In ColItems
     If InStr(LCase(ObjItem.Caption),LCase("XP Professional")) Then
     WmiVar = "winmgmts:{impersonationLevel=impersonate}!//."
     Set SerialNum = GetObject(WmiVar).InstancesOf ("Win32_BIOS")
      For  Each ObjSN In SerialNum
       If ObjSN.SerialNumber = strComputer Then
         MsgBox "This Computer Name already taken!" & vbCrLf &_
         "Computer Name: "& StrComputer,4128, "Computer Name In Use"
         Wscript.Quit
       End If
       If InStr(LCase(ObjSN.SerialNumber),LCase("System")) Then
        MsgBox "Error Cannot Retrieve This Computer Serial Number!",4128,"Error No Serial Number"
        Wscript.Quit
       End If
       If SN.SerialNumber = "" Then
        MsgBox "Error Cannot Retrieve This Computer Serial Number!",4128,"Error No Serial Number"
        Wscript.Quit
       End If
       If Len(ObjSN.SerialNumber) => 1 Then
       Var1 = Left(ComType,1) & "-" & ObjSN.SerialNumber
        Set ObjReName = GetObject("winmgmts:{impersonationLevel=Impersonate}!\\" & _
        strComputer & "\root\cimv2:Win32_ComputerSystem.Name='" &  strComputer & "'")
        ObjReName.Rename(Var1, StrPassword, StrUser)
        If ErrCode = 0 Then
         MsgBox "The Computer Rename Has Been Completed" & vbCrLf & _
         "New Name :" & Var1, 4128,"Rename Completed"
        End If
       End If
      Next
     End If
    Next
   End Function

crahak
QUOTE (gunsmokingman @ Jun 18 2008, 10:23 PM) *
Try this script it should do what you want it to do.

A few issues...

QUOTE
whatever.vbs(72, 53) Microsoft VBScript compilation error: Cannot use parentheses when calling a Sub

The fix:
CODE
ObjReName.Rename Var1, StrPassword, StrUser


Next...
CODE
If ObjSN.SerialNumber = strComputer Then

You're testing if the computer is named by its serial number alone, which is not the format you're actually trying to rename to (might be a total non-issue, as long as you didn't go around naming your PCs by serial # alone first)

Next...
CODE
If SN.SerialNumber = "" Then

QUOTE
Microsoft VBScript runtime error: Variable is undefined: 'SN'

fix:
CODE
If ObjSN.SerialNumber = "" Then


Next...
CODE
If ObjSN.SerialNumber = "" Then

and
CODE
If Len(ObjSN.SerialNumber) => 1 Then

failed to take in account that a lot of PCs w/o a serial number return a 1 character string, consisting of a single space (0x20, 32 dec), this would force the most part of our desktops to be renamed as "D- " and laptops as "L- " (thankfully it doesn't work, due to the trailing space). StrPassword and StrUser are empty too (not null but empty), not sure if that would even work, depends what it transforms the empty values into before making the API call -- a 0 length string or a null (haven't tried, too lazy!)

Next...
CODE
If ErrCode = 0 Then

ErrCode is empty, so it falsely says it has been renamed, even when it fails. (try running: If varthatdoesntexist = 0 Then MsgBox "nice!" -- nice eh?) Perhaps you meant to use Err, but that won't catch errors of WMI classes' methods, you need to do something like:
CODE
intResult = ObjReName.Rename (Var1, StrPassword, StrUser)

(Yes, NOW parentheses are required, and don't forget intResult needs to be dim'ed since you're using option explicit)
Here, intResult returns 87 indicating it actually failed.

Also, the rename method of the Win32_ComputerSystem class has limited OS support (hence why you made your script for XP only perhaps), and it will break domain memberships too (not fun) because it has to be renamed in there too! (unless it's smart enough to throw an error message and fail instead), making the script unusable for most businesses. For this reason alone, it's better to use the wsname utility, which handles all that stuff (i.e. domain memberships), and will accomplish this task (assuming your serial #s aren't blank), without a script at all i.e. using the /N:$CHASSIS[0]-$SERIALNUM argument, free of bugs too.

And that's ignoring that a large portion of computers (unless you only buy Dell) don't have the serial # filled in their BIOS in the first place, making this age-old problem not quite that easily solvable. More often than not, it's done from a list of mac addresses <-> computer name table, mainly because that never fails. (you just have to retrieve the mac addresses of your PCs first, along with their current names, with yet another script)

Also, not totally sure why you're using functions in a linear program flow (main calls ComputerType right under it, which then calls ComputerSerialNumber right under it, then returns from ComputerSerialNumber to ComputerType, which immediately returns to main...). And them functions are only called once (might be a reused snippet, that would explain it)

Edit: typo
gunsmokingman
QUOTE
CODE
Also, not totally sure why you're using functions in a linear program flow (main calls ComputerType right under it, which then calls ComputerSerialNumber right under it, then returns from ComputerSerialNumber to ComputerType, which immediately returns to main...). And them functions are only called once (might be a reused snippet, that would explain it)


The function are there just to make it easier for him to edit. I was not sure how he was going to get StrPassword, StrUser, I was going to add another function to get that info.

Since I do not know what he wants to do I just wrote him a script with what was provided, I only tested to make sure it runs without errors, I had the rename part comment so that how I missed that.

Here is a updated version with the corrections. I changed the rename part, with this link
Rename Method of the Win32_ComputerSystem Class
QUOTE
CODE
Option Explicit
Dim ColItems, ComType, ErrCode, Net, ObjItem, ObjReName, ObjSN, Return, SerialNum
Dim StrComputer, StrPassword, StrType, StrUser, Wmi, WmiVar, Var1

  Set Net = CreateObject("WScript.Network")
      StrComputer = Net.ComputerName
  Set Wmi= GetObject("winmgmts:\\" & StrComputer & "\root\CIMV2")
'/-> Start The Script
  ComputerType()
'/-> Get Pc Type
   Function ComputerType()
    Set ColItems = Wmi.ExecQuery("SELECT * FROM Win32_SystemEnclosure",,48)
     For Each ObjItem in ColItems
      For Each StrType in ObjItem.ChassisTypes
       Select Case StrType
        Case 1 ComType = "Other"
        Case 2 ComType = "Unknown"
        Case 3 ComType = "Desktop"
        Case 4 ComType = "Low Profile Desktop"
        Case 5 ComType = "Pizza Box"
        Case 6 ComType = "Mini Tower"
        Case 7 ComType = "Tower"
        Case 8 ComType = "Portable"
        Case 9 ComType = "Laptop"
        Case 10 ComType = "Notebook"
        Case 11 ComType = "Handheld"
        Case 12 ComType = "Docking Station"
        Case 13 ComType = "All-in-One"
        Case 14 ComType = "Sub-Notebook"
        Case 15 ComType = "Space Saving"
        Case 16 ComType = "Lunch Box"
        Case 17 ComType = "Main System Chassis"
        Case 18 ComType = "Expansion Chassis"
        Case 19 ComType = "Sub-Chassis"
        Case 20 ComType = "Bus Expansion Chassis"
        Case 21 ComType = "Peripheral Chassis"
        Case 22 ComType = "Storage Chassis"
        Case 23 ComType = "Rack Mount Chassis"
        Case 24 ComType = "Sealed-Case PC"
        Case Else ComType = "Unknown"
      End Select
     Next
    Next
'/-> Get The Computer Serial Number
    ComputerSerialNumber()
   End Function
'/-> Get Serial Number
   Function ComputerSerialNumber()
    Set ColItems = Wmi.ExecQuery("Select * from Win32_OperatingSystem",,48)
    For Each ObjItem In ColItems
     If InStr(LCase(ObjItem.Caption),LCase("XP Professional")) Then
     WmiVar = "winmgmts:{impersonationLevel=impersonate}!//."
     Set SerialNum = GetObject(WmiVar).InstancesOf ("Win32_BIOS")
      For  Each ObjSN In SerialNum
       If ObjSN.SerialNumber = strComputer Then
         MsgBox "This Computer Name already taken!" & vbCrLf &_
         "Computer Name: "& StrComputer,4128, "Computer Name In Use"
         Wscript.Quit
       End If
       If InStr(LCase(ObjSN.SerialNumber),LCase("System")) Then
        MsgBox "Error 1 Cannot Retrieve This Computer Serial Number!",4128,"Error 1 System Serial Number"
        Wscript.Quit
       End If
       If ObjSN.SerialNumber = "" Then
        MsgBox "Error 2 Cannot Retrieve This Computer Serial Number!",4128,"Error 2 No Serial Number"
        Wscript.Quit
       End If
       If Len(ObjSN.SerialNumber) => 2 Then
       Var1 = Left(ComType,1) & "-" & ObjSN.SerialNumber
        For Each ObjReName In Wmi.InstancesOf("Win32_ComputerSystem")
         Return = ObjReName.Rename(Var1, StrPassword, StrUser)
         If Return <> 0 Then
          MsgBox "Error 3 The Renaming Of This Computer Has Failed Error = " &_
           Err.Number,4128,"Error 3 Rename Failed"
         Else
          MsgBox "The Computer Rename Has Been Completed" & vbCrLf & _
         "New Name :" & Var1 & vbCrLf & "Reboot The Computer To Apply The New Name", 4128,"Rename Completed"
         End If
        Next
       End If
      Next
     End If
    Next
   End Function
crahak
No more typos smile.gif

But there still remain some other issues.

One thing I just thought of, is he wants computers named D-serial or M-serial

Your script will likely rename some laptops to P-serial (Portable), L-serial (Laptop), N-serial (Notebook), S-serial (Sub-Notebook), D-serial (if on a docking station) and perhaps even H-serial (Handheld), depending on the value of the ChassisType property. Similarly desktops could be named L-serial (Low Profile Desktop), M-serial (Mini Tower) which is what he wanted to name laptops(!), T-serial (Tower), etc.

And still, the script remains XP-only, and only works if your computers are part of a workgroup (doesn't work with domains) which is a serious limitation. And there's nothing you can do about the countless computers without a serial number in the DMI tables of the SMBIOS.

wsname will let you rename without any script at all, as intended, with he /N:$CHASSIS[0]-$SERIALNUM argument. It's been time tested by a LOT of people, bugfixed and all. And it works on *every* version of windows (i.e. 9x, NT, and the still fairly popular win2k). And it works even if your computers are part of a domain (most enterprise computers would be). It also has plenty of other handy functions like logging, it integrates nicely with disk imaging/sysprep solutions, can set other infos, etc. Should you decide to rename based on mac addresses (when you find out more than half your computers don't have a serial number), then it can do that too, using these arguments /RDF:macaddytoname.txt /DFK:$MAC and a properly formatted simple text file (macaddyhere = correspondingname). It even has a mechanism to ignore certain types of network adapters for that purpose.

I like scripting as much as the next guy, but when there's a specialized utility that already does this in a better way, why bother?
gunsmokingman
QUOTE
One thing I just thought of, is he wants computers named D-serial or M-serial


I am just trying to provide a template for Covert Ops, it would be up to him to edit it to what he wanted.
Covert Ops
QUOTE (gunsmokingman @ Jun 19 2008, 06:49 AM) *
QUOTE
One thing I just thought of, is he wants computers named D-serial or M-serial


I am just trying to provide a template for Covert Ops, it would be up to him to edit it to what he wanted.



This worked for me. I modified it to just output D- or M-

Thank you all for the help!!
Google Internet Forums Unattended CD/DVD Guide
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.