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\

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)
}
Maurice Daly
Maurice has been working in the IT industry since 1999. Technology focus includes Active Directory, Group Policy, Hyper-V, Windows Deployment (SCCM & MDT) and Office 365.

Maurice is a Microsoft MVP since 2017 in the area of Enterprise Mobility

(174)

There are no comments.

Leave a Reply