Skip to main content

SCCM - Install dell drivers dynamically during OSD

The below script may be used in an SCCM task to download Dell drivers from :
"" to a PC being imaged.

Create a Dell group in the task sequence
Run the Powershell Script to filter dell systems with the WMI query as shown below.

The next step should run the powershell script shown below

Add another step to install dell drivers as using dism

The powershell script is shown below:

#By Tausif for FICO
#download dell drivers directly and install during the SCCM task sequence.

#Logging function borrowed from Mikael Nystrom 
Function Import-SMSTSENV
  $tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
  Write-Output "$ScriptName - tsenv is $tsenv "
  $MDTIntegration = "YES"
  #$tsenv.GetVariables() | % { Write-Output "$ScriptName - $_ = $($tsenv.Value($_))" }
  Write-Output "$ScriptName - Unable to load Microsoft.SMS.TSEnvironment"
  Write-Output "$ScriptName - Running in standalonemode"
  $MDTIntegration = "NO"
  if ($MDTIntegration -eq "YES")
   $Logpath = $tsenv.Value("LogPath")
   $LogFile = $Logpath + "\" + "$ScriptName.log"
   $Logpath = $env:TEMP
   $LogFile = $Logpath + "\" + "$ScriptName.txt"
Function Start-Logging
 start-transcript -path $LogFile -Force
Function Stop-Logging

# Set Vars
$SCRIPTDIR = split-path -parent $MyInvocation.MyCommand.Path
$SCRIPTNAME = split-path -leaf $MyInvocation.MyCommand.Path
$LANG = (Get-Culture).Name
$OSV = $Null

#Try to Import SMSTSEnv

#Start Transcript Logging
. Start-Logging

#Output base info
Write-Output ""
Write-Output "$ScriptName - ScriptDir: $ScriptDir"
Write-Output "$ScriptName - SourceRoot: $SOURCEROOT"
Write-Output "$ScriptName - ScriptName: $ScriptName"
Write-Output "$ScriptName - Log: $LogFile"

Function Set-RegistryKey
 [Parameter(Mandatory=$True,HelpMessage="Please Enter Registry Item Path",Position=1)]
 [Parameter(Mandatory=$True,HelpMessage="Please Enter Registry Item Name",Position=2)]
 [Parameter(Mandatory=$True,HelpMessage="Please Enter Registry Property Item Value",Position=3)]
 [Parameter(Mandatory=$False,HelpMessage="Please Enter Registry Property Type",Position=4)]
 $PropertyType = "DWORD"
 # If path does not exist, create it
 If( (Test-Path $Path) -eq $False ) {
 $newItem = New-Item -Path $Path -Force
 # Update registry value, create it if does not exist (DWORD is default)
 $itemProperty = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
 If($itemProperty -ne $null) {
 $itemProperty = Set-ItemProperty -Path $Path -Name $Name -Value $Value
 } Else {
 $itemProperty = New-ItemProperty -Path $Path -Name $Name -Value $Value -PropertyType $PropertyType

 Function Get-OSVersion() {
# Version numbers as per
$osVersion = "Version not listed"
$os = (Get-WmiObject -class Win32_OperatingSystem)
Switch (($os.Version).Substring(0,3)) {
    "5.1" { $osVersion = "XP" }
    "5.2" { $osVersion = "2003" }
    "6.0" { If ($os.ProductType -eq 1) { $osVersion = "Vista" } Else { $osVersion = "2008" } }
    "6.1" { If ($os.ProductType -eq 1) { $osVersion = "Windows 7" } Else { $osVersion = "2008R2" } }
    "6.2" { If ($os.ProductType -eq 1) { $osVersion = "Windows 8" } Else { $osVersion = "2012" } }
    # 8.1/2012R2 version detection can be broken, and show up as "6.2", as per
    "6.3" { If ($os.ProductType -eq 1) { $osVersion = "Windows 8.1" } Else { $osVersion = "2012R2" } }
    "10." { If ($os.ProductType -eq 1) { $osVersion = "Windows 10" } Else { $osVersion = "2016" } }
return $osVersion

$osversion = Get-OSVersion
Write-Output "$osversion - Log: $LogFile"
$Model = (Get-WmiObject Win32_ComputerSystem).Model
Write-Output "$Model - Log: $LogFile"

### Disable IE First Run Wizard and RSS Feeds this is needed to Invoke-Webrequest will work without running IE for the first time.
Set-RegistryKey -Path "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Main" -Name "DisableFirstRunCustomize" -Value 1

# Remove the "E" prefix character from Latitude models due to some dodgy Dell URLs...
If ($Model.ToCharArray()[0] -eq "E" -and $Model -notmatch "Embedded")
 $Model = $Model.Replace("E", "")
 Write-Output "Model name set to $Model - Log: $LogFile"

# Find the specific wiki page for the model from the main wiki page
$URI = ""
Write-Output "URI set to $URI - Log: $LogFile"
$html = Invoke-WebRequest $URI -ErrorAction Stop -TimeoutSec 1800
Write-Output "$URL queried successfully - Log: $LogFile"
$Href = $HTML.AllElements | Where {$_.innerText -match ("$Model" + " W") -and $_.innerText -match "Windows 10" -and $_.innerText -match "Driver" -and $_.tagName -eq "A"} | Select -ExpandProperty href
If (!$Href)
 Write-Output "No Wiki page found for $Model and $OperatingSystem.- Log: $LogFile"
Write-Output "Wiki page found for $Model and $OperatingSystem. - $Href - Log: $LogFile"
# Find the download URL from the model
$URI = "$Href"

Write-Output "URI updated to $URI - Log: $LogFile"
    $HTML = Invoke-WebRequest -Uri $URI -ErrorAction Stop
    $CabDownloadLink = $HTML.AllElements | Where {$_.innerHTML -match "Download Now" -and $_.tagName -eq "A"} | Select -ExpandProperty href
 #Return $CabDownloadLink
 Write-Output "Cab download link set to $CabDownloadLink - Log: $LogFile"
 Write-Output "Cab download not found- Log: $LogFile"

$CABfilename = $CabDownloadLink.Substring($CabDownloadLink.LastIndexOf("/") + 1)
Write-Output "Cab file name is $CABfilename - Log: $LogFile"
$drivedownloaddirectory = "C:\Temp"

if(!(Test-Path -Path $drivedownloaddirectory )){
 New-Item -ItemType directory -Path $drivedownloaddirectory
 Write-Output "$drivedownloaddirectory created - Log: $LogFile"

$CABDestinationpath = "$drivedownloaddirectory\$CABfilename"
Write-Output "The CAB will be downloaded to $CABDestinationpath - Log: $LogFile"
    # Begin the download
    $WebClient = New-Object System.Net.WebClient
    $WebClient.DownloadFile($CabDownloadLink, $CABDestinationpath)
 Write-Output "Failed to download file - Log: $LogFile"


$DriverSourceCab = (Get-ChildItem $drivedownloaddirectory).FullName
$DriverExtractDest = "$drivedownloaddirectory\Extracted"

if(!(Test-Path -Path $DriverExtractDest )){
 New-Item -ItemType directory -Path $DriverExtractDest
 Write-Output "Created the $DriverExtractDest directory - Log: $LogFile"

Expand "$DriverSourceCab" -F:* "$DriverExtractDest"
#Copy-Item "C:\Windows\System32\pnputil.exe" "X:\Windows\System32"
$driverinfs = get-childitem -path $DriverExtractDest -recurse -filter *.inf
foreach ($inf in $driverinfs)
    Write-Host "Injecting driver $inf"
    #pnputil -i -a $inf.FullName

#this part does not work because for some reason it throws a memory error, will replace this with:

DISM.exe /Image:%OSDTargetSystemDrive%\ /Add-Driver /Driver:c:\Temp\Extracted /Recurse /logpath:%_SMSTSLogPath%\dism.log
. Stop-Logging

This script logs to SMSTS.log directly and the dism step can log to wherever you'd like it to.
Add another step to delete the Extracted drivers and downloaded drivers as needed.


Popular posts from this blog

Removing corporate wireless restrictions completely : "The policies of your network prevent the creation of ad hoc (computer-to-computer) networks. For more information, contact your system administrator."

So i was recently tasked with removing wireless restrictions from a VP's windows 7 laptop that some infrastructure company had placed while contracted with our network, since he needed to enable setting up of adhoc connections on his laptop and he always got

"The policies of your network prevent the creation of ad hoc (computer-to-computer) networks. For more information, contact your system administrator."

A little bit of probing revealed that adhoc and peer to peer connections were blocked as evidenced by the the command 

netsh wlan show filter on an  elevated command prompt revealed that adhoc network type was blocked by group policy:

I removed the restrictions by:

1: open services.msc as administrator, scroll down to WLAN AutoConfig:

To Unlock Windows Update locked due to group policy.

To Unlock Windows Update locked due to group policy.

Open gpedit.msc and browse to the location /Computer Configuration/Administrative Templates/System/Internet Communication Management/Internet Communication Settings and double click "turn off access to all windows update features" and set it to disabled.

Migrating Outlook Profile to Office 365

We had a migration from Hosted Exchange to Office 365 and i was tasked with automating the local Outloook profile migration for Users:

I Created a GUI utility using powershell which would allow users to create an Office365 Profile and set it as default, I prepared PRF files for each version of office and an autodiscover.xml to be used for local autodiscover and uploaded them to a hosted site:

The PRF file to set settings for Office 365 are hard to find: i used the below entries: