Managing Group Policies during OS construction

As workstations are built in controlled environments, Group Policy restrictions will tend to prevent elements of an Operating System build from occuring as expected.

We can get around problems by ensuring that a workstation (or server) is initilly built in a specific Organisational Unit that has general domain policies blocked and then moving the computer account at the end of the build process.  Microsoft's Deployment Toolkit itself uses an account with unencrypted, plain text details for creating computer accounts which is restricted to only performing those functions.  With the example below, a typical Deployment Toolkit Solution Accelerator is used to move a computer account based on its chasis to either a desktop or mobile OU relative to the OU its currently residing.



    Function Main
            iRetVal = Success

      Dim iExitcode   : iExitcode = 0
      Dim strADDomain : strADDomain  = "MYDOMAIN.local"
      Dim strMessageText
      Dim oFso, oSysInfo, oWMIService, Laptop
      Dim colChassis, objChassis, strComputerDN, nComma, strCurrentOU, strComputerName

      'Create Objects
      Set oShell        = CreateObject("")
      Set oFso          = CreateObject("Scripting.FileSystemObject")
      Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

      '// Use WMI to determine Chassis type

      Set colChassis = oWMIService.ExecQuery ("Select * from Win32_SystemEnclosure")

      For Each objChassis in colChassis
        For i = Lbound(objChassis.ChassisTypes) to Ubound(objChassis.ChassisTypes)
            oLogging.CreateEntry "Chassis Log Type = "& objChassis.ChassisTypes(i) , LogTypeInfo
            wscript.echo         "Chassis Log Type = "& objChassis.ChassisTypes(i)
            Laptop = Islaptop(objChassis.ChassisTypes(i))

'// The current location of the machine account is read from the registry and deconstructed by splitting the string 

'// into OU locations - this will be different in all organisations

    wscript.echo      "Retrieving strComputerDN"   
    strComputerDN     = oShell.Regread("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Distinguished-Name")  
    wscript.echo      "strComputerDN = " & strComputerDN
    nComma            = InStr(strComputerDN,",")
    strCurrentOU      = Mid(strComputerDN,nComma + 1)
    strComputerName   = Left(strComputerDN,nComma - 1)
    strComputerName   = Right(strComputerName,len(strComputerName) - 3)

    oLogging.CreateEntry  "current OU = " &strCurrentOU , LogTypeInfo    

    ADArray = split(strCurrentOU,",")
    If Laptop = true then
        StrNewOU = "OU=Mobile"
        StrNewOU = "OU=Desktops"
    end if

    for x = 1 to Ubound(ADArray)
      StrNewOU = StrNewOU & "," &ADArray(x)

    if Ucase(ADArray(0)) = "OU=DEFAULTCONTAINER" then 
        oLogging.CreateEntry "Destination OU = " &StrNewOU , LogTypeInfo    
        set oLDAP = GetObject("LDAP:")
        Set objOU = oLDAP.OpenDSObject("LDAP://" &strADDomain &"/" &StrNewOU , "DOMAIN\USERNAME", "PASSWORD", 1)

       Set objMoveComputer = objOU.MoveHere("LDAP://" &strADDomain &"/" &strComputerDN, vbNullString)
        strMessageText = "Machine not being moved as it is not under the default GPO OU for building machines"
    end if

        Main = iRetVal
    End Function

Determining is a machine is a desktop or mobile device is surprising difficult as the introducion of a wide raneg of smaller devices with distinct marketing terms has meant there is no consistency in reliably detecting what type of device is being detected.  Some organisations may be lucky enough to be ceratin of all the hardware being migrated.  Some organisations will detect a battery to tell if a machine is a laptop but if the battery isn't seated correctly (or is missing) this check will fail as well.  The function at the bottom of this page lists all currently detected chasis types to determine mobile vs desktop machines.

The function below will return true for laptop machines.

'// WMI allows for multiple devices to be identified as a laptop
'// including notebooks and sub notebooks
'// Use:    Islaptop(integer)
'// Returns Bool true / false

function Islaptop(wmiInt)
    Dim Result
    Result = false

    select case wmiInt
      Case 1 'Other
        Result = false
      Case 2 'Unknown
        Result = false
      Case 3 'Desktop
        Result = false
      Case 4 'Low Profile Desktop
        Result = false
      Case 5 'Pizza Box
        Result = false
      Case 6 'Mini Tower
        Result = false
      Case 7 'Tower
        Result = false
      Case 8 'Portable
        Result = false
      Case 9 'Laptop
        Result = true
      Case 10 'Notebook
        Result = true
      Case 11 'Hand Held
        Result = true
      Case 12 'Docking Station
        Result = true
      Case 13 'All in One
        Result = false
      Case 14 'Sub Notebook
        Result = true
      Case 15 'Space-Saving
        Result = false
      Case 16 'Lunch Box
        Result = false
      Case 17 'Main System Chassis
        Result = false
      Case 18 'Expansion Chassis
        Result = false
      Case 19 'Sub Chassis
        Result = false
      Case 20 'Bus Expansion Chassis
        Result = false
      Case 21 'Peripheral Chassis
        Result = false
      Case 22 'Storage Chassis
        Result = false
      Case 23 'Rack Mount Chassis
        Result = false
      Case 24 'Sealed-Case PC
        Result = false
end select

Islaptop = Result
end function