SCCM Dell Client Bios & Driver Autodownload PowerShell Script


dell
If you are a Dell hardware house then this script might come in useful for you.

As you are probably aware Dell provide excellent support for SCCM deployments via their Dell Command integration software and up to date driver cab files via their Enterprise Client Deployment site at http://en.community.dell.com/techcenter/enterprise-client/w/wiki/2065.dell-command-deploy-driver-packs-for-enterprise-client-os-deployment.

dellsccmscreen1

When I was refreshing my driver and bios update file repository I got thinking wouldn’t it be nice if I could just run a script that would download these update files based on the models of Dell client systems listed in my SCCM device collections?.

I found a script on Dustin Hedges blog (https://deploymentramblings.wordpress.com/2014/04/17/downloading-dell-driver-cab-files-automagically-with-the-driver-pack-catalog/) but I wanted to automate this further.

So here is my resulting effort. The below scripts requires you to specify your driver file share and your SCCM site server name as a variable, it then does the following;

  1. Queries SCCM for a full list of Dell enterprise client products (Optiplex & Latitude)
  2. Downloads BIOS updates for each model
  3. Downloads the driver CAB for each model
  4. Extract the driver CAB
  5. Import the drivers in the extracted CAB folder
  6. Create a Category based on the machine model
  7. Create a Driver Package based on the machine model and filename
  8. Imports the associated drivers into the newly created Driver Package
  9. Creates a BIOS Update Package based on machine model
  10. Creates a BIOS update deployment PowerShell script for each model using the latest BIOS update and silent switches

Progress bars have also been added for both the system model and driver import stage.

The downloads are stored within sub-folders within the share you specified, e.g;

\\MySCCMServer\Drivers\Dell Optiplex 7040\BIOS
\\MySCCMServer\Drivers\Dell Optiplex 7040\Driver Cabs\

This slideshow requires JavaScript.

Automatically created SCCM Driver Packages:

dellsccmscreen7

SCCM Driver Package Contents;

dellsccmscreen8

 

Multi-Threaded Script

To run the script use the following syntax;

.\DellDownloads.ps1 -SiteServer YOURSITESERVER -RepositoryPath “\\YOURSERVER\DRIVERREPO\” -PackagePath “\\YOURSERVER\DRIVERPACKPATH”

dellmultithread
Multi-Thread Script In Use (Running Code in PS Console)

Task Sequence BIOS Update Script

In the latest release BIOS packaging is included, it also generates a PowerShell script for use at deployment time which is contained within the BIOS folder of the model and uses the latest BIOS exe with silent switches for a silent upgrade.

Note: If you are using a BIOS setup password (which you should be), you will need to specify this within the script (unless you want me to update the script to look for this run running it from the shell).

Modify the following line – $BIOSSwitches = ” -noreboot -nopause /p=%YOURBIOSPASSWORD ”

This slideshow requires JavaScript.

 

UPDATE LOG

08/11/2016
The script has been updated with the following functionality;

  1. Creates BIOS packages for each model downloaded
  2. Creates a deployment PowerShell script containing the latest BIOS exe name and switches for a silent / no reboot update of the BIOS
  3. If the script is re-run it will automatically update the BIOS exe to use in the deployment PS script and update the distribution points.

28/10/2016
As a response to feedback, I have added a $MaxConcurrent jobs variable into the multi-threaded script that lets you specify the max number of jobs in order to control CPU utilization.

26/10/2016
I have added in an additional script below which is multi-threaded. This should help reduce the overall time to download, extract and create the driver packages in large environments with a wide range of models.

16/10/2016
Additional functionality has been added to now automate the process of extracting the CAB, creating computer categories, import the drivers into SCCM and create a driver pack for each of the models / driver packs downloaded.

Script Download Link – https://gallery.technet.microsoft.com/scriptcenter/SCCM-Dell-Client-Bios-ee577b04?redir=0

<#
.NOTES
===========================================================================
Created with: SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.128
Created on: 16/10/2016 13:00
Created by: Maurice Daly
Filename: DellDownloads.ps1
===========================================================================
.DESCRIPTION
This script allows you to automate the process of keeping your Dell
driver and BIOS update sources up to date. The script reads the Dell
SCCM driver pack site for models you have specified and then downloads
the corresponding latest driver packs and BIOS updates.

Version 1.0
Retreive Dell models and download BIOS and Driver Packs
Version 2.0
Added driver CAB file extract, create new driver pack, category creation
and import driver functions.
Version 2.1
Added multi-threading
Version 2.2
Added Max Concurrent jobs setting for limiting CPU utilisation
Version 2.3
Replaced Invoke-WebRequest download with BITS enabled downloads for
improved performance
Version 2.4
Updated code and separated functions. Added required variables via commandline
Version 3.0
Creates BIOS Packages for each model and writes update powershell file for deployment
with SCCM.

Notes
You can skip the driver package creation process by changing the
$DriverPackageCreation variable to $False.
The system architecture can also be changed by modifying the
$Architecture variable and using x64 or x86

To re-enable error messaging for troubleshooting purpose
comment out the Error and Warning Preference values below

Use : This script is provided as it and I accept no responsibility for
any issues arising from its use.

Twitter : @modaly_it
Blog : https://modalyitblog.com/
#>
[CmdletBinding(SupportsShouldProcess = $true)]
param (
[parameter(Mandatory = $true, HelpMessage = "Site server where the SMS Provider is installed", Position = 1)]
[ValidateNotNullOrEmpty()]
[ValidateScript({ Test-Connection -ComputerName $_ -Count 1 -Quiet })]
[string]$SiteServer,
[parameter(Mandatory = $true, HelpMessage = "UNC path for downloading and extracting drivers")]
[ValidateNotNullOrEmpty()]
[ValidateScript({ Test-Path $_ })]
[string]$RepositoryPath,
[parameter(Mandatory = $true, HelpMessage = "UNC path of your driver package repository")]
[ValidateNotNullOrEmpty()]
[ValidateScript({ Test-Path $_ })]
[string]$PackagePath
)

$ErrorActionPreference = 'SilentlyContinue'
$WarningPreference = 'SilentlyContinue'

# Define Maximum Number Of Simultaneously Running Jobs
$MaxConcurrentJobs = 5

$ErrorActionPreference = 'SilentlyContinue'
$WarningPreference = 'SilentlyContinue'

# Import SCCM PowerShell Module
$ModuleName = (get-item $env:SMS_ADMIN_UI_PATH).parent.FullName + "\ConfigurationManager.psd1"
Import-Module $ModuleName

# Query SCCM Site Code
function QuerySiteCode ($SiteServer)
{
Write-Debug "Determining SiteCode for Site Server: '$($SiteServer)'"
$SiteCodeObjects = Get-WmiObject -Namespace "root\SMS" -Class SMS_ProviderLocation -ComputerName $SiteServer -ErrorAction Stop
foreach ($SiteCodeObject in $SiteCodeObjects)
{
if ($SiteCodeObject.ProviderForLocalSite -eq $true)
{
$SiteCode = $SiteCodeObject.SiteCode
Write-Debug "SiteCode: $($SiteCode)"

}
}
Return [string]$SiteCode
}

function QueryModels ($SiteCode)
{
# ArrayList to store the Dell models in
$DellProducts = New-Object -TypeName System.Collections.ArrayList
# Enumerate through all models
$Models = Get-WmiObject -Namespace "root\SMS\site_$($SiteCode)" -Class SMS_G_System_COMPUTER_SYSTEM | Select-Object -Property Model | Where-Object { ($_.Model -like "*Optiplex*") -or ($_.Model -like "*Latitude*") }
# Add model to ArrayList if not present
if ($Models -ne $null)
{
foreach ($Model in $Models)
{
if ($Model.Model -notin $DellProducts)
{
$DellProducts.Add($Model.Model) | Out-Null
}
}
}
Return $DellProducts
}

function StartDownloadAndPackage ($PackagePath, $RepositoryPath, $SiteCode, $DellProducts)
{
$RunDownloadJob = {
Param ($Model,
$SiteCode,
$PackagePath,
$RepositoryPath)

# =================== DEFINE VARIABLES =====================
# Import SCCM PowerShell Module
$ModuleName = (get-item $env:SMS_ADMIN_UI_PATH).parent.FullName + "\ConfigurationManager.psd1"
Import-Module $ModuleName

# Directory used for driver downloads
$DriverRepositoryRoot = ($RepositoryPath.Trimend("\") + "\Dell\")
Write-Host "Driver package path set to $DriverRepositoryRoot"

# Directory used by SCCM for driver package
$DriverPackageRoot = $PackagePath
Write-Host "Driver package path set to $DriverPackageRoot"

# Define Operating System
$OperatingSystem = "Windows 10"
$Architecture = "x64"

# Define Dell Download Sources
$DellDownloadList = "http://downloads.dell.com/published/Pages/index.html"
$DellDownloadBase = "http://downloads.dell.com"
$DellSCCMDriverList = "http://en.community.dell.com/techcenter/enterprise-client/w/wiki/2065.dell-command-deploy-driver-packs-for-enterprise-client-os-deployment"
$DellSCCMBase = "http://en.community.dell.com"

# Import Driver Packs?
$DriverPackCreation = $true

# =================== INITIATE DOWNLOADS ===================

# ============= BIOS Upgrade Download ==================

Write-Host "Getting download URL for Dell client model: $Model"
$ModelLink = (Invoke-WebRequest -Uri $DellDownloadList).Links | Where-Object { $_.outerText -eq $Model }
$ModelURL = (Split-Path $DellDownloadList -Parent) + "/" + ($ModelLink.href)

# Correct slash direction issues
$ModelURL = $ModelURL.Replace("\", "/")
$BIOSDownload = (Invoke-WebRequest -Uri $ModelURL -UseBasicParsing).Links | Where-Object { ($_.outerHTML -like "*BIOS*") -and ($_.outerHTML -like "*WINDOWS*") } | select -First 1
$BIOSFile = $BIOSDownload.href | Split-Path -Leaf

# Check for destination directory, create if required and download the BIOS upgrade file
if ((Test-Path -Path ($DriverRepositoryRoot + $Model + "\BIOS")) -eq $true)
{
if ((Test-Path -Path ($DriverRepositoryRoot + $Model + "\BIOS\" + $BIOSFile)) -eq $false)
{
Write-Host -ForegroundColor Green "Downloading $($BIOSFile) BIOS update file"
# Invoke-WebRequest ($DellDownloadBase + $BIOSDownload.href) -OutFile ($DriverRepositoryRoot + $Model + "\BIOS\" + $BIOSFile) -UseBasicParsing
Start-BitsTransfer ($DellDownloadBase + $BIOSDownload.href) -Destination ($DriverRepositoryRoot + $Model + "\BIOS\" + $BIOSFile)
}
else
{
Write-Host -ForegroundColor Yellow "Skipping $BIOSFile... File already downloaded..."
}
}
else
{
Write-Host -ForegroundColor Green "Creating $Model download folder"
New-Item -Type dir -Path ($DriverRepositoryRoot + $Model + "\BIOS")
Write-Host -ForegroundColor Green "Downloading $($BIOSFile) BIOS update file"
# Invoke-WebRequest ($DellDownloadBase + $BIOSDownload.href) -OutFile ($DriverRepositoryRoot + $Model + "\BIOS\" + $BIOSFile) -UseBasicParsing
Start-BitsTransfer ($DellDownloadBase + $BIOSDownload.href) -Destination ($DriverRepositoryRoot + $Model + "\BIOS\" + $BIOSFile)
}

# ============= SCCM Driver Cab Download ==================

Write-Host "Getting SCCM driver pack link for model: $Model"
$ModelLink = (Invoke-WebRequest -Uri $DellSCCMDriverList -UseBasicParsing).Links | Where-Object { ($_.outerHTML -like "*$Model*") -and ($_.outerHTML -like "*$OperatingSystem*") } | select -First 1
$ModelURL = $DellSCCMBase + ($ModelLink.href)

# Correct slash direction issues
$ModelURL = $ModelURL.Replace("\", "/")
$SCCMDriverDownload = (Invoke-WebRequest -Uri $ModelURL -UseBasicParsing).Links | Where-Object { $_.href -like "*.cab" }
$SCCMDriverCab = $SCCMDriverDownload.href | Split-Path -Leaf

# Check for destination directory, create if required and download the driver cab
if ((Test-Path -Path ($DriverRepositoryRoot + $Model + "\Driver Cab\")) -eq $true)
{
if ((Test-Path -Path ($DriverRepositoryRoot + $Model + "\Driver Cab\" + $SCCMDriverCab)) -eq $false)
{
Write-Host -ForegroundColor Green "Downloading $($SCCMDriverCab) driver cab file"
# Invoke-WebRequest ($SCCMDriverDownload.href) -OutFile ($DriverRepositoryRoot + $Model + "\Driver Cab\" + $SCCMDriverCab) -UseBasicParsing
Start-BitsTransfer -Source ($SCCMDriverDownload.href) -Destination ($DriverRepositoryRoot + $Model + "\Driver Cab\" + $SCCMDriverCab)
$SkipDriver = $false
}
else
{
Write-Host -ForegroundColor Yellow "Skipping $SCCMDriverCab... File already downloaded..."
$SkipDriver = $true
}
}
else
{
Write-Host -ForegroundColor Green "Creating $Model download folder"
New-Item -Type dir -Path ($DriverRepositoryRoot + $Model + "\Driver Cab")
Write-Host -ForegroundColor Green "Downloading $($SCCMDriverCab) driver cab file"
#Invoke-WebRequest ($SCCMDriverDownload.href) -OutFile ($DriverRepositoryRoot + $Model + "\Driver Cab\" + $SCCMDriverCab)
Start-BitsTransfer -Source ($SCCMDriverDownload.href) -Destination ($DriverRepositoryRoot + $Model + "\Driver Cab\" + $SCCMDriverCab)
}

# =================== CREATE BIOS UPDATE PACKAGE ===========================

$BIOSUpdatePackage = ("Dell" + " " + $Model + " " + "BIOS UPDATE")
$BIOSUpdateRoot = ($DriverRepositoryRoot + $Model + "\BIOS\")

Set-Location -Path ($SiteCode + ":")
if ((Get-CMPackage -name $BIOSUpdatePackage) -eq $null)
{
Write-Host -ForegroundColor Green "Creating BIOS Package"
New-CMPackage -Name "$BIOSUpdatePackage" -Path $BIOSUpdateRoot -Description "Dell $Model BIOS Updates" -Manufacturer "Dell" -Language English
}
Set-Location -Path $env:SystemDrive
$BIOSUpdateScript = ($BIOSUpdateRoot + "BIOSUpdate.ps1")
$CurrentBIOSFile = Get-ChildItem -Path $BIOSUpdateRoot -Filter *.exe -Recurse | Sort-Object $_.LastWriteTime | select -First 1
if ((Test-Path -Path $BIOSUpdateScript) -eq $False)
{
# Create BIOSUpdate.ps1 Deployment Script
New-Item -Path ($BIOSUpdateRoot + "BIOSUpdate.ps1") -ItemType File
$BIOSSwitches = " -noreboot -nopause "
Add-Content -Path $BIOSUpdateScript ('$CurrentBIOSFile=' + '"' + $($CurrentBIOSFile.name) + '"')
Add-Content -Path $BIOSUpdateScript ('$BIOSSwitches=' + '"' + $($BIOSSwitches) + '"')
Add-Content -Path $BIOSUpdateScript ('Start-Process $CurrentBIOSFile -ArgumentList $BIOSSwitches')
}
else
{
# Check if older BIOS update exists and update BIOSUpdate deployment script
$BIOSFileCount = (Get-ChildItem -Path $BIOSUpdateRoot -Filter *.exe -Recurse).count
if ($BIOSFileCount -gt 1)
{
$OldBIOSFiles = Get-ChildItem -Path $BIOSUpdateRoot -Filter *.exe -Recurse | Where-Object { $_.Name -ne $CurrentBIOSFile.name }

foreach ($OldBIOS in $OldBIOSFiles)
{
(Get-Content -Path $BIOSUpdateScript) -replace $OldBIOS.name, $CurrentBIOSFile.name | Set-Content -Path $BIOSUpdateScript
}
}
}
# Refresh Distribution Points
Get-CMPackage -name $BIOSUpdatePackage | Update-CMDistributionPoint
}

# =================== CREATE DRIVER PACKAGE AND IMPORT DRIVERS ===================

$DriverSourceCab = ($DriverRepositoryRoot + $Model + "\Driver Cab\" + $SCCMDriverCab)
$DriverExtractDest = ($DriverRepositoryRoot + $Model + "\Extracted Drivers")
$DriverPackageDir = ($DriverSourceCab | Split-Path -Leaf)
$DriverPackageDir = $DriverPackageDir.Substring(0, $DriverPackageDir.length - 4)
$DriverCabDest = $DriverPackageRoot + "\Dell\" + $DriverPackageDir

if ($DriverPackCreation -eq $true)
{
if ((Test-Path -Path $DriverExtractDest) -eq $false)
{
New-Item -Type dir -Path $DriverExtractDest
}
else
{
Get-ChildItem -Path $DriverExtractDest -Recurse | Remove-Item -Recurse -Force
}
New-Item -Type dir -Path $DriverCabDest
Set-Location -Path ($SiteCode + ":")
$CMDDriverPackage = "Dell " + $Model + " " + "(" + $DriverPackageDir + ")" + " " + $Architecture
if (Get-CMDriverPackage -Name $CMDDriverPackage)
{
Write-Host -ForegroundColor Yellow "Skipping.. Driver package already exists.."
}
else
{
Write-Host -ForegroundColor Green "Creating driver package"
Set-Location -Path $env:SystemDrive
Expand "$DriverSourceCab" -F:* "$DriverExtractDest"
$DriverINFFiles = Get-ChildItem -Path $DriverExtractDest -Recurse -Filter "*.inf" | Where-Object { $_.FullName -like "*$Architecture*" }
Set-Location -Path ($SiteCode + ":")
# Get-Location | Out-File -FilePath C:\Location2.txt
New-CMDriverPackage -Name $CMDDriverPackage -path ($DriverPackageRoot + "\Dell\" + $DriverPackageDir + "\" + $OperatingSystem + "\" + $Architecture)
if (Get-CMCategory -CategoryType DriverCategories -name ("Dell " + $Model))
{
Write-Host -ForegroundColor Yellow "Category already exists"
$DriverCategory = Get-CMCategory -CategoryType DriverCategories -name ("Dell " + $Model)
}
else
{
Write-Host -ForegroundColor Green "Creating category"
$DriverCategory = New-CMCategory -CategoryType DriverCategories -name ("Dell " + $Model)
}
$DriverPackage = Get-CMDriverPackage -Name $CMDDriverPackage
foreach ($DriverINF in $DriverINFFiles)
{
$DriverInfo = Import-CMDriver -UncFileLocation ($DriverINF.FullName) -ImportDuplicateDriverOption AppendCategory -EnableAndAllowInstall $True -AdministrativeCategory $DriverCategory | Select-Object *
Add-CMDriverToDriverPackage -DriverID $DriverInfo.CI_ID -DriverPackageName $CMDDriverPackage
}
}
Set-Location -Path $env:SystemDrive
}

$TotalModelCount = $DellProducts.Count
$RemainingModels = $TotalModelCount
foreach ($Model in $DellProducts)
{
write-progress -activity "Initiate Driver Download &amp;amp;amp; Driver Package Jobs" -status "Progress:" -percentcomplete (($TotalModelCount - $RemainingModels)/$TotalModelCount * 100)
$RemainingModels--
$Check = $false
while ($Check -eq $false)
{
if ((Get-Job -State 'Running').Count -lt $MaxConcurrentJobs)
{
Start-Job -ScriptBlock $RunDownloadJob -ArgumentList $Model, $SiteCode, $PackagePath, $RepositoryPath -Name ($Model + " Download")
$Check = $true
}
}
}
Get-Job | Wait-Job | Receive-Job
Get-Job | Remove-Job
}

# Get SCCM Site Code
$SiteCode = QuerySiteCode ($SiteServer)

Write-Debug $PackagePath
Write-Debug $RepositoryPath

if ($SiteCode -ne $null)
{
# Query Dell Products in SCCM using QueryModels function
$DellProducts = QueryModels ($SiteCode)
# Output the members of the ArrayList
if ($DellProducts.Count -ge 1)
{
foreach ($ModelItem in $DellProducts)
{
$PSObject = [PSCustomObject]@{
"Dell Models Found" = $ModelItem
}
Write-Output $PSObject
Write-Debug $PSObject
}
}
# Start download, extract, import and package process
Write-Host -ForegroundColor Green "Starting download, extract, import and driver package build process.."
StartDownloadAndPackage ($PackagePath) ($RepositoryPath) ($SiteCode) ($DellProducts)
}

38 thoughts on “SCCM Dell Client Bios & Driver Autodownload PowerShell Script

  1. Shelby December 22, 2016 / 6:00 pm

    The following is more of a critique on Dell nomenclature than your script but I am getting errors with the following models.

    “Optiplex 9030 AIO”
    “Latitude 5175”

    Keep in mind these model names/numbers are derived from WMI.

    Looking into $DellDownloadList, They list the Optiplex 9030 AIO as “OptiPlex 9030 All In One” and the 5175 as “Latitude 5175 2-in-1.”

    I don’t know how you would code around this. You can’t just wildcard around the number because several models have the same model number but a different form factor, i.e. …

    OptiPlex 9020
    OptiPlex 9020 All In One
    OptiPlex 9020M

    I am sure there is a way to work around this I am just not a strong enough coder to think of it.

    Also how are you planning on handling new versions and legacy clean up? Would new files go into the existing package or would you create a new package altogether? If existing, don’t forget to update the DP. If it’s a new package, maybe allow one legacy package and remove others so you aren’t whacking a production package.

  2. Shelby December 22, 2016 / 5:37 pm

    Really great stuff, Maurice. Now to go brag to the other SCCM admin about all the “work” I just did 🙂

    I am subbed to this thread so will check back in whenever new updates come out.

    Thanks again!

      • Shelby December 22, 2016 / 6:03 pm

        Will do! Poking around there now trying to find something else to earn some points at work.

        Also, sorry my replies are all over the place. It’s sometimes hard to maintain a thread on these wordpress pages.

        • Maurice Daly December 22, 2016 / 6:05 pm

          No problem. Drop me a mail at Maurice.Daly@outlook.com with a list of things you’d think would be useful as it’s great to get good feedback and we can discuss these further.

          All the best

          Maurice

  3. Shelby December 21, 2016 / 8:04 pm

    Hey Maurice,

    Any way to run this exclusively for the BIOS download and package creation?

    Thanks,
    Shelby

    • Maurice Daly December 21, 2016 / 8:07 pm

      Hi Shelby,

      That option isn’t there at present but I can easily add that in for you if you wish.

      Maurice

  4. Steve (@StevePetroski) December 13, 2016 / 2:34 pm

    Hi Maurice. Thanks for this. It’s really a huge time saver. I asked in the Q&A on technet about restarting and here’s why. First I have like 30+ dell models in the environment so this took a while. During that time someone else logged into the server. When I logged on the script was still on the screen but looked to be interrupted. It started again but I’ve noticed some issues. First I have some packages that are empty, no drivers. Also, and this is a bit odd but most, but not all of the newly created driver packages have source versions in the 100’s. I would have thought they would all be source version 1 but i’m seeing source versions on these packages like 138, 118, 123.
    I’m thinking about clearing this all out and running the script again overnight when I know no one else will be on the server.

    One more thought. Is there any want to select the machines I want to create packages for? I have 30+ Dell systems but really only want to create packages for 29 of them.

    Again, thanks for this script!

    -Steve

    • Maurice Daly December 13, 2016 / 11:21 pm

      Hi Steve,

      Thanks for the feedback and good to see it has been a help. I could look at allowing you to select the models returned from SCCM or alternatively adding a switch to allow you to specify the models. I hope to wrap this all up in a GUI in the next release.

      Maurice

  5. Corey December 3, 2016 / 5:44 am

    HI Guys

    Looks great and when I get it going it will save so much time its not funny -,

    However, I am getting to the Downloading Driver Cab File section and the script is just stopping.
    I have copied the Script from above and downloaded from Technet but result is the same

    I am running it on my site server in Powershell console (not ise) The script downloads the Bios update so i dont think its an access issue.

    Im guessing its probably something silly but any thoughts? what logs can i check etc

    Thanks in advance

    • Maurice Daly December 5, 2016 / 12:02 am

      Hi Corey,

      Could you mail me over a list of the Dell models pulled from SCCM so I can have a look at this and also let me know which OS you specified.

      Maurice

  6. Joe Crowe November 19, 2016 / 6:16 am

    I’m sure I’m doing something wrong. The script completes without an error. (Using v3 copied from above vs the older script available from technet gallery). The BIOS and Driver cabs get downloaded to the repository path as expected. The BIOS packages get created, but w/o any programs. No driver packages get created. The packagepath directory remains empty. I ran the script as an admin on the site server (not using ISE). The command I used is:
    .\DellDownloads.ps1 -SiteServer sccm1 -RepositoryPath ‘\\sccm1\d$\Drivers\Dell’ -PackagePath ‘\\sccm11\d$\Packages\DellDrivers’

    • modalyit November 19, 2016 / 11:40 am

      Hi Joe, by the looks of it you might have a typo in your packagepath. You have a different server name labelled \\sccm11 compared to your repository path of \\sccm1. As for the BIOS package, there isn’t a program created as such, inside of the folder you should see a PowerShell script which contains the switches needed to upgrade the BIOS. Use this in a Run PowerShell Script within your TS to upgrade the BIOS (a separate blog post is to follow on the Dell CCTK). I’ll add in a create program function if need that also.

      • Joe Crowe November 19, 2016 / 12:22 pm

        Thanks for the response! I sanitized the server name before posting (and then introduced confusion by mistyping my fake server name). I used tab-autocomplete to populate the paths, so I’m certain I did that portion correctly.

        Do you know if the script would have any issue with the “d$” in my paths? If not that, then what else might be awry?

        • modalyit November 19, 2016 / 9:53 pm

          Hi Joe,

          Given that it is downloading the drivers and progressing through the BIOS package creation, I would suggest it might be a permissions based issue with the driver package repository. If you comment out the following lines you will see any warnings / errors about file paths etc;

          $ErrorActionPreference = ‘SilentlyContinue’
          $WarningPreference = ‘SilentlyContinue’

          I will also add in some debug steps into the script for troubleshooting purposes.

  7. Kevin October 27, 2016 / 6:36 pm

    Just a quick update for everyone following this: Maurice has been a huge help today and helped me via Teamviewer. I started the script in PowerShell ISE instead of the normal PowerShell console. That was the problem, now everything is working. 🙂

    • modalyit October 28, 2016 / 10:45 am

      Hi Kevin,

      Thanks for the feedback by email. I have added in the requested Max Concurrent jobs variable so you can now limit your CPU utilization during the download / package phase.

  8. Kevin October 27, 2016 / 10:55 am

    It’s not working, I just copied it again. I also get this in line 49:

    + Begin
    + ~~~~~
    + CategoryInfo : ObjectNotFound: (Begin:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    • modalyit October 27, 2016 / 11:02 am

      I’ve just sent you an email..

  9. Kevin October 27, 2016 / 10:11 am

    Hi Maurice,

    yes I’m running the script on the site server. I’m using the multi-threaded script.

    Thanks!

    Best regards
    Kevin

    • modalyit October 27, 2016 / 10:33 am

      Hi Kevin,

      OK so stepping through this one step at a time, if you run lines 38-97 do you get any returned values for the $DellProducts or $Models arrays?.

      Maurice

    • modalyit October 27, 2016 / 10:36 am

      Actually Kevin it looks like that there might have been an issue pasting my script into WordPress. I have just pasted in the script again and run it with no issue. Can you either copy it off of the site or I can email you a copy.

  10. Kevin October 27, 2016 / 9:39 am

    Hi there, first of all thanks for this script. I can’t get it to work, here is what happens. I edit all the variables (SCCM Server, Path to the ConfigurationManager.psd1 because our SCCM is setup on the D: drive and source share path.)

    When I run the script, it gives me the following output and nothing else happens:

    # Determine SiteCode from WMI
    try
    {
    Write-Verbose “Determining SiteCode for Site Server: ‘$($SiteServer)'”
    $SiteCodeObjects = Get-WmiObject -Namespace “root\SMS” -Class SMS_ProviderLocation -ComputerName $SiteServer -ErrorAction Stop
    foreach ($SiteCodeObject in $SiteCodeObjects)
    {
    if ($SiteCodeObject.ProviderForLocalSite -eq $true)
    {
    $SiteCode = $SiteCodeObject.SiteCode
    Write-Debug “SiteCode: $($SiteCode)”
    }
    }
    }
    catch [Exception] {
    Throw “Unable to determine SiteCode”
    }

    Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
    ——- —— —– —– —– —— — ———–
    439 36 146676 132868 1597 86,28 4328 AFD2DMonitor
    323 14 8896 14932 68 7,80 5644 AgPkiMon
    2345 31 28252 32480 547 1,52 1256 AIUpdateSVC
    ….
    ….

    # ArrayList to store the Dell models in
    $DellProducts = New-Object -TypeName System.Collections.ArrayList
    # Enumerate through all models
    $Models = Get-WmiObject -Namespace “root\SMS\site_$($SiteCode)” -Class SMS_G_System_COMPUTER_SYSTEM | Select-Object -Property Model | Where-Object { ($_.Model -like
    “*Optiplex*”) -or ($_.Model -like “*Latitude*”) }
    # Add model to ArrayList if not present
    if ($Models -ne $null)
    {
    foreach ($Model in $Models)
    {
    if ($Model.Model -notin $DellProducts)
    {
    $DellProducts.Add($Model.Model) | Out-Null
    }
    }
    }
    # Output the members of the ArrayList
    if ($DellProducts.Count -ge 1)
    {
    foreach ($ModelItem in $DellProducts)
    {
    $PSObject = [PSCustomObject]@{
    Model = $ModelItem
    }
    Write-Output $PSObject
    }
    }

    PS C:\Windows\system32>

    I also tried to set the site code manually because apparently the script can’t find it correctly but it doesn’t help either.

    Best regards
    Kevin

    • modalyit October 27, 2016 / 9:43 am

      Hi Kevin,

      Just checking first of all that you are running the script on your Site Server?. Can you also let me know if you are running the single or multi-threaded script.

      Regards

      Maurice

      • Shelby December 21, 2016 / 8:23 pm

        That would be awesome.

        I would like to implement the drivers piece but we are a large organization (Fortune 500) and completely revamping our driver management would take some work whereas the BIOS change would go in as net-new since we aren’t currently cataloging and deploying BIOS upgrades.

        If there is anything I can do to help, please let me know.

        Also, looking forward to seeing what you come up with in regards to a GUI for all of this.

        • Maurice Daly December 21, 2016 / 10:18 pm

          No problem at all, the feedback I got initially was the majority of people just wanted a means to exclude the BIOS updates but I have no problem adding in the option for BIOS only.

          One thing to remember is that the Powershell script that is created with the update switches, requires the BIOS password to be blank. I handle this in my environment by blanking the password before the step in the TS and then adding the password back in following the update as this saves you hard coding BIOS passwords.

        • Shelby December 22, 2016 / 4:14 pm

          Here’s my results …

          It definitely didn’t run. Wasn’t sure whether to use the redo or pkg source so just used both to see what it would do.
          Also just threw in OS and Arch switch just to be sure.

          Let me know what I can fix.

        • Maurice Daly December 22, 2016 / 4:19 pm

          Looking at the error it was unable to determine your SCCM site code. Are you running the script on your SCCM server or remotely?.

        • Shelby December 22, 2016 / 4:35 pm

          I was running it remotely but after running it on the server I get the following …

          (Sorry for phone captures. All photo sharing sites are blocked at the office)

          It’s no longer giving me errors and appears to be working but low network traffic and empty file directories say otherwise.

          And I should have said this in my initial response, thank you.

        • Maurice Daly December 22, 2016 / 4:43 pm

          Do you have direct Internet access on the server or are you going through a proxy?

        • Shelby December 22, 2016 / 5:23 pm

          Okay, I got it to run after lowering the -MaxConcurrentJob value down from 5 to 1.

          Awesome tool, but some feedback that would make this better fit my use case (and others I would think), if you included the version of the BIOS both in the file folder structure as well as within the SCCM package name, that would be helpful. As it stands, there doesn’t appear to be any version checking. So basically “Take these models, go grab bios, dump here” whereas I would be great if it could do “Take these models, check their bios ver, check latest available bios. Is new available? Yes = download, catalog, package, etc.”

          Also, It successfully created several packages with just using the repo switch but near the end of the script some errors were thrown griping about the null package path. If I were to run the same script again? Would it recognize that it has already been ran or will it try and pull down the same files again?

        • Maurice Daly December 22, 2016 / 5:34 pm

          Thanks for the feedback.

          In relation to the BIOS updates I was going to add in a clean up portion to remove any legacy downloaded files. When re-running the script if it detects that files are already downloaded or packages created with the same version it will skip the download/package process.

          I am adding in a log output too for troubleshooting purposes in the next release.

          I hope you found it useful.

          Maurice

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s