mirror of
https://github.com/freedbygrace/ADDAP.git
synced 2026-07-26 11:08:13 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 742b01a905 | |||
| de2979f1cc | |||
| abe7fcbb68 | |||
| ffe9ceb895 | |||
| fd41fdfb89 |
Binary file not shown.
@@ -1,94 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-16"?>
|
|
||||||
|
|
||||||
<?xml-stylesheet type='text/xsl' href='style.xsl'?>
|
|
||||||
|
|
||||||
<!--Please specify the configuration settings that will be used by the driver package creation powershell script.-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
By default, the settings XML will be automatically modified by the 'Invoke-DriverPackageCreation' script to include the model you execute the script on, but only if it matches one of the manufacturers within the XML.
|
|
||||||
|
|
||||||
To add a model manually, copy and paste the following code into the Powershell ISE on the specific model you want to add to this XML.
|
|
||||||
|
|
||||||
The text will be automatically copied to the clipboard.
|
|
||||||
|
|
||||||
Add the model under the desired manufacturer in order to the entry to be processed correctly.
|
|
||||||
|
|
||||||
### Begin Code Snippet ###
|
|
||||||
$PropertyList = New-Object -TypeName 'System.Collections.Generic.List[Object]'
|
|
||||||
$PropertyList.Add(@{Name = 'Enabled'; Expression = {$True}})
|
|
||||||
$PropertyList.Add('SystemProductName')
|
|
||||||
$PropertyList.Add(@{Name = 'ProductID'; Expression = {$_.BaseboardProduct}})
|
|
||||||
$PropertyList.Add('BaseboardProduct')
|
|
||||||
$PropertyList.Add('SystemSKU')
|
|
||||||
$PropertyList.Add('SystemVersion')
|
|
||||||
$PropertyList.Add('SystemFamily')
|
|
||||||
$PropertyList.Add('SystemManufacturer')
|
|
||||||
|
|
||||||
$MSSystemInformation = Get-CIMInstance -Namespace "root\WMI" -Class "MS_SystemInformation" | Select-Object -Property ($PropertyList)
|
|
||||||
|
|
||||||
$XMLAttributes = $MSSystemInformation.PSObject.Properties | ForEach-Object {"$($_.Name)=`"$($_.Value)`""}
|
|
||||||
|
|
||||||
$XMLNode = "<Model $($XMLAttributes -Join ' ') />"
|
|
||||||
|
|
||||||
Write-Output -InputObject ($XMLNode)
|
|
||||||
|
|
||||||
$Null = $XMLNode | Set-Clipboard -Verbose
|
|
||||||
### End Code Snippet ###
|
|
||||||
|
|
||||||
<ModelList>
|
|
||||||
### Copy and paste the generated text from the clipboard in between the 'ModelList' section for the desired manufacturer ###
|
|
||||||
</ModelList>
|
|
||||||
|
|
||||||
As an example, the following details are available from the following powershell command
|
|
||||||
|
|
||||||
Get-CIMInstance -Namespace 'Root\WMI' -Class 'MS_SystemInformation'
|
|
||||||
|
|
||||||
BaseBoardManufacturer : Dell Inc.
|
|
||||||
BaseBoardProduct : 01Y2TP
|
|
||||||
BaseBoardVersion : A00
|
|
||||||
BiosMajorRelease : 1
|
|
||||||
BiosMinorRelease : 6
|
|
||||||
BIOSReleaseDate : 09/05/2022
|
|
||||||
BIOSVendor : Dell Inc.
|
|
||||||
BIOSVersion : 1.6.1
|
|
||||||
ECFirmwareMajorRelease : 255
|
|
||||||
ECFirmwareMinorRelease : 255
|
|
||||||
InstanceName : ROOT\mssmbios\0000_0
|
|
||||||
SystemFamily : Latitude
|
|
||||||
SystemManufacturer : Dell Inc.
|
|
||||||
SystemProductName : Latitude 5430
|
|
||||||
SystemSKU : 0B04
|
|
||||||
SystemVersion :
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
<Settings>
|
|
||||||
<GeneratedBy>DSW\amote</GeneratedBy>
|
|
||||||
<GeneratedOn>NBAMOTE</GeneratedOn>
|
|
||||||
<GeneratedDate>2022-11-10T15:01</GeneratedDate>
|
|
||||||
<OperatingSystemList>
|
|
||||||
<OperatingSystem Enabled="True" Vendor="Microsoft" Name="Windows 10" NameExpression=".*10.*" ArchitectureExpression=".*64.*" ReleaseExpression=".*" LatestReleaseOnly="True" />
|
|
||||||
<OperatingSystem Enabled="True" Vendor="Microsoft" Name="Windows 11" NameExpression=".*11.*" ArchitectureExpression=".*64.*" ReleaseExpression=".*" LatestReleaseOnly="True" />
|
|
||||||
</OperatingSystemList>
|
|
||||||
<ManufacturerList>
|
|
||||||
<Manufacturer Enabled="True" Name="Dell" EligibilityExpression="(^.*Dell.*$)" ProductIDPropertyName="SystemSKU">
|
|
||||||
<URLs DriverPackCatalog="https://dl.dell.com/catalog/DriverPackCatalog.cab" DownloadBase="https://dl.dell.com" />
|
|
||||||
<ModelList>
|
|
||||||
<Model Enabled="False" SystemProductName="Latitude 5420" ProductID="0A20" BaseboardProduct="0M51J7" SystemSKU="0A20" SystemVersion="" SystemFamily="Latitude" SystemManufacturer="Dell" />
|
|
||||||
</ModelList>
|
|
||||||
</Manufacturer>
|
|
||||||
<Manufacturer Enabled="True" Name="HP" EligibilityExpression="(^.*HP.*$)|(^.*Hewlett.*Packard.*$)" ProductIDPropertyName="BaseboardProduct">
|
|
||||||
<URLs DriverPackCatalog="https://ftp.hp.com/pub/caps-softpaq/cmit/HPClientDriverPackCatalog.cab" DownloadBase="" />
|
|
||||||
<ModelList>
|
|
||||||
<Model Enabled="False" SystemProductName="HP ZBook Studio G7 Mobile Workstation" ProductID="8736" BaseboardProduct="8736" SystemSKU="8YP41AV" SystemVersion="" SystemFamily="103C_5336AN HP ZBook" SystemManufacturer="HP" />
|
|
||||||
</ModelList>
|
|
||||||
</Manufacturer>
|
|
||||||
<Manufacturer Enabled="True" Name="Lenovo" EligibilityExpression="(^.*LENOVO.*$)" ProductIDPropertyName="SystemProductName">
|
|
||||||
<URLs DriverPackCatalog="https://download.lenovo.com/cdrt/td/catalogv2.xml" DownloadBase="" />
|
|
||||||
<ModelList>
|
|
||||||
<Model Enabled="False" SystemProductName="10AXS2CQ00" ProductID="10AX" BaseboardProduct="10AXS2CQ00" SystemSKU="LENOVO_MT_10AX" SystemVersion="ThinkCentre M73" SystemFamily="To be filled by O.E.M." SystemManufacturer="Lenovo" />
|
|
||||||
</ModelList>
|
|
||||||
</Manufacturer>
|
|
||||||
</ManufacturerList>
|
|
||||||
</Settings>
|
|
||||||
@@ -152,6 +152,16 @@ Function Get-WindowsReleaseHistory
|
|||||||
|
|
||||||
#Create an object that will contain the functions output.
|
#Create an object that will contain the functions output.
|
||||||
$OutputObjectList = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'
|
$OutputObjectList = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'
|
||||||
|
|
||||||
|
#region Adjust security protocol type(s)
|
||||||
|
[System.Net.SecurityProtocolType]$DesiredSecurityProtocol = [System.Net.SecurityProtocolType]::TLS12
|
||||||
|
|
||||||
|
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to set the desired security protocol to `"$($DesiredSecurityProtocol.ToString().ToUpper())`". Please Wait..."
|
||||||
|
Write-Verbose -Message ($LoggingDetails.LogMessage)
|
||||||
|
|
||||||
|
$Null = [System.Net.ServicePointManager]::SecurityProtocol = ($DesiredSecurityProtocol)
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
Catch
|
Catch
|
||||||
{
|
{
|
||||||
@@ -192,7 +202,7 @@ Function Get-WindowsReleaseHistory
|
|||||||
|
|
||||||
$OGTitle = ($MetadataList[0].Attributes | Where-Object {($_.Name -ieq 'Content')}).Value
|
$OGTitle = ($MetadataList[0].Attributes | Where-Object {($_.Name -ieq 'Content')}).Value
|
||||||
|
|
||||||
$HistoryTableList = $HTMLDocumentObject.SelectNodes('//table') | Where-Object {($_.ID -imatch '(^HistoryTable_\d+$)')}
|
$Global:HistoryTableList = $HTMLDocumentObject.SelectNodes('//table') | Where-Object {($_.ID -imatch '(^HistoryTable_\d+$)')}
|
||||||
|
|
||||||
$RootNodeList = $HTMLDocumentObject.SelectNodes('//strong')
|
$RootNodeList = $HTMLDocumentObject.SelectNodes('//strong')
|
||||||
|
|
||||||
@@ -215,19 +225,67 @@ Function Get-WindowsReleaseHistory
|
|||||||
$OutputObjectProperties.ReleaseHistory = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'
|
$OutputObjectProperties.ReleaseHistory = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'
|
||||||
|
|
||||||
<#
|
<#
|
||||||
$HistoryTableChildNodeList = ($HistoryTableList | Where-Object {($_.InnerText -imatch ".*$($OutputObjectProperties.Build).*")}).ChildNodes | Where-Object {([String]::IsNullOrEmpty($_.InnerText) -eq $False) -and ([String]::IsNullOrWhiteSpace($_.InnerText) -eq $False)} | Sort-Object -Property @('InnerText') -Unique
|
$HistoryTableRowList = ($HistoryTableList.ChildNodes | Where-Object {($_.ChildNodes.Count -gt 0)})
|
||||||
|
|
||||||
For ($HistoryTableChildNodeIndex = 0; $HistoryTableChildNodeIndex -lt $HistoryTableChildNodeList.Count; $HistoryTableChildNodeIndex++)
|
For ($HistoryTableRowListIndex = 0; $HistoryTableRowListIndex -lt $HistoryTableRowList.Count; $HistoryTableRowListIndex++)
|
||||||
{
|
{
|
||||||
$HistoryTableChildNode = $HistoryTableChildNodeList[$HistoryTableChildNodeIndex]
|
$HistoryTableRow = $HistoryTableRowList[$HistoryTableRowListIndex]
|
||||||
|
|
||||||
$InnerTextLines = $HistoryTableChildNode.InnerText.Split("`n", [System.StringSplitOptions]::RemoveEmptyEntries).Trim()
|
Switch ($HistoryTableRowListIndex)
|
||||||
|
|
||||||
For ($InnerTextLineIndex = 0; $InnerTextLineIndex -lt $InnerTextLines.Count; $InnerTextLineIndex++)
|
|
||||||
{
|
{
|
||||||
$InnerTextLine = $InnerTextLines[$InnerTextLineIndex]
|
{($_ -eq 0)}
|
||||||
|
{
|
||||||
|
$HistoryTableRowNodeList = $HistoryTableRow.ChildNodes | Where-Object {([String]::IsNullOrEmpty($_.InnerText) -eq $False) -and ([String]::IsNullOrWhiteSpace($_.InnerText) -eq $False)}
|
||||||
|
|
||||||
#$InnerTextLine
|
$HistoryTableRowPropertyList = ($HistoryTableRowNodeList | ForEach-Object {($TextInfo.ToTitleCase($_.InnerText) -ireplace '(\s+)', '')}) -As [System.Collections.Generic.List[String]]
|
||||||
|
}
|
||||||
|
|
||||||
|
Default
|
||||||
|
{
|
||||||
|
Switch ($HistoryTableRowPropertyList.Count -gt 0)
|
||||||
|
{
|
||||||
|
{($_ -eq $True)}
|
||||||
|
{
|
||||||
|
$ReleaseHistoryObjectProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
||||||
|
|
||||||
|
$HistoryTableRowData = $HistoryTableRow.ChildNodes | Where-Object {($_.ChildNodes.Count -gt 0)}
|
||||||
|
|
||||||
|
For ($HistoryTableRowPropertyListIndex = 0; $HistoryTableRowPropertyListIndex -lt $HistoryTableRowPropertyList.Count; $HistoryTableRowPropertyListIndex++)
|
||||||
|
{
|
||||||
|
$HistoryTableRowPropertyName = $HistoryTableRowPropertyList[$HistoryTableRowPropertyListIndex]
|
||||||
|
|
||||||
|
$HistoryTableRowPropertyValue = $HistoryTableRowData[$HistoryTableRowPropertyListIndex]
|
||||||
|
|
||||||
|
Switch ($Null -ine $HistoryTableRowPropertyValue)
|
||||||
|
{
|
||||||
|
{($_ -eq $True)}
|
||||||
|
{
|
||||||
|
$ValuesMatchingRowNodeList = $HistoryTableRowNodeList | Where-Object {($_.InnerText -imatch ".*$($HistoryTableRowPropertyValue.InnerText).*")}
|
||||||
|
|
||||||
|
$ValuesMatchingRowNodeListCount = ($ValuesMatchingRowNodeList | Measure-Object).Count
|
||||||
|
|
||||||
|
Switch ($ValuesMatchingRowNodeListCount -eq 0)
|
||||||
|
{
|
||||||
|
{($_ -eq $True)}
|
||||||
|
{
|
||||||
|
$ReleaseHistoryObjectProperties."$($HistoryTableRowPropertyName)" = $HistoryTableRowPropertyValue.InnerText
|
||||||
|
}
|
||||||
|
|
||||||
|
Default
|
||||||
|
{
|
||||||
|
$ReleaseHistoryObjectProperties."$($HistoryTableRowPropertyName)" = $Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$ReleaseHistoryObject = New-Object -TypeName 'PSObject' -Property ($ReleaseHistoryObjectProperties)
|
||||||
|
|
||||||
|
$OutputObjectProperties.ReleaseHistory.Add($ReleaseHistoryObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#>
|
#>
|
||||||
@@ -239,12 +297,13 @@ Function Get-WindowsReleaseHistory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$Null = $OutputObjectProperties.ReleaseHistory = $OutputObjectProperties.ReleaseHistory.ToArray() | Where-Object {($Null -ine $_)}
|
||||||
}
|
}
|
||||||
|
|
||||||
#Write the object to the powershell pipeline
|
#Write the object to the powershell pipeline
|
||||||
$OutputObjectList = $OutputObjectList.ToArray()
|
$OutputObjectList = $OutputObjectList.ToArray()
|
||||||
|
|
||||||
$Global:WindowsReleaseHistory = $OutputObjectList | Sort-Object -Property @('Version')
|
$Global:WindowsReleaseHistory = $OutputObjectList | Sort-Object -Property @('Version') | Group-Object -Property @('Name')
|
||||||
}
|
}
|
||||||
|
|
||||||
Default
|
Default
|
||||||
@@ -296,5 +355,5 @@ Function Get-WindowsReleaseHistory
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
<#
|
<#
|
||||||
Get-WindowsReleaseHistory -Force:$False -Verbose
|
Get-WindowsReleaseHistory -Verbose
|
||||||
#>
|
#>
|
||||||
@@ -11,18 +11,25 @@ Function Invoke-SQLDBQuery
|
|||||||
The database connection will be opened, each database query will be executed, the results will be stored, and the database connection will be closed.
|
The database connection will be opened, each database query will be executed, the results will be stored, and the database connection will be closed.
|
||||||
|
|
||||||
.PARAMETER Server
|
.PARAMETER Server
|
||||||
|
The FQDN or IP Address of a MS SQL database server.
|
||||||
|
|
||||||
.PARAMETER Instance
|
.PARAMETER Instance
|
||||||
|
A valid instance name of the desired MS SQL database server instance. (Optional)
|
||||||
|
|
||||||
.PARAMETER Port
|
.PARAMETER Port
|
||||||
|
A valid port number of the MS SQL database server. (Optional)
|
||||||
|
|
||||||
.PARAMETER UserID
|
.PARAMETER UserID
|
||||||
|
A valid SQL authentication username (If not specified, Windows authentication will be used.)
|
||||||
|
|
||||||
.PARAMETER Password
|
.PARAMETER Password
|
||||||
|
A valid SQL authentication password (If not specified, Windows authentication will be used.)
|
||||||
|
|
||||||
.PARAMETER Database
|
.PARAMETER Database
|
||||||
|
A valid database name that resides on the specified MS SQL database server.
|
||||||
|
|
||||||
.PARAMETER DBQueryList
|
.PARAMETER DBQueryList
|
||||||
|
One or more valid SQL queries for the specified database.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
$DBQueryResults = Invoke-SQLDBQuery -Server 'MyDBServer.mydomain.com' -UserID 'SQLAuthUser' -Password 'SQLAuthUserPassword' -Database 'YourDatabaseName' -DBQueryList @('Select * From YourTableName') -Verbose
|
$DBQueryResults = Invoke-SQLDBQuery -Server 'MyDBServer.mydomain.com' -UserID 'SQLAuthUser' -Password 'SQLAuthUserPassword' -Database 'YourDatabaseName' -DBQueryList @('Select * From YourTableName') -Verbose
|
||||||
@@ -30,7 +37,7 @@ Function Invoke-SQLDBQuery
|
|||||||
Write-Output -InputObject ($DBQueryResults)
|
Write-Output -InputObject ($DBQueryResults)
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
$DBQueryList = [System.Collections.Generic.List[String]]@()
|
$DBQueryList = New-Object -TypeName 'System.Collections.Generic.List[String]'
|
||||||
$DBQueryList.Add(@"
|
$DBQueryList.Add(@"
|
||||||
Select Distinct
|
Select Distinct
|
||||||
dbo.v_Add_Remove_Programs.DisplayName0 As 'DisplayName'
|
dbo.v_Add_Remove_Programs.DisplayName0 As 'DisplayName'
|
||||||
@@ -52,6 +59,26 @@ Order By
|
|||||||
|
|
||||||
Write-Output -InputObject ($DBQueryResults)
|
Write-Output -InputObject ($DBQueryResults)
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
$InvokeSQLDBQueryParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
||||||
|
$InvokeSQLDBQueryParameters.Server = "MyDBServer.mydomain.com"
|
||||||
|
$InvokeSQLDBQueryParameters.Instance = "MyDBInstance"
|
||||||
|
$InvokeSQLDBQueryParameters.Port = "1433"
|
||||||
|
$InvokeSQLDBQueryParameters.UserID = "sa"
|
||||||
|
$InvokeSQLDBQueryParameters.Password = "Password1"
|
||||||
|
$InvokeSQLDBQueryParameters.Database = "YourDatabaseName"
|
||||||
|
$InvokeSQLDBQueryParameters.DBQueryList = New-Object -TypeName 'System.Collections.Generic.List[String]'
|
||||||
|
$InvokeSQLDBQueryParameters.DBQueryList.Add('Select * From YourTableName1')
|
||||||
|
$InvokeSQLDBQueryParameters.DBQueryList.Add('Select * From YourTableName2')
|
||||||
|
$InvokeSQLDBQueryParameters.ExportJSON = $True
|
||||||
|
$InvokeSQLDBQueryParameters.ExportDirectory = "$($Env:Public)\Desktop\SQLDBQueryResults"
|
||||||
|
$InvokeSQLDBQueryParameters.ContinueOnError = $True
|
||||||
|
$InvokeSQLDBQueryParameters.Verbose = $True
|
||||||
|
|
||||||
|
$InvokeSQLDBQueryResult = Invoke-SQLDBQuery @InvokeSQLDBQueryParameters
|
||||||
|
|
||||||
|
Write-Output -InputObject ($InvokeSQLDBQueryResult)
|
||||||
|
|
||||||
.LINK
|
.LINK
|
||||||
https://www.SQLshack.com/connecting-powershell-to-SQL-server/
|
https://www.SQLshack.com/connecting-powershell-to-SQL-server/
|
||||||
|
|
||||||
@@ -59,7 +86,7 @@ Order By
|
|||||||
https://stackoverflow.com/questions/64681003/fetch-a-whole-row-from-SQL-server-with-powershell
|
https://stackoverflow.com/questions/64681003/fetch-a-whole-row-from-SQL-server-with-powershell
|
||||||
#>
|
#>
|
||||||
|
|
||||||
[CmdletBinding(ConfirmImpact = 'Low', HelpURI = '', DefaultParameterSetName = '_AllParameterSets', SupportsShouldProcess = $True, PositionalBinding = $True)]
|
[CmdletBinding(ConfirmImpact = 'Low', HelpURI = '', DefaultParameterSetName = '_AllParameterSets', SupportsShouldProcess = $True)]
|
||||||
Param
|
Param
|
||||||
(
|
(
|
||||||
[Parameter(Mandatory=$True)]
|
[Parameter(Mandatory=$True)]
|
||||||
@@ -140,38 +167,6 @@ Order By
|
|||||||
#Define Default Action Preferences
|
#Define Default Action Preferences
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
$LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - The following parameters and values were provided to the `'$($CmdletName)`' function."
|
|
||||||
Write-Verbose -Message $LogMessage
|
|
||||||
|
|
||||||
$FunctionProperties = Get-Command -Name $CmdletName
|
|
||||||
|
|
||||||
$FunctionParameters = $FunctionProperties.Parameters.Keys | Where-Object {($_ -inotmatch '(^Password$)|(^UserID$)|(^DBQueryList$)')}
|
|
||||||
|
|
||||||
ForEach ($Parameter In $FunctionParameters)
|
|
||||||
{
|
|
||||||
If (!([String]::IsNullOrEmpty($Parameter)))
|
|
||||||
{
|
|
||||||
$ParameterProperties = Get-Variable -Name $Parameter -ErrorAction SilentlyContinue
|
|
||||||
$ParameterValueCount = $ParameterProperties.Value | Measure-Object | Select-Object -ExpandProperty Count
|
|
||||||
|
|
||||||
If ($ParameterValueCount -gt 1)
|
|
||||||
{
|
|
||||||
$ParameterValueStringFormat = ($ParameterProperties.Value | ForEach-Object {"`"$($_)`""}) -Join ", "
|
|
||||||
$LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - $($ParameterProperties.Name):`r`n`r`n$($ParameterValueStringFormat)"
|
|
||||||
}
|
|
||||||
Else
|
|
||||||
{
|
|
||||||
$ParameterValueStringFormat = ($ParameterProperties.Value | ForEach-Object {"`"$($_)`""}) -Join ', '
|
|
||||||
$LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - $($ParameterProperties.Name): $($ParameterValueStringFormat)"
|
|
||||||
}
|
|
||||||
|
|
||||||
If (!([String]::IsNullOrEmpty($ParameterProperties.Name)))
|
|
||||||
{
|
|
||||||
Write-Verbose -Message $LogMessage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($CmdletName) began on $($FunctionStartTime.ToString($DateTimeLogFormat))"
|
$LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($CmdletName) began on $($FunctionStartTime.ToString($DateTimeLogFormat))"
|
||||||
Write-Verbose -Message $LogMessage
|
Write-Verbose -Message $LogMessage
|
||||||
|
|
||||||
@@ -185,10 +180,10 @@ Order By
|
|||||||
$LoggingDetails.Add('ErrorMessage', $Null)
|
$LoggingDetails.Add('ErrorMessage', $Null)
|
||||||
|
|
||||||
#Create a database connection string builder
|
#Create a database connection string builder
|
||||||
$DBConnectionStringBuilder = [System.Data.SQLClient.SQLConnectionStringBuilder]::New()
|
$DBConnectionStringBuilder = New-Object -TypeName 'System.Data.SQLClient.SQLConnectionStringBuilder'
|
||||||
|
|
||||||
#Create a database data source builder
|
#Create a database data source builder
|
||||||
$DataSourceBuilder = [System.Text.StringBuilder]::New()
|
$DataSourceBuilder = New-Object -TypeName 'System.Text.StringBuilder'
|
||||||
|
|
||||||
#Dynamically build the connection string based on parameter values
|
#Dynamically build the connection string based on parameter values
|
||||||
Switch ($True)
|
Switch ($True)
|
||||||
@@ -219,26 +214,34 @@ Order By
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$DBConnection = [System.Data.SQLClient.SQLConnection]::New()
|
$DBConnection = New-Object -TypeName 'System.Data.SQLClient.SQLConnection'
|
||||||
|
|
||||||
Switch (([String]::IsNullOrEmpty($UserID) -eq $True) -or ([String]::IsNullOrWhiteSpace($UserID) -eq $True) -or ([String]::IsNullOrEmpty($Password) -eq $True) -or ([String]::IsNullOrWhiteSpace($Password) -eq $True))
|
Switch ((([String]::IsNullOrEmpty($UserID) -eq $False) -and ([String]::IsNullOrWhiteSpace($UserID) -eq $False)) -and (([String]::IsNullOrEmpty($Password) -eq $False) -or ([String]::IsNullOrWhiteSpace($Password) -eq $False)))
|
||||||
{
|
{
|
||||||
{($_ -eq $True)}
|
{($_ -eq $True)}
|
||||||
{
|
{
|
||||||
$DBConnectionStringBuilder.PSBase.IntegratedSecurity = $True
|
$DBConnectionStringBuilder.PSBase.IntegratedSecurity = $False
|
||||||
|
|
||||||
|
$CredentialParameters = New-Object -TypeName 'System.Collections.Generic.List[Object]'
|
||||||
|
$CredentialParameters.Add($UserID)
|
||||||
|
$CredentialParameters.Add((ConvertTo-SecureString -String $Password -AsPlainText -Force))
|
||||||
|
|
||||||
|
$Credential = New-Object -TypeName 'System.Management.Automation.PSCredential' -ArgumentList ($CredentialParameters.ToArray())
|
||||||
|
|
||||||
|
$Null = $Credential.Password.MakeReadOnly()
|
||||||
|
|
||||||
|
$DBConnectionCredentialParameters = New-Object -TypeName 'System.Collections.Generic.List[Object]'
|
||||||
|
$DBConnectionCredentialParameters.Add($Credential.UserName)
|
||||||
|
$DBConnectionCredentialParameters.Add($Credential.Password)
|
||||||
|
|
||||||
|
$DBConnectionCredential = New-Object -TypeName 'System.Data.SQLClient.SQLCredential' -ArgumentList ($DBConnectionCredentialParameters.ToArray())
|
||||||
|
|
||||||
|
$DBConnection.Credential = ($DBConnectionCredential)
|
||||||
}
|
}
|
||||||
|
|
||||||
Default
|
Default
|
||||||
{
|
{
|
||||||
$DBConnectionStringBuilder.PSBase.IntegratedSecurity = $False
|
$DBConnectionStringBuilder.PSBase.IntegratedSecurity = $True
|
||||||
|
|
||||||
$Credential = [System.Management.Automation.PSCredential]::New($UserID, (ConvertTo-SecureString -String $Password -AsPlainText -Force))
|
|
||||||
|
|
||||||
$Null = $Credential.Password.MakeReadOnly()
|
|
||||||
|
|
||||||
$DBConnectionCredential = [System.Data.SQLClient.SQLCredential]::New($Credential.UserName, $Credential.Password)
|
|
||||||
|
|
||||||
$DBConnection.Credential = ($DBConnectionCredential)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +274,7 @@ Order By
|
|||||||
[String]$DBQuery = $DBQueryList[$DBQueryListIndex]
|
[String]$DBQuery = $DBQueryList[$DBQueryListIndex]
|
||||||
[Int]$DBQueryNumber = $DBQueryListIndex + 1
|
[Int]$DBQueryNumber = $DBQueryListIndex + 1
|
||||||
|
|
||||||
$DBCommand = [System.Data.SQLClient.SQLCommand]::New()
|
$DBCommand = New-Object -TypeName 'System.Data.SQLClient.SQLCommand'
|
||||||
$DBCommand.Connection = ($DBConnection)
|
$DBCommand.Connection = ($DBConnection)
|
||||||
$DBCommand.CommandText = ($DBQuery)
|
$DBCommand.CommandText = ($DBQuery)
|
||||||
|
|
||||||
@@ -280,9 +283,13 @@ Order By
|
|||||||
|
|
||||||
$Null = $DBCommand.ExecuteScalar()
|
$Null = $DBCommand.ExecuteScalar()
|
||||||
|
|
||||||
$DBQueryResults = [System.Data.DataTable]::New()
|
$DBQueryResults = New-Object -TypeName 'System.Data.DataTable'
|
||||||
|
|
||||||
|
$DBDataAdapterParameters = New-Object -TypeName 'System.Collections.Generic.List[Object]'
|
||||||
|
$DBDataAdapterParameters.Add($DBCommand)
|
||||||
|
|
||||||
|
$DBDataAdapter = New-Object -TypeName 'System.Data.SQLClient.SQLDataAdapter' -ArgumentList ($DBDataAdapterParameters.ToArray())
|
||||||
|
|
||||||
$DBDataAdapter = [System.Data.SQLClient.SQLDataAdapter]::New($DBCommand)
|
|
||||||
$Null = $DBDataAdapter.Fill($DBQueryResults)
|
$Null = $DBDataAdapter.Fill($DBQueryResults)
|
||||||
|
|
||||||
$DBQueryRowCount = $DBQueryResults.Rows.Count
|
$DBQueryRowCount = $DBQueryResults.Rows.Count
|
||||||
@@ -305,10 +312,10 @@ Order By
|
|||||||
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - " + "Attempting to add the result(s) from database query #$($DBQueryNumber) to property `"$($ResultSetPropertyName)`". Please Wait..."
|
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - " + "Attempting to add the result(s) from database query #$($DBQueryNumber) to property `"$($ResultSetPropertyName)`". Please Wait..."
|
||||||
Write-Verbose -Message ($LoggingDetails.LogMessage)
|
Write-Verbose -Message ($LoggingDetails.LogMessage)
|
||||||
|
|
||||||
$PropertyInclusionList = [System.Collections.Generic.List[Object]]@()
|
$PropertyInclusionList = New-Object -TypeName 'System.Collections.Generic.List[Object]'
|
||||||
$Null = $PropertyInclusionList.Add('*')
|
$Null = $PropertyInclusionList.Add('*')
|
||||||
|
|
||||||
$PropertyExclusionList = [System.Collections.Generic.List[Object]]@()
|
$PropertyExclusionList = New-Object -TypeName 'System.Collections.Generic.List[Object]'
|
||||||
$Null = $PropertyExclusionList.AddRange(('HasErrors', 'ItemArray', 'RowError', 'RowState', 'Table'))
|
$Null = $PropertyExclusionList.AddRange(('HasErrors', 'ItemArray', 'RowError', 'RowState', 'Table'))
|
||||||
|
|
||||||
$DBQueryRows = $DBQueryResults.Rows | Select-Object -Property ($PropertyInclusionList) -ExcludeProperty ($PropertyExclusionList)
|
$DBQueryRows = $DBQueryResults.Rows | Select-Object -Property ($PropertyInclusionList) -ExcludeProperty ($PropertyExclusionList)
|
||||||
@@ -353,7 +360,7 @@ Order By
|
|||||||
{($ExportJSON.IsPresent)}
|
{($ExportJSON.IsPresent)}
|
||||||
{
|
{
|
||||||
$ExportParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
$ExportParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
||||||
$ExportParameters.Add('Compress', $False)
|
$ExportParameters.Add('Compress', $True)
|
||||||
$ExportParameters.Add('Encoding', [System.Text.Encoding]::Default)
|
$ExportParameters.Add('Encoding', [System.Text.Encoding]::Default)
|
||||||
$ExportParameters.Add('Depth', 10)
|
$ExportParameters.Add('Depth', 10)
|
||||||
|
|
||||||
|
|||||||
@@ -978,6 +978,26 @@ Else
|
|||||||
{
|
{
|
||||||
{($_ -eq $True)}
|
{($_ -eq $True)}
|
||||||
{
|
{
|
||||||
|
$OperatingSystemCriteria = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
||||||
|
|
||||||
|
Switch ($WindowsImageDetails.BuildLabEX)
|
||||||
|
{
|
||||||
|
{($_ -imatch '.*amd64.*')}
|
||||||
|
{
|
||||||
|
$OperatingSystemCriteria.Architecture = 'X64'
|
||||||
|
}
|
||||||
|
|
||||||
|
Default
|
||||||
|
{
|
||||||
|
$OperatingSystemCriteria.Architecture = 'X86'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Deployed Operating System - Architecture: $($OperatingSystemCriteria.Architecture)"
|
||||||
|
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
|
||||||
|
|
||||||
|
$OperatingSystemCriteria.Version = $WindowsImageDetails.Version
|
||||||
|
|
||||||
$GenericDriverPackageMetadataFileList = Get-ChildItem -Path ($GenericDriverPackageRootDirectory.FullName) -Filter '*.json' -Recurse -Force | Where-Object {($_ -is [System.IO.FileInfo])}
|
$GenericDriverPackageMetadataFileList = Get-ChildItem -Path ($GenericDriverPackageRootDirectory.FullName) -Filter '*.json' -Recurse -Force | Where-Object {($_ -is [System.IO.FileInfo])}
|
||||||
|
|
||||||
ForEach ($GenericDriverPackageMetadataFile In $GenericDriverPackageMetadataFileList)
|
ForEach ($GenericDriverPackageMetadataFile In $GenericDriverPackageMetadataFileList)
|
||||||
|
|||||||
@@ -1 +1,230 @@
|
|||||||
A.D.D.A.P. - Autonomous Driver Downloader and Packager
|
# A.D.D.A.P. — Autonomous Driver Downloader And Packager
|
||||||
|
|
||||||
|
A PowerShell-based solution that automates the downloading, extraction, and WIM compression of OEM driver packs from **Dell**, **HP**, and **Lenovo**. A companion script dynamically downloads and applies the correct WIM driver pack during OS Deployment (OSD) based on the detected hardware and deployed operating system.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Managing drivers across a fleet of hardware models is one of the most time-consuming parts of Windows OS deployment. ADDAP solves this by:
|
||||||
|
|
||||||
|
1. **Downloading** vendor driver pack catalogs and driver packages from Dell, HP, and Lenovo.
|
||||||
|
2. **Extracting** the downloaded driver packs.
|
||||||
|
3. **Compressing** the extracted drivers into WIM format for efficient storage and transfer.
|
||||||
|
4. **Dynamically applying** the correct WIM driver pack during OSD by matching the target device's hardware identifiers and the operating system being deployed.
|
||||||
|
|
||||||
|
All processing is driven by an **XML configuration file** that defines which manufacturers, models, and operating systems to include.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
### Phase 1 — Driver Pack Creation (Infrastructure / Build Server)
|
||||||
|
|
||||||
|
`Invoke-DriverPackageCreator.ps1` is run on a build server or administrative workstation. It:
|
||||||
|
|
||||||
|
- Reads the XML settings file (`Content\Settings\Settings.xml`) to determine which manufacturers, models, and OS versions to process.
|
||||||
|
- Downloads the vendor driver pack catalogs (`.cab` / `.xml`) from Dell, HP, and Lenovo.
|
||||||
|
- Matches catalog entries to the models and operating systems defined in the XML.
|
||||||
|
- Downloads the applicable driver packs.
|
||||||
|
- Extracts driver packs using the bundled **7-Zip** tool (`Tools\X64\7z.exe` / `Tools\X86\7z.exe`).
|
||||||
|
- Compresses the extracted drivers into **WIM** images.
|
||||||
|
- Generates a metadata XML file (`DriverPackageList.xml`) that maps each WIM driver pack to its hardware product IDs and target OS.
|
||||||
|
|
||||||
|
### Phase 2 — Driver Pack Application (During OSD)
|
||||||
|
|
||||||
|
`Invoke-DriverPackageDownload.ps1` runs during an MDT or MECM task sequence. It:
|
||||||
|
|
||||||
|
- Detects the current device's manufacturer, product ID, and other hardware identifiers via WMI (`MS_SystemInformation`).
|
||||||
|
- Reads the deployed OS version and release from the offline Windows image registry hive.
|
||||||
|
- Reads the metadata XML to find the driver pack that matches both the hardware and the deployed OS.
|
||||||
|
- Supports **down-leveling** — falling back to an older OS release driver pack when an exact match is not available (can be disabled with `-DisableDownLeveling`).
|
||||||
|
- Downloads the matching WIM driver pack to the target volume.
|
||||||
|
- Applies (expands) the WIM to inject drivers into the deployed OS.
|
||||||
|
|
||||||
|
### Configuration Generator (Optional)
|
||||||
|
|
||||||
|
`Invoke-ConfigurationGenerator.ps1` automates the creation of the XML settings file. It can:
|
||||||
|
|
||||||
|
- Query a **SQL database** (e.g., the MECM database) to retrieve a list of all hardware models in the environment.
|
||||||
|
- Generate the full XML settings file with the correct manufacturer entries and model lists pre-populated.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Repository Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
ADDAP/
|
||||||
|
├── Invoke-DriverPackageCreator.ps1 # Downloads, extracts, and WIM-compresses driver packs
|
||||||
|
├── Invoke-DriverPackageDownload.ps1 # Runs during OSD to download and apply driver packs
|
||||||
|
├── Invoke-ConfigurationGenerator.ps1 # Generates the XML settings file (optional)
|
||||||
|
├── Content/
|
||||||
|
│ ├── Settings/
|
||||||
|
│ │ └── Template.xml # XML settings template (manufacturers, models, OS list)
|
||||||
|
│ ├── DBQueries/
|
||||||
|
│ │ └── GetProductIDList.sql # SQL query to retrieve model list from MECM database
|
||||||
|
│ └── ScheduledTasks/
|
||||||
|
│ └── Template.xml # Scheduled task template for automation
|
||||||
|
├── Functions/ # Helper PowerShell functions (dot-sourced at runtime)
|
||||||
|
│ ├── Convert-FileSize.ps1
|
||||||
|
│ ├── Copy-ItemWithProgress.ps1
|
||||||
|
│ ├── Get-WindowsReleaseHistory.ps1
|
||||||
|
│ ├── Invoke-FileDownload.ps1
|
||||||
|
│ ├── Invoke-FileDownloadWithProgress.ps1
|
||||||
|
│ ├── Invoke-RegistryHiveAction.ps1
|
||||||
|
│ ├── Invoke-SQLDBQuery.ps1
|
||||||
|
│ ├── Invoke-ScheduledTaskAction.ps1
|
||||||
|
│ ├── Start-ProcessWithOutput.ps1
|
||||||
|
│ └── Libraries/ # .NET assemblies (AlphaFS, HtmlAgilityPack, etc.)
|
||||||
|
├── Templates/
|
||||||
|
│ └── TaskSequences/
|
||||||
|
│ └── MDT/
|
||||||
|
│ └── ts.xml # Sample MDT task sequence template
|
||||||
|
├── Tools/
|
||||||
|
│ ├── X64/ # 64-bit 7-Zip binaries
|
||||||
|
│ └── X86/ # 32-bit 7-Zip binaries
|
||||||
|
└── SampleLogs/ # Example log output and DISM logs
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## XML Settings Configuration
|
||||||
|
|
||||||
|
The settings XML (`Content\Settings\Template.xml`) controls all processing. Key sections:
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
| Parameter | Description |
|
||||||
|
|---|---|
|
||||||
|
| `ApplicationDataRootDirectory` | Root working directory for the script |
|
||||||
|
| `StagingDirectory` | Temporary staging area for downloads and extraction |
|
||||||
|
| `DownloadDirectory` | Where raw driver pack downloads are stored |
|
||||||
|
| `DriverPackageDirectory` | Output directory for the final WIM driver packages |
|
||||||
|
| `DisableDownload` | Skip downloading (use previously downloaded packs) |
|
||||||
|
| `Force` | Force reprocessing even if packages already exist |
|
||||||
|
| `ContinueOnError` | Continue processing remaining models on failure |
|
||||||
|
|
||||||
|
### Operating System List
|
||||||
|
|
||||||
|
Defines which Windows versions to target (e.g., Windows 10 x64, Windows 11 x64). Supports regex-based matching and a `LatestReleaseOnly` option.
|
||||||
|
|
||||||
|
### Manufacturer List
|
||||||
|
|
||||||
|
Each manufacturer entry includes:
|
||||||
|
|
||||||
|
- **Name** and **Eligibility Expression** — regex to match the device's `SystemManufacturer` WMI property.
|
||||||
|
- **Catalog URLs** — vendor-specific driver pack catalog download URLs.
|
||||||
|
- **Product ID Property** — which WMI property to use for hardware matching (`SystemSKU` for Dell, `BaseboardProduct` for HP, `SystemProductName` for Lenovo).
|
||||||
|
- **Model List** — the specific hardware models to process, each identified by `ProductID`, `BaseboardProduct`, `SystemSKU`, etc.
|
||||||
|
|
||||||
|
### Adding a New Model
|
||||||
|
|
||||||
|
Run the following PowerShell snippet on the target hardware to generate the XML node, then paste it into the appropriate manufacturer's `<ModelList>` section:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$PropertyList = New-Object -TypeName 'System.Collections.Generic.List[Object]'
|
||||||
|
$PropertyList.Add(@{Name = 'Enabled'; Expression = {$True}})
|
||||||
|
$PropertyList.Add('SystemProductName')
|
||||||
|
$PropertyList.Add(@{Name = 'ProductID'; Expression = {$_.BaseboardProduct}})
|
||||||
|
$PropertyList.Add('BaseboardProduct')
|
||||||
|
$PropertyList.Add('SystemSKU')
|
||||||
|
$PropertyList.Add('SystemVersion')
|
||||||
|
$PropertyList.Add('SystemFamily')
|
||||||
|
$PropertyList.Add('SystemManufacturer')
|
||||||
|
|
||||||
|
$MSSystemInformation = Get-CIMInstance -Namespace "root\WMI" -Class "MS_SystemInformation" | Select-Object -Property ($PropertyList)
|
||||||
|
|
||||||
|
$XMLAttributes = $MSSystemInformation.PSObject.Properties | ForEach-Object {"$($_.Name)=`"$($_.Value)`""}
|
||||||
|
|
||||||
|
$XMLNode = "<Model $($XMLAttributes -Join ' ') />"
|
||||||
|
|
||||||
|
Write-Output -InputObject ($XMLNode)
|
||||||
|
|
||||||
|
$Null = $XMLNode | Set-Clipboard -Verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Supported Vendors
|
||||||
|
|
||||||
|
| Vendor | Catalog Source | Product ID Property |
|
||||||
|
|---|---|---|
|
||||||
|
| **Dell** | [DriverPackCatalog.cab](https://dl.dell.com/catalog/DriverPackCatalog.cab) | `SystemSKU` |
|
||||||
|
| **HP** | [HPClientDriverPackCatalog.cab](https://ftp.hp.com/pub/caps-softpaq/cmit/HPClientDriverPackCatalog.cab) | `BaseboardProduct` |
|
||||||
|
| **Lenovo** | [catalogv2.xml](https://download.lenovo.com/cdrt/td/catalogv2.xml) | `SystemProductName` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- **PowerShell 3.0** or later.
|
||||||
|
- **Administrative privileges** (the scripts will self-elevate if not already running as admin).
|
||||||
|
- Network access to vendor catalog and download URLs.
|
||||||
|
- For OSD usage: an active **MDT** or **MECM** task sequence environment.
|
||||||
|
- For SQL-based configuration generation: access to a MECM SQL database.
|
||||||
|
|
||||||
|
### Creating Driver Packages
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Run from an elevated PowerShell prompt
|
||||||
|
.\Invoke-DriverPackageCreator.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
The script will:
|
||||||
|
1. Create `Content\Settings\Settings.xml` from the template if it does not already exist.
|
||||||
|
2. Download vendor catalogs.
|
||||||
|
3. Download, extract, and WIM-compress driver packs for all enabled models and OS versions.
|
||||||
|
|
||||||
|
To add the current machine's model to the XML automatically:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\Invoke-DriverPackageCreator.ps1 -AdditionalXMLNodes '<Model Enabled="True" SystemProductName="Latitude 5430" ProductID="0B04" ... />'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Generating Configuration from MECM Database
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\Invoke-ConfigurationGenerator.ps1 -QuerySQLDatabase -SQLDatabaseFQDN "sqlserver.domain.com" -SQLDatabaseBName "CM_ABC"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Downloading and Applying Drivers During OSD
|
||||||
|
|
||||||
|
Add `Invoke-DriverPackageDownload.ps1` as a **Run PowerShell Script** step in your MDT or MECM task sequence:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\Invoke-DriverPackageDownload.ps1 -DriverPackageRootDirectory "\\server\share\Out-Of-Box-Driver-Packages" -DriverPackageMetadataPath "\\server\share\Out-Of-Box-Driver-Packages\Metadata\DriverPackageList.xml"
|
||||||
|
```
|
||||||
|
|
||||||
|
Key parameters:
|
||||||
|
|
||||||
|
| Parameter | Description |
|
||||||
|
|---|---|
|
||||||
|
| `-DriverPackageRootDirectory` | UNC path to the root of the driver package share |
|
||||||
|
| `-DriverPackageMetadataPath` | Path to the metadata XML generated by the creator script |
|
||||||
|
| `-DisableDownLeveling` | Require an exact OS release match (no fallback) |
|
||||||
|
| `-Stage` | Stage (copy) the driver content locally before applying |
|
||||||
|
| `-RandomDelay` | Add a random delay before downloading (load balancing) |
|
||||||
|
| `-ContinueOnError` | Do not fail the task sequence on error |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Logging
|
||||||
|
|
||||||
|
All scripts produce detailed transcript logs:
|
||||||
|
|
||||||
|
- **Creator script**: `%WINDIR%\Logs\Software\Invoke-DriverPackageCreator\`
|
||||||
|
- **Download script (full OS)**: `%WINDIR%\Logs\Software\Invoke-DriverPackageDownload\`
|
||||||
|
- **Download script (task sequence)**: The task sequence log directory (e.g., `_SMSTSLogPath`)
|
||||||
|
|
||||||
|
Log history is automatically maintained with a maximum of **3** log files per script.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Windows PowerShell 3.0+
|
||||||
|
- Windows 10 / Windows 11 / Windows Server 2016+
|
||||||
|
- 7-Zip (bundled in `Tools\`)
|
||||||
|
- .NET Framework (for bundled libraries: AlphaFS, HtmlAgilityPack, NLog, NFluent, Registry)
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<sequence version="3.00" name="Custom Task Sequence" description="Sample Custom Task Sequence">
|
||||||
|
<group expand="true" name="Driver Package Actions" description="" disable="false" continueOnError="false">
|
||||||
|
<action />
|
||||||
|
<group expand="true" name="Variables" description="" disable="false" continueOnError="false">
|
||||||
|
<action />
|
||||||
|
<step type="SMS_TaskSequence_SetVariableAction" name="CustomContentPath" description="Set this location to the path where " disable="false" continueOnError="false" successCodeList="0 3010">
|
||||||
|
<defaultVarList>
|
||||||
|
<variable name="VariableName" property="VariableName">CustomContentPath</variable>
|
||||||
|
<variable name="VariableValue" property="VariableValue">%ScriptRoot%\Custom</variable>
|
||||||
|
</defaultVarList>
|
||||||
|
<action>cscript.exe "%SCRIPTROOT%\ZTISetVariable.wsf"</action>
|
||||||
|
<condition>
|
||||||
|
<operator type="not">
|
||||||
|
<expression type="SMS_TaskSequence_VariableConditionExpression">
|
||||||
|
<variable name="Variable">CustomContentPath</variable>
|
||||||
|
<variable name="Operator">exists</variable>
|
||||||
|
<variable name="Value"></variable>
|
||||||
|
</expression>
|
||||||
|
</operator>
|
||||||
|
</condition>
|
||||||
|
</step>
|
||||||
|
<step type="SMS_TaskSequence_SetVariableAction" name="DownloadSegmentSize" description="Controls the download buffer for the script that performs the downloading of the driver package(s)." disable="false" continueOnError="false" successCodeList="0 3010">
|
||||||
|
<defaultVarList>
|
||||||
|
<variable name="VariableName" property="VariableName">DownloadSegmentSize</variable>
|
||||||
|
<variable name="VariableValue" property="VariableValue">102400</variable>
|
||||||
|
</defaultVarList>
|
||||||
|
<action>cscript.exe "%SCRIPTROOT%\ZTISetVariable.wsf"</action>
|
||||||
|
<condition>
|
||||||
|
<operator type="not">
|
||||||
|
<expression type="SMS_TaskSequence_VariableConditionExpression">
|
||||||
|
<variable name="Variable">DownloadSegmentSize</variable>
|
||||||
|
<variable name="Operator">exists</variable>
|
||||||
|
<variable name="Value"></variable>
|
||||||
|
</expression>
|
||||||
|
</operator>
|
||||||
|
</condition>
|
||||||
|
</step>
|
||||||
|
<step type="SMS_TaskSequence_SetVariableAction" name="DriverPackageRootDirectory" description="This is the root directory where driver package(s) will be retrieved for download." disable="false" continueOnError="false" successCodeList="0 3010">
|
||||||
|
<defaultVarList>
|
||||||
|
<variable name="VariableName" property="VariableName">DriverPackageRootDirectory</variable>
|
||||||
|
<variable name="VariableValue" property="VariableValue">%DEPLOYROOT%\Out-Of-Box-Driver-Packages</variable>
|
||||||
|
</defaultVarList>
|
||||||
|
<action>cscript.exe "%SCRIPTROOT%\ZTISetVariable.wsf"</action>
|
||||||
|
</step>
|
||||||
|
<step type="SMS_TaskSequence_SetVariableAction" name="DriverPackageMetadataPath" description="This is the path to the XML that will be referenced to determine which of the downloaded driver package(s) are applicable to the device and operating system being deployed." disable="false" continueOnError="false" successCodeList="0 3010">
|
||||||
|
<defaultVarList>
|
||||||
|
<variable name="VariableName" property="VariableName">DriverPackageMetadataPath</variable>
|
||||||
|
<variable name="VariableValue" property="VariableValue">%DriverPackageRootDirectory%\Metadata\DriverPackageList.xml</variable>
|
||||||
|
</defaultVarList>
|
||||||
|
<action>cscript.exe "%SCRIPTROOT%\ZTISetVariable.wsf"</action>
|
||||||
|
</step>
|
||||||
|
<step type="SMS_TaskSequence_SetVariableAction" name="StagingRootDirectory" description="After the drivers have been downloaded and installed, the driver(s) can be optionally staged on the local disk for recovery/reinstallation situations." disable="false" continueOnError="false" successCodeList="0 3010">
|
||||||
|
<defaultVarList>
|
||||||
|
<variable name="VariableName" property="VariableName">StagingRootDirectory</variable>
|
||||||
|
<variable name="VariableValue" property="VariableValue">%OSDisk%\DriverCache</variable>
|
||||||
|
</defaultVarList>
|
||||||
|
<action>cscript.exe "%SCRIPTROOT%\ZTISetVariable.wsf"</action>
|
||||||
|
</step>
|
||||||
|
</group>
|
||||||
|
<group expand="true" name="Scripts" description="" disable="false" continueOnError="false">
|
||||||
|
<action />
|
||||||
|
<step type="BDD_RunPowerShellAction" name="Download and apply driver package(s)" description="Using the XML metadata file, an attempt to identify, download, mount, and apply any and all relevant driver package(s) for the platform." disable="false" continueOnError="false" successCodeList="0 3010">
|
||||||
|
<defaultVarList>
|
||||||
|
<variable name="ScriptName" property="ScriptName">%CustomContentPath%\Invoke-DriverPackageAction\Invoke-DriverPackageDownload.ps1</variable>
|
||||||
|
<variable name="Parameters" property="Parameters">-SegmentSize %DownloadSegmentSize% -DPRD '%DriverPackageRootDirectory%' -DPMDP '%DriverPackageMetadataPath%' -StageDriversLocally -SRD '%StagingRootDirectory%'</variable>
|
||||||
|
<variable name="PackageID" property="PackageID" />
|
||||||
|
</defaultVarList>
|
||||||
|
<action>cscript.exe "%SCRIPTROOT%\ZTIPowerShell.wsf</action>
|
||||||
|
</step>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
</sequence>
|
||||||
Reference in New Issue
Block a user