FOG Post install script for Win Driver injection

  • Moderator

    fog.drivers

    This script does the heavy lifting of identifying what hardware the script is running on and then copies all of the files from the correct source directory to the destination directory on the target computer.

    #!/bin/bash
    ceol=`tput el`;
    manu=`dmidecode -s system-manufacturer`;
    case $manu in
        [Ll][Ee][Nn][Oo][Vv][Oo])
            machine=$(dmidecode -s system-version)
            ;;
        *[Dd][Ee][Ll][Ll]*)
            machine=$(dmidecode -s system-product-name) #pruduct is typo, just realized sorry :(
            ;;
        *)
            machine=$(dmidecode -s system-product-name) # Technically, we can remove the dell one as it's the "default"
            ;;
    esac
    [[ -z $machine ]] && return #assuming you want it to break if it is not lenovo or dell?
    machine="${machine%"${machine##*[![:space:]]}"}" #Removes Trailing Spaces
    
    #############################################
    # Quick hack to find out if the installed OS image is a x86 or x64
    system64="/ntfs/Windows/SysWOW64/regedit.exe" # sloppy detect if 64bit or not
    [[ ! -f $system64 ]] && arch="x86" || arch="x64"
    
    #############################################
    #this section has been updated to bring the osn names in line
    # with how the Dell CABs are defined
    case $osid in
        5) osn="win7" ;;
        6) osn="win8" ;;
        7) osn="win8.1" ;;
        9) osn="win10" ;;
    esac
    
    #############################################
    dots "Preparing Drivers"
    # below creates local folder on imaged pc
    # this can be anywhere you want just remember
    # to make sure it matches throughout! (case IS important here)
    clientdriverpath="/ntfs/Windows/DRV"
    remotedriverpath="/images/drivers/$machine/$osn/$arch"
    
    [[ ! -d $clientdriverpath ]] && mkdir -p "$clientdriverpath" >/dev/null 2>&1
    echo -n "In Progress"
    
    #there's 3 ways you could handle this,
    #driver cab file, extracted driver files or both
    #so on the server put extracted driver files to match below folder tree
    #i.e. Model Latitude E5410, Windows 7 x86 image would be:
    #/fog/Drivers/Latitude E5410/win7/x86
    
    rsync -aqz "$remotedriverpath" "$clientdriverpath" >/dev/null 2>&1
    [[ ! $? -eq 0 ]] && handleError "Failed to download driver information for [$machine/$osn/$arch]"
    
    #this next bit adds driver location on pc to devicepath in registry (so sysprep uses it to reference)
    # remember to make devicepath= match the path you've used locally
    #also do not remove %SystemRoot%\inf
    #and to add more locations just use ; in between each location
    
    regfile="/ntfs/Windows/System32/config/SOFTWARE"
    key="\Microsoft\Windows\CurrentVersion\DevicePath"
    devpath="%SystemRoot%\DRV;%SystemRoot%\inf;";
    reged -e "$regfile" &>/dev/null <<EOFREG
    ed $key
    $devpath
    q
    y
    EOFREG
    echo -e "\b\b\b\b\b\b\b\b\b\b\b${ceol}Done"; # this just removes "In Progress and replaces it with done :-)"
    
    

    I can tell you that this section works for Windows 7 and older (no idea on Win8 or Win8.1), but it DOES NOT WORK with Win10. Windows 10 no longer references this registry key to locate its drivers. For Win10 you must enter this information into the unattend.xml file.

    
    regfile="/ntfs/Windows/System32/config/SOFTWARE"
    key="\Microsoft\Windows\CurrentVersion\DevicePath"
    devpath="%SystemRoot%\inf;%SystemRoot%\DRV";
    reged -e "$regfile" &>/dev/null <<EOFREG
    ed $key
    $devpath
    q
    y
    EOFREG
    echo -e "\b\b\b\b\b\b\b\b\b\b\b${ceol}Done"; # this just removes "In Progress and replaces it with done :-)"
    
    

    0_1478217813029_fog.drivers

    For WIN10 you must update the unattend.xml file to include this section. This is an example for the amd64 arch.

        <settings pass="offlineServicing">
            <component name="Microsoft-Windows-PnpCustomizationsNonWinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                <DriverPaths>
                    <PathAndCredentials wcm:action="add" wcm:keyValue="1">
                        <Path>C:\Windows\DRV</Path>
                    </PathAndCredentials>
                </DriverPaths>
            </component>
        </settings>
    
  • Moderator

    fog.ad

    This script can be used to update files on the target computer. In this case we’ll use it to update the unattend.xml file with install time data like host name, connect to AD or what ever you need. I can say if you use the FOG client to do this stuff, then this script isn’t really needed. But its here to show you what’s possible.

    #!/bin/bash
    hostadpwd="ADPASSWDHERRE"; #only downside to this method- this is the plain ad password
    unattends=$(find /ntfs/ -iname "unattend.xml")
    for unattend in $unattends
        [[ ! -f $unattend ]] && return
        dots "Preparing Sysprep File"
        #rm -f /ntfs/Windows/System32/sysprep/unattend.xml >/dev/null 2>&1
        #if [[ ! $? -eq 0 ]]; then
            #echo "Failed"
            #debugPause
            #handleError "Failed to remove original unattend file"
        #fi
        echo "Done"
        debugPause
        dots "Writing Computer Name to $unattend"
        sed -i "/ComputerName/s/*/$hostname/g" $unattend >/dev/null 2>&1
        if [[ ! $? -eq 0 ]]; then
            echo "Failed"
            debugPause
            handleError "Failed to update originating unattend file"
        fi
        echo "Done"
        echo "ComputerName set to $hostname in $unattend"
        debugPause
        [[ -z $addomain ]] && continue
        dots "Set PC to join the domain"
        sed -i "/<JoinWorkgroup>/d" $unattend >/dev/null 2>&1
        if [[ ! $? -eq 0 ]]; then
            echo "Failed"
            debugPause
            handleError "Failed to remove the Workgroup setter"
        fi
        sed -i \
            -e "s|<Password></Password>|<Password>${hostadpwd}</Password>|g" \
            -e "s|<Username></Username>|<Username>${addomain}\\\\${aduser}</Username>|g" \
            -e "s|<MachineObjectOU></MachineObjectOU>|<MachineObjectOU>${adou}</MachineObjectOU>|g" \
            -e "s|<JoinDomain></JoinDomain>|<JoinDomain>${addomain}</JoinDomain>|g" $unattend >/dev/null 2>&1
        if [[ ! $? -eq 0 ]]; then
            echo "Failed"
            debugPause
            handleError "Failed to update user, pass, ou, and domain setter"
        fi
        echo "Done"
        debugPause
    done
    

    0_1478213498187_fog.ad

  • Moderator

    Driver repository structure

    For this process to work you must setup your driver library on the fog server in a certain fashion.

    On your fog server create the drivers directory under the images directory with:
    md /images/drivers
    Below the /images/drivers directory you will create a directory per machine name (that exactly matches what comes from smbios using this command for Dell computers dmidecode -s system-product-name

    The structure should be built to match the varialbles used in the fog.drivers script.

    /images
    ├─/drivers
      ├─$machine
          ├─$osn
            └─$arch
    

    or translated into real values

    /images
    ├─/drivers
      ├─Optiplex 7040
          ├─win10
            └─x64
    

    (my standard workflow will be added here)

361
Online

9.7k
Users

16.1k
Topics

148.4k
Posts