locked
Just wanted to share a discovery to help with "Driver Management" RRS feed

  • General discussion

  • After finding truly great ways for managing drivers dynamically within MDT, I think I have stumbled upon one of the more efficient ways that offers granularity and simplifies management all at the same time.

    In "CustomSettings.ini" use the following value

    ;Driver Settings (Based on the OSVersion, Image Architecture, Make, and Model of the device)

    DriverGroup001=CreateBaseImage\%OSCurrentVersion_MajorMinor%\%ImageProcessor%

    DriverGroup001=Deploy\%OSCurrentVersion_MajorMinor%\%ImageProcessor%\%Make%\%Model%

    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    'Get OSCurrentVersion_MajorMinor
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    If Not IsNull(oEnvironment.Item("ImageBuild")) And Not (oEnvironment.Item("ImageBuild") = "") Then
        OSCurrentVersion = oEnvironment.Item("ImageBuild")
    Else
        OSCurrentVersion = oEnvironment.Item("OSCurrentVersion")
    End If
        
    If Not IsNull(OSCurrentVersion) And Not (OSCurrentVersion = "") Then
        OSCurrentVersion = Split(OSCurrentVersion, ".")(0) + "." + Split(OSCurrentVersion, ".")(1)
        oEnvironment.Item("OSCurrentVersion_MajorMinor") = OSCurrentVersion
    End If
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    Place the above block of code into your respective "UserExit" scripts. It will generate a variable that contains the first two parts of the operating system version/kernel (6.1, 10.0, etc)

    This is great because the value is set to use the built-in task sequence variable of "ImageBuild" that will contain the version of the windows image you are deploying and should that be blank, it will use the version from the current OS. Also, the built in variable of "ImageProcessor" will always come out as X86 or X64. Now your drivers will pull based on the OS Version, OS Architecture, Make, and Model of the device your are deploying. Provided that your Out-Of-Box Driver folders are created according to this pattern, all you would have to do is maintain the Out-Of-Box Driver folder structure and thus eliminate having to worry about changing driver paths within Task Sequences, etc!

    Your resulting path can be found in the logs, but the path will expand to look like the following...

    "Deploy\6.1\X86\Hewlett-Packard\HP ProBook 640 G1" when deploying (Windows 7 x86)

    "Deploy\6.1\X64\Hewlett-Packard\HP ProBook 640 G1" when deploying (Windows 7 x64)

    "Deploy\6.3\X64\Hewlett-Packard\HP ProBook 640 G1" when deploying (Windows 8.1 x64)

    "Deploy\10.0\X64\Hewlett-Packard\HP ProBook 640 G1" when deploying (Windows 10 x64)

    (That is only if Microsoft does not redesign how those builtin variables are named or formatted!)

    Tested and working great using Microsoft Deployment Toolkit 2013 Update 1 and with Windows 10! We also deploy Windows 7 here, it is working there as well!

    I hope this helps somebody! Have a blessed day folks!







    Tuesday, November 10, 2015 2:36 PM

All replies

  • This is very good work.  One thing you might be able to replace

    %OSCurrentVersion_MajorMinor% with %OSVersionNumber% and skip the userexit code.


    Logs are very important. https://keithga.wordpress.com/2014/10/24/video-mdt-2013-log-files-basics-bdd-log-and-smsts-log/ Mention any customizations you have made.

    Wednesday, November 11, 2015 1:46 AM
  • I do not see %OSVersionNumber% in the logs. How did you generate that variable? The only reason I thought the user exit was best is because in this instance, we need to be able to make use of the %ImageBuild% variable, but only if it is not blank or null. From what I can tell, the %ImageBuild% variable will be blank if you are not using a task sequence that deploys a Windows Image. Should that be the case, it will generate the %OSCurrentVersion_MajorMinor% variable from the currently running OS which is stored in the %OSCurrentVersion% variable generated by MDT. If you see a better way or a method to optimize what is there, please let me know, because the easier something like this is to plugin, the better! I truly appreciate the input bro, Thanks!
    Wednesday, November 11, 2015 4:42 PM
  • I see your point, but if you aren't deploying an image why would you need to establish a drivergroup?

    This is similar to Johan's Total control method with the addition of an OS variable, what's nice about your method is you can copy and paste this into multiple task sequences without the need to modify the value.


    If this post is helpful please vote it as Helpful or click Mark for answer.

    Wednesday, November 11, 2015 5:50 PM
  • It is in ZTIGather.xml.

    Logs are very important. https://keithga.wordpress.com/2014/10/24/video-mdt-2013-log-files-basics-bdd-log-and-smsts-log/ Mention any customizations you have made.

    Wednesday, November 11, 2015 6:23 PM
  • I just realized what else you could use that variable for outside of a drivergroup. It would be to copy files/folders based on OS and Architecture. Then you could maintain a folder structure around that and place a simple step into your task sequence according to those paths. I currently use that and it works great!

    %DEPLOYROOT%\Custom\Files\%OSCurrentVersion_MajorMinor%\%Architecture%

    Added Bonus! (I have a script that makes use of Windows Explorer and Powershell in order to copy the contents of a folder to a destination) It will simply copy the files and folders with progress during a task sequence or in a standalone fashion. Enjoy guys!

    [CmdletBinding()]
    
    Param
    (        	
    	[Parameter(Mandatory=$True)]
    		$Source,
        
        [Parameter(Mandatory=$True)]
    		$Destination
    )
    
    #Clear The Screen
        Clear-Host
    
    #Define Default Action Preferences
        $DebugPreference = "Continue"
        $ErrorActionPreference = "Continue"
        $WarningPreference = "Continue"
    	
    #Define ASCII Characters    
        $Equals = [char]61
        $Space = [char]32
        $SingleQuote = [char]39
        $DoubleQuote = [char]34
        $NewLine = "`n"
    	
    #Set Working Directory  
        $ScriptDir =  $MyInvocation.MyCommand.Definition | Split-Path -Parent
        $ScriptName = [System.IO.Path]::GetFileNameWithoutExtension($MyInvocation.MyCommand.Name)
        $Temp = "$Env:Windir\Temp"
    
    #Start logging script output
        (Start-Transcript -Path "$Temp\$ScriptName.log")
    
    #Query WMI
    	$HostName = (Get-WmiObject -Class Win32_ComputerSystem -Property Name | Select -ExpandProperty Name).Trim().ToUpper()
    	$OSArchitecture = (Get-WmiObject -Class Win32_OperatingSystem -Property OSArchitecture | Select -ExpandProperty OSArchitecture).Replace("-bit", "").Replace("32", "86").Insert(0,"x").ToUpper()
        $OSCaption = ("{1} {2} {3}" -f (Get-WmiObject -Class Win32_OperatingSystem -Property Caption | Select -ExpandProperty Caption).Split(" ").Trim())
        $OSVersion = [Decimal]("{0}.{1}" -f (Get-WmiObject -Class Win32_OperatingSystem -Property Version | Select -ExpandProperty Version).Split(".").Trim())
    
    #Define Functions
    	#Encode a plain text string to a Base64 string
    		Function ConvertTo-Base64 ($String) 
    	        { 
    	            $Encoded = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($String))
    	            Return $Encoded 
    	        }	
    		
        #Decode a Base64 string to a plain text string
    	    Function ConvertFrom-Base64 ($String) 
    	        { 
    	            $Decoded = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($String))
    	            Return $Decoded
    	        }
        
        #Copy Files/Folders using Windows Explorer
            Function Copy-ItemUsingExplorer ([String]$Source, [String]$Destination, [Int]$CopyFlags = 16)
                {  
                    If (!(Test-Path -Path "$Destination")) {[Void](New-Item -Path "$Destination" -ItemType Directory -Force)}
            
                    $CopyFlags = "0x" + [String]::Format("{0:x}", $CopyFlags)
                    
                    $SourceIsFile = (Test-Path -Path $Source -PathType Leaf)
                    $SourceIsFolder = (Test-Path -Path $Source -PathType Container)
                    $DestinationIsFolder = (Test-Path -Path $Destination -PathType Container)
                    
                    If ($SourceIsFile -eq $True)
                        { 
                            $oDestination = (New-Object -ComObject Shell.Application).Namespace($Destination)
                            If ($DestinationIsFolder -eq $True) {$oDestination.CopyHere((Get-Item -Path $Source).FullName, $CopyFlags)}
                        }
                    ElseIf ($SourceIsFolder -eq $True)
                        {
                            $oSource = (New-Object -ComObject Shell.Application).Namespace($Source)
                            $oDestination = (New-Object -ComObject Shell.Application).Namespace($Destination)
                            If ($DestinationIsFolder -eq $True) {$oDestination.CopyHere($oSource.Items(), $CopyFlags)}
                        }
                }
    		
    #If the script IS being run within a Microsoft Deployment Toolkit Task Sequence, perform the following steps
    	
        If (Test-Path -Path TSEnv: -ErrorAction SilentlyContinue)
            
    	    {			
                $ExecuteCopy = (Copy-ItemUsingExplorer -Source "$Source" -Destination "$Destination")
            }					
    	
    #If the script IS NOT being run within a Microsoft Deployment Toolkit Task Sequence, perform the following steps	
        
        ElseIf (!(Test-Path -Path TSEnv: -ErrorAction SilentlyContinue))
    		
    		{		
                $ExecuteCopy = (Copy-ItemUsingExplorer -Source "$Source" -Destination "$Destination")
            }
    
    #Wait The Specified Amount Of Time
        Start-Sleep -Seconds "15"
    
    #Echo The Values Of Supplied Arguments
        Write-Host ("Microsoft Deployment Toolkit Variable Drive Present = " + (Test-Path -Path TSEnv: -ErrorAction SilentlyContinue))
        Write-Host ("Operating System Architecture = " + $OSArchitecture)
        Write-Host ("Operating System Caption = " + $OSCaption)
        Write-Host ("Operating System Kernel Version = " + $OSVersion)
        Write-Host ("Source = " + $Source)
        Write-Host ("Destination = " + $Destination)
        
    #Stop logging script output
        (Stop-Transcript)

    Thursday, November 12, 2015 3:23 PM