SCCM Viglen Client Driver Autodownload PowerShell Script


viglen

In October of 2016 I released a script that downloaded drivers and bios updates for Dell client systems and created associated driver packs in SCCM (https://modalyitblog.wordpress.com/2016/10/10/sccm-dell-client-bios-driver-autodownload-ps-script/).

A friend of mine works in the UK educational system as an admin and thought it would be nice to have a similar script for his environment, mainly consisting of the UK educational hardware builder Viglen.

So here is version 1.0 of the download script adjusted for Viglen client systems.

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 Viglen client products
  2. Downloads the driver INF zip file for each model
  3. Extract the driver INF zip
  4. Import the drivers in the extracted ZIP folder
  5. Create a Category based on the machine model
  6. Create a Driver Package based on the machine model
  7. Imports the associated drivers into the newly created Driver Package

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

\\MySCCMServer\Drivers\Viglen 820s\Driver ZIP\
\\MySCCMServer\Drivers\Viglen 820s\Extracted Drivers\

This slideshow requires JavaScript.

PowerShell Script

To run the script use the following syntax;

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

The script has Windows 10 x64 specified, however you can change this under the #Define Operating Systems section. Note I have tested Windows 7 & 10 only during building this.


<#
.NOTES
===========================================================================
Created with: SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.128
Created on: 03/11/2016 13:00
Created by: Maurice Daly
Filename: ViglenSCCMDownloads.ps1
==========================================================================
.DESCRIPTION
This script allows you to automate the process of keeping your
driver sources up to date. The script reads the Viglen support download
site for models found within SCCM and then downloads the corresponding
drivers

Version 1.0
Initial release

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
You can limit the number of concurrent jobs by specifying
your max value in the $MaxConcurrent jobs variable

To run the script use the following syntax;

.\ViglenSCCMDownload.ps1 -SiteServer YOURSITESERVER -RepositoryPath UNCTEMPDRIVERPATH -PackagePath UNCDRIVERPACKAGEPATH

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.wordpress.com/
#>

# Define SCCM Site Server
[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'

# Import SCCM PowerShell Module
Import-Module "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1"

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

# Query SCCM Site Code
function QuerySiteCode ($SiteServer)
{
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)"

}
}
Return [string]$SiteCode
}

function QueryModels ($SiteCode)
{
# ArrayList to store the Viglen models in
$ViglenProducts = New-Object -TypeName System.Collections.ArrayList
# Enumerate through all models
#$Models = "VIG430P","VIG665W","Vig670W","Vig800S","Vig820S","Vig830S"
$Models = Get-WmiObject -Namespace "root\SMS\site_$($SiteCode)" -Class SMS_G_System_COMPUTER_SYSTEM | Select-Object -Property Model | Where-Object { $_.Model -like "*Vig*" }
# Add model to ArrayList if not present
if ($Models -ne $null)
{
foreach ($Model in $Models)
{
if ($Model.Model -notin $ViglenProducts)
{
$ViglenProducts.Add($Model.Model) | Out-Null
}
}
}
#$ViglenProducts = "VIG430P", "VIG665W", "Vig670W", "Vig800S", "Vig820S", "Vig830S"
Return $ViglenProducts
}

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

# =================== DEFINE VARIABLES =====================

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

# Directory used by SCCM for driver package
$DriverPackageRoot = ($PackagePath.Trimend("\") + "\Viglen\")
Write-Host "Driver package path set to $DriverPackageRoot"

# Define Operating System
$OperatingSystem = "Windows"
$OperatingSystemVersion = "10"
$Architecture = "64"

# Define Viglen Download Sources
$ViglenBaseURL = "http://download.viglen.co.uk"
$ViglenDownloadList = "/files/Motherboards/"
$ViglenBIOSFolder = "BIOS/"
$ViglenDriverFolder = "Drivers/"

# Import Driver Packs?
$DriverPackCreation = $true

# Import SCCM PowerShell Module
Import-Module "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1"

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

Write-Host "Getting download URL for Viglen client model: $Model"
$ModelLink = (Invoke-WebRequest -Uri ($ViglenBaseURL + $ViglenDownloadList) -UseBasicParsing).Links | Where-Object { $_.href -like "*$Model*" }
$ModelURL = ($ViglenBaseURL + $ModelLink.href)

# Correct slash direction issues
$ModelURL = $ModelURL.Replace("\", "/")

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

Write-Host "Getting SCCM driver pack link for model: $Model"
$ViglenInfFolder = (((Invoke-WebRequest -Uri ($ModelURL + $ViglenDriverFolder) -UseBasicParsing).links | Where-Object { $_.href -like "*INF*" }).href | Split-Path -Leaf) + "/"
$SCCMDriverDownload = ((Invoke-WebRequest -Uri ($ModelURL + $ViglenDriverFolder + $ViglenInfFolder) -UseBasicParsing).Links | Where-Object { $_.href -like "*$($OperatingSystem.trim("dows"))*$OperatingSystemVersion*.zip" } | Select-Object -Last 1).href
if ($SCCMDriverDownload -eq $null)
{
# Check for driver folder for specified OS
$DriverOSSubFolder = ((Invoke-WebRequest -Uri ($ModelURL + $ViglenDriverFolder + $ViglenInfFolder) -UseBasicParsing).Links | Where-Object { $_.outerHTML -like "*$OperatingSystem*$OperatingSystemVersion*" }).href | Split-Path -Leaf
if ($DriverOSSubFolder -eq $null)
{
Write-Host -ForegroundColor White -BackgroundColor Red "Driver does not exist for $Model running $OperatingSystem $OperatingSystemVersion"
Break
}
else
{
$SCCMDriverDownload = ((Invoke-WebRequest -Uri ($ModelURL + $ViglenDriverFolder + $ViglenInfFolder + $DriverOSSubFolder) -UseBasicParsing).Links | Where-Object { $_.href -like "*$($OperatingSystem.trim("dows"))*$OperatingSystemVersion*.zip" } | Select-Object -Last 1).href
}
}
else
{
# $SCCMDriverDownload = $SCCMDriverDownload.href
}

$SCCMDriverZIP = ($SCCMDriverDownload | Split-Path -Leaf)

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

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

Write-Host -ForegroundColor Green "Starting extract and import process"
$DriverSourceFile = ($DriverRepositoryRoot + $Model + "\Driver ZIP\" + $SCCMDriverZIP)
$DriverExtractDest = ($DriverRepositoryRoot + $Model + "\Extracted Drivers")
$DriverPackageDir = ($DriverSourceFile | Split-Path -Leaf)
$DriverPackageDir = $DriverPackageDir.Substring(0, $DriverPackageDir.length - 4)
$DriverFileDest = $DriverPackageRoot + "Viglen\" + $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 $DriverFileDest
Set-Location -Path ($SiteCode + ":")
$CMDDriverPackage = "Viglen " + $Model + " " + $OperatingSystem + " " + $OperatingSystemVersion + " " + $Architecture + "bit"
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
Add-Type -assembly "system.io.compression.filesystem"
[io.compression.zipfile]::ExtractToDirectory($DriverSourceFile, $DriverExtractDest)
$DriverINFFiles = Get-ChildItem -Path $DriverExtractDest -Recurse -Filter "*.inf"
}
Set-Location -Path ($SiteCode + ":")
New-CMDriverPackage -Name $CMDDriverPackage -path ($DriverPackageRoot + $Model + "\" + $OperatingSystem + " " + $OperatingSystemVersion + "\" + $Architecture)
if (Get-CMCategory -CategoryType DriverCategories -name ("Viglen " + $Model))
{
Write-Host -ForegroundColor Yellow "Category already exists"
$DriverCategory = Get-CMCategory -CategoryType DriverCategories -name ("Viglen " + $Model)
}
else
{
Write-Host -ForegroundColor Green "Creating category"
$DriverCategory = New-CMCategory -CategoryType DriverCategories -name ("Viglen " + $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 = $ViglenProducts.Count
$RemainingModels = $TotalModelCount
foreach ($Model in $ViglenProducts)
{
write-progress -activity "Initiate Driver Download & 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 Viglen Products in SCCM using QueryModels function
$ViglenProducts = QueryModels ($SiteCode)
# Output the members of the ArrayList
if ($ViglenProducts.Count -ge 1)
{
foreach ($ModelItem in $ViglenProducts)
{
$PSObject = [PSCustomObject]@{
"Viglen Models Found" = $ModelItem
}
Write-Output $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)
}

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