Initial Upload

This commit is contained in:
freedbygrace
2022-12-01 11:40:57 -05:00
committed by GitHub
commit 3fcf06990c
25 changed files with 7931 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
Declare @OperatingSystemFilter VARCHAR(Max) = '%NT%Workstation%';
Declare @IsVirtualMachine INT = 0;
Declare @Manufacturer VARCHAR(Max) = '%';
Declare @NullReplacementValue VARCHAR(Max) = 'N/A';
Select Distinct
dbo.v_GS_MS_SYSTEMINFORMATION.BaseBoardProduct0 As 'BaseboardProduct',
dbo.v_GS_MS_SYSTEMINFORMATION.SystemFamily0 As 'SystemFamily',
dbo.v_GS_MS_SYSTEMINFORMATION.SystemManufacturer0 As 'SystemManufacturer',
dbo.v_GS_MS_SYSTEMINFORMATION.SystemProductName0 As 'SystemProductName',
dbo.v_GS_MS_SYSTEMINFORMATION.SystemSKU0 As 'SystemSKU',
dbo.v_GS_MS_SYSTEMINFORMATION.SystemVersion0 As 'SystemVersion'
From
dbo.v_R_System
Inner Join dbo.v_GS_MS_SYSTEMINFORMATION On (dbo.v_R_System.ResourceID = dbo.v_GS_MS_SYSTEMINFORMATION.ResourceID)
Where
(dbo.v_R_System.Operating_System_Name_and0 Like @OperatingSystemFilter)
And
(dbo.v_R_System.Is_Virtual_Machine0 = @IsVirtualMachine)
And
((dbo.v_GS_MS_SYSTEMINFORMATION.SystemManufacturer0 Like @Manufacturer))
Order By
dbo.v_GS_MS_SYSTEMINFORMATION.SystemManufacturer0
+94
View File
@@ -0,0 +1,94 @@
<?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>
+118
View File
@@ -0,0 +1,118 @@
## Microsoft Function Naming Convention: http://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx
#region Function Convert-FileSize
Function Convert-FileSize
{
<#
.SYSNOPSIS
Converts a size in bytes to its upper most value.
.PARAMETER Size
The size in bytes to convert
.EXAMPLE
$ConvertFileSizeParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ConvertFileSizeParameters.Size = 4294964
$ConvertFileSizeParameters.DecimalPlaces = 2
$ConvertFileSizeResult = Convert-FileSize @ConvertFileSizeParameters
Write-Output -InputObject ($ConvertFileSizeResult)
.EXAMPLE
$ConvertFileSizeResult = Convert-FileSize -Size 4294964
Write-Output -InputObject ($ConvertFileSizeResult)
.NOTES
Size : 429496456565656
DecimalPlaces : 0
Divisor : 1099511627776
SizeUnit : TB
SizeUnitAlias : Terabytes
CalculatedSize : 391
CalculatedSizeStr : 391 TB
#>
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[Alias("Length")]
$Size,
[Parameter(Mandatory=$False)]
[ValidateNotNullOrEmpty()]
[Alias("DP")]
[Int]$DecimalPlaces
)
Try
{
Switch ($True)
{
{([String]::IsNullOrEmpty($DecimalPlaces) -eq $True) -or ([String]::IsNullOrWhiteSpace($DecimalPlaces) -eq $True)}
{
[Int]$DecimalPlaces = 2
}
}
$OutputObjectProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$OutputObjectProperties.Size = $Size
$OutputObjectProperties.DecimalPlaces = $DecimalPlaces
Switch ($Size)
{
{($_ -lt 1MB)}
{
$OutputObjectProperties.Divisor = 1KB
$OutputObjectProperties.SizeUnit = 'KB'
$OutputObjectProperties.SizeUnitAlias = 'Kilobytes'
Break
}
{($_ -lt 1GB)}
{
$OutputObjectProperties.Divisor = 1MB
$OutputObjectProperties.SizeUnit = 'MB'
$OutputObjectProperties.SizeUnitAlias = 'Megabytes'
Break
}
{($_ -lt 1TB)}
{
$OutputObjectProperties.Divisor = 1GB
$OutputObjectProperties.SizeUnit = 'GB'
$OutputObjectProperties.SizeUnitAlias = 'Gigabytes'
Break
}
{($_ -ge 1TB)}
{
$OutputObjectProperties.Divisor = 1TB
$OutputObjectProperties.SizeUnit = 'TB'
$OutputObjectProperties.SizeUnitAlias = 'Terabytes'
Break
}
}
$OutputObjectProperties.CalculatedSize = [System.Math]::Round(($Size / $OutputObjectProperties.Divisor), $OutputObjectProperties.DecimalPlaces)
$OutputObjectProperties.CalculatedSizeStr = "$($OutputObjectProperties.CalculatedSize) $($OutputObjectProperties.SizeUnit)"
}
Catch
{
Write-Error -Exception $_
}
Finally
{
$OutputObject = New-Object -TypeName 'PSObject' -Property ($OutputObjectProperties)
Write-Output -InputObject ($OutputObject)
}
}
#endregion
+621
View File
@@ -0,0 +1,621 @@
## Microsoft Function Naming Convention: http://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx
#region Function Copy-ItemWithProgress
Function Copy-ItemWithProgress
{
<#
.SYNOPSIS
Copies file(s) from a valid path in segments.
.DESCRIPTION
Supports the copying of files from a valid location in segments either directly or recursively.
Supports the usage of filters and exclusions exactly the way that the Get-ChildItem or Copy-Item cmdlets work.
.PARAMETER Path
A valid file or folder location.
.PARAMETER Destination
The destination directory where the content will be copied.
.PARAMETER Include
One or more filter(s) to implicitly copy what is specified.
.PARAMETER Exclude
One or more filter(s) to implicitly skip the copying of what is specified.
.PARAMETER Recurse
Recurse through the specified directories.
.PARAMETER Force
Overwrite file(s) that have already been copied. The default behavior is to skip the copying of the file.
.PARAMETER SegmentSize
The segment size in megabytes that each file will be transferred with.
.PARAMETER RandomDelay
Adds a pulse in between the transfer of each segment.
.PARAMETER ContinueOnError
Continues processing even if an error has occured.
.EXAMPLE
Copy-ItemWithProgress -Path 'FileOrDirectoryPath' -Destination 'YourDestinationDirectory' -Verbose
.EXAMPLE
$CopyItemWithProgressParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$CopyItemWithProgressParameters.Path = "FileOrDirectoryPath"
$CopyItemWithProgressParameters.Destination = "YourDestinationDirectory"
$CopyItemWithProgressParameters.Include = New-Object -TypeName 'System.Collections.Generic.List[String]'
$CopyItemWithProgressParameters.Include.Add('*.*')
$CopyItemWithProgressParameters.Exclude = New-Object -TypeName 'System.Collections.Generic.List[String]'
$CopyItemWithProgressParameters.Exclude.Add('*.ini')
$CopyItemWithProgressParameters.Recurse = $True
$CopyItemWithProgressParameters.Force = $False
$CopyItemWithProgressParameters.SegmentSize = 4096
$CopyItemWithProgressParameters.RandomDelay = $False
$CopyItemWithProgressParameters.ContinueOnError = $False
$CopyItemWithProgressParameters.Verbose = $True
$CopyItemWithProgressResult = Copy-ItemWithProgress @CopyItemWithProgressParameters
Write-Output -InputObject ($CopyItemWithProgressResult)
.NOTES
A progress bar is displayed and can be useful for scripts where the copying of large file(s) is taking place.
.LINK
http://stackoverflow.com/questions/2434133/progress-during-large-file-copy-copy-item-write-progress
.LINK
https://stackoverflow.com/questions/13883404/custom-robocopy-progress-bar-in-powershell
#>
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[ValidateScript({Test-Path -Path $_})]
[Alias('P')]
[String]$Path,
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[Alias('D')]
[System.IO.DirectoryInfo]$Destination,
[Parameter(Mandatory=$False)]
[Alias('I')]
[String[]]$Include,
[Parameter(Mandatory=$False)]
[Alias('E')]
[String[]]$Exclude,
[Parameter(Mandatory=$False)]
[Alias('R')]
[Switch]$Recurse,
[Parameter(Mandatory=$False)]
[Alias('Overwrite')]
[Switch]$Force,
[Parameter(Mandatory=$False)]
[ValidateNotNullOrEmpty()]
[Alias('SS', 'BufferInMegabytes')]
[Int]$SegmentSize,
[Parameter(Mandatory=$False)]
[Alias('RD')]
[Switch]$RandomDelay,
[Parameter(Mandatory=$False)]
[Alias('COE')]
[Switch]$ContinueOnError
)
Begin
{
Try
{
$DateTimeLogFormat = 'dddd, MMMM dd, yyyy @ hh:mm:ss.FFF tt' ###Monday, January 01, 2019 @ 10:15:34.000 AM###
[ScriptBlock]$GetCurrentDateTimeLogFormat = {(Get-Date).ToString($DateTimeLogFormat)}
$DateTimeMessageFormat = 'MM/dd/yyyy HH:mm:ss.FFF' ###03/23/2022 11:12:48.347###
[ScriptBlock]$GetCurrentDateTimeMessageFormat = {(Get-Date).ToString($DateTimeMessageFormat)}
$DateFileFormat = 'yyyyMMdd' ###20190403###
[ScriptBlock]$GetCurrentDateFileFormat = {(Get-Date).ToString($DateFileFormat)}
$DateTimeFileFormat = 'yyyyMMdd_HHmmss' ###20190403_115354###
[ScriptBlock]$GetCurrentDateTimeFileFormat = {(Get-Date).ToString($DateTimeFileFormat)}
$TextInfo = (Get-Culture).TextInfo
$LoggingDetails = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$LoggingDetails.Add('LogMessage', $Null)
$LoggingDetails.Add('WarningMessage', $Null)
$LoggingDetails.Add('ErrorMessage', $Null)
$CommonParameterList = New-Object -TypeName 'System.Collections.Generic.List[String]'
$CommonParameterList.AddRange([System.Management.Automation.PSCmdlet]::CommonParameters)
$CommonParameterList.AddRange([System.Management.Automation.PSCmdlet]::OptionalCommonParameters)
$FileSystemObject = New-Object -ComObject 'Scripting.FileSystemObject'
[ScriptBlock]$ErrorHandlingDefinition = {
$ErrorMessageList = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ErrorMessageList.Add('Message', $_.Exception.Message)
$ErrorMessageList.Add('Category', $_.Exception.ErrorRecord.FullyQualifiedErrorID)
$ErrorMessageList.Add('Script', $_.InvocationInfo.ScriptName)
$ErrorMessageList.Add('LineNumber', $_.InvocationInfo.ScriptLineNumber)
$ErrorMessageList.Add('LinePosition', $_.InvocationInfo.OffsetInLine)
$ErrorMessageList.Add('Code', $_.InvocationInfo.Line.Trim())
ForEach ($ErrorMessage In $ErrorMessageList.GetEnumerator())
{
$LoggingDetails.ErrorMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - ERROR: $($ErrorMessage.Key): $($ErrorMessage.Value)"
Write-Warning -Message ($LoggingDetails.ErrorMessage)
}
Switch (($ContinueOnError.IsPresent -eq $False) -or ($ContinueOnError -eq $False))
{
{($_ -eq $True)}
{
Throw
}
}
}
#Determine the date and time we executed the function
$FunctionStartTime = (Get-Date)
[String]$FunctionName = $MyInvocation.MyCommand
[System.IO.FileInfo]$InvokingScriptPath = $MyInvocation.PSCommandPath
[System.IO.DirectoryInfo]$InvokingScriptDirectory = $InvokingScriptPath.Directory.FullName
[System.IO.FileInfo]$FunctionPath = "$($InvokingScriptDirectory.FullName)\Functions\$($FunctionName).ps1"
[System.IO.DirectoryInfo]$FunctionDirectory = "$($FunctionPath.Directory.FullName)"
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($FunctionName)`' is beginning. Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
#Define Default Action Preferences
$ErrorActionPreference = 'Stop'
[String[]]$AvailableScriptParameters = (Get-Command -Name ($FunctionName)).Parameters.GetEnumerator() | Where-Object {($_.Value.Name -inotin $CommonParameterList)} | ForEach-Object {"-$($_.Value.Name):$($_.Value.ParameterType.Name)"}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Available Function Parameter(s) = $($AvailableScriptParameters -Join ', ')"
Write-Verbose -Message ($LoggingDetails.LogMessage)
[String[]]$SuppliedScriptParameters = $PSBoundParameters.GetEnumerator() | ForEach-Object {"-$($_.Key):$($_.Value.GetType().Name)"}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Supplied Function Parameter(s) = $($SuppliedScriptParameters -Join ', ')"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($FunctionName) began on $($FunctionStartTime.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
#region Load any required libraries
[System.IO.DirectoryInfo]$LibariesDirectory = "$($FunctionDirectory.FullName)\Libraries"
Switch ([System.IO.Directory]::Exists($LibariesDirectory.FullName))
{
{($_ -eq $True)}
{
$LibraryPatternList = New-Object -TypeName 'System.Collections.Generic.List[String]'
#$LibraryPatternList.Add('')
Switch ($LibraryPatternList.Count -gt 0)
{
{($_ -eq $True)}
{
$LibraryList = Get-ChildItem -Path ($LibariesDirectory.FullName) -Include ($LibraryPatternList.ToArray()) -Recurse -Force | Where-Object {($_ -is [System.IO.FileInfo])}
$LibraryListCount = ($LibraryList | Measure-Object).Count
Switch ($LibraryListCount -gt 0)
{
{($_ -eq $True)}
{
For ($LibraryListIndex = 0; $LibraryListIndex -lt $LibraryListCount; $LibraryListIndex++)
{
$Library = $LibraryList[$LibraryListIndex]
[Byte[]]$LibraryBytes = [System.IO.File]::ReadAllBytes($Library.FullName)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to load assembly `"$($Library.FullName)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$Null = [System.Reflection.Assembly]::Load($LibraryBytes)
}
}
}
}
}
}
}
#endregion
#region Set Default Parameter Values
Switch ($True)
{
{($Null -ieq $SegmentSize) -or ($SegmentSize -eq 0)}
{
[Int]$SegmentSize = 8192
}
}
#endregion
#Create an object that will contain the functions output.
$OutputObjectList = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
}
}
Process
{
Try
{
Switch ($Null -ine $Path)
{
{($_ -eq $True)}
{
$GetChildItemParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$GetChildItemParameters.Path = $Path
$GetChildItemParameters.Force = $True
$GetChildItemParameters.ErrorAction = [System.Management.Automation.Actionpreference]::SilentlyContinue
Switch ($True)
{
{([String]::IsNullOrEmpty($Include) -eq $False) -and ([String]::IsNullOrWhiteSpace($Include) -eq $False)}
{
$GetChildItemParameters.Include = $Include
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - File(s) matching $($GetChildItemParameters.Include -Join ', ') will be included."
Write-Verbose -Message ($LoggingDetails.LogMessage)
}
{([String]::IsNullOrEmpty($Exclude) -eq $False) -and ([String]::IsNullOrWhiteSpace($Exclude) -eq $False)}
{
$GetChildItemParameters.Exclude = $Exclude
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - File(s) matching $($GetChildItemParameters.Exclude -Join ', ') will be excluded."
Write-Verbose -Message ($LoggingDetails.LogMessage)
}
{($Recurse.IsPresent -eq $True)}
{
$GetChildItemParameters.Recurse = $True
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - The search will be performed recursively."
Write-Verbose -Message ($LoggingDetails.LogMessage)
}
}
$FileList = Get-ChildItem @GetChildItemParameters | Where-Object {($_ -is [System.IO.FileInfo])}
$FileListDetails = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$FileListDetails.Count = ($FileList | Measure-Object).Count
Switch ($FileListDetails.Count -gt 0)
{
{($_ -eq $True)}
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - $($FileListDetails.Count) file(s) will be copied in $($SegmentSize) MB segments to the destination directory of `"$($Destination.FullName)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$FileListDetails.TotalBytes = ($FileList | Measure-Object -Sum 'Length').Sum
$FileListDetails.TransferredBytes = 0
$FileListDetails.PercentComplete = 0
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - A total of $([System.Math]::Round(($FileListDetails.TotalBytes / 1MB), 2)) MB needs to be transferred."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$StopWatchTable = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$StopWatchTable.Primary = New-Object -TypeName 'System.Diagnostics.Stopwatch'
$StopWatchTable.Secondary = New-Object -TypeName 'System.Diagnostics.Stopwatch'
$Null = $StopWatchTable.Primary.Start()
For ($FileListIndex = 0; $FileListIndex -lt $FileListDetails.Count; $FileListIndex++)
{
Try
{
$FileObjectProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$FileObjectProperties.Source = ($FileList[$FileListIndex]) -As [System.IO.FileInfo]
Switch ($Recurse.IsPresent)
{
{($_ -eq $True)}
{
$FileObjectProperties.SourceSegmentList = $FileObjectProperties.Source.FullName.Replace($Path, '').Split('\', [System.StringSplitOptions]::RemoveEmptyEntries) -As [System.Collections.Generic.List[String]]
$FileObjectProperties.Destination = (Join-Path -Path ($Destination.FullName) -ChildPath ($FileObjectProperties.SourceSegmentList -Join '\')) -As [System.IO.FileInfo]
$FileObjectProperties.Remove('SourceSegmentList')
}
Default
{
$FileObjectProperties.Destination = "$($Destination.FullName)\$($FileObjectProperties.Source.Name)" -As [System.IO.FileInfo]
}
}
Switch ($True)
{
{([System.IO.Directory]::Exists($FileObjectProperties.Destination.Directory.FullName) -eq $False)}
{
$Null = [System.IO.Directory]::CreateDirectory($FileObjectProperties.Destination.Directory.FullName)
}
}
Switch (([System.IO.File]::Exists($FileObjectProperties.Destination.FullName) -eq $False) -or ($Force.IsPresent -eq $True))
{
{($_ -eq $True)}
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to copy `"$($FileObjectProperties.Source.FullName)`" to `"$($FileObjectProperties.Destination.FullName)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$FileDetails = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$FileDetails.Source = [System.IO.File]::OpenRead($FileObjectProperties.Source.FullName)
$FileDetails.Destination = [System.IO.File]::Create($FileObjectProperties.Destination.FullName)
$FileDetails.Buffer = New-Object -TypeName 'Byte[]' -ArgumentList ($SegmentSize * 1024)
$FileDetails.SegmentBytes = 0
$FileDetails.TransferredBytes = 0
$FileDetails.Number = $FileListIndex + 1
$Null = $StopWatchTable.Secondary.Start()
Do
{
$FileDetails.SegmentBytes = $FileDetails.Source.Read($FileDetails.Buffer, 0, $FileDetails.Buffer.Length)
$FileDetails.Destination.Write($FileDetails.Buffer, 0, $FileDetails.SegmentBytes)
$FileDetails.TransferredBytes = $FileDetails.TransferredBytes + $FileDetails.SegmentBytes
$FileListDetails.TransferredBytes = $FileListDetails.TransferredBytes + $FileDetails.SegmentBytes
Switch ($FileDetails.Source.Length -gt 1)
{
{($_ -eq $True)}
{
$FileDetails.PercentComplete = (($FileDetails.TransferredBytes / $FileDetails.Source.Length) * 100) -As [Int]
}
Default
{
$FileDetails.PercentComplete = (100) -As [Int]
}
}
$FileDetails.PercentComplete = [System.Math]::Round($FileDetails.PercentComplete, 2)
$FileDetails.TotalSecondsElasped = $StopWatchTable.Secondary.Elapsed.TotalSeconds -As [Int]
Switch ($FileDetails.TotalSecondsElasped -ne 0)
{
{($_ -eq $True)}
{
$FileDetails.TransferRate = ($FileDetails.TransferredBytes / $FileDetails.TotalSecondsElasped / 1MB) -As [Single]
}
Default
{
$FileDetails.TransferRate = (0.0) -As [Single]
}
}
$FileDetails.TransferRate = [System.Math]::Round($FileDetails.TransferRate, 2)
Switch (($Total % 1MB) -eq 0)
{
{($_ -eq $True)}
{
Switch ($FileDetails.PercentComplete -gt 0)
{
{($_ -eq $True)}
{
$FileDetails.SecondsRemaining = ((($FileDetails.TotalSecondsElasped / $FileDetails.PercentComplete) * 100) - $FileDetails.TotalSecondsElasped) -As [Int]
}
Default
{
$FileDetails.SecondsRemaining = (0) -As [Int]
}
}
$FileListDetails.PercentComplete = [System.Math]::Round((($FileListDetails.TransferredBytes / $FileListDetails.TotalBytes) * 100), 2)
$FileListDetails.TotalSecondsElasped = $StopWatchTable.Primary.Elapsed.TotalSeconds -As [Int]
Switch ($FileListDetails.PercentComplete -gt 0)
{
{($_ -eq $True)}
{
$FileListDetails.SecondsRemaining = ((($FileListDetails.TotalSecondsElasped / $FileListDetails.PercentComplete) * 100) - $FileListDetails.TotalSecondsElasped) -As [Int]
}
Default
{
$FileListDetails.SecondsRemaining = ((($FileListDetails.TotalSecondsElasped / $FileListDetails.PercentComplete) * 100) - $FileListDetails.TotalSecondsElasped) -As [Int]
}
}
$TaskSequence = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$TaskSequence.Environment = Try {New-Object -ComObject 'Microsoft.SMS.TSEnvironment'} Catch {$Null}
$TaskSequence.IsRunning = $Null -ine $TaskSequence.Environment
Switch ($TaskSequence.IsRunning)
{
{($_ -eq $True)}
{
$FileProgressParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$FileProgressParameters.ID = 1
$FileProgressParameters.Activity = "$($FileDetails.PercentComplete)% - Downloading $($FileSystemObject.GetFile($FileObjectProperties.Destination.FullName).ShortName) @ $($FileDetails.TransferRate) Mbps ($($FileDetails.Number) of $($FileListDetails.Count))"
$FileProgressParameters.Status = "$($FileDetails.PercentComplete)% - Downloading $($FileSystemObject.GetFile($FileObjectProperties.Destination.FullName).ShortName) @ $($FileDetails.TransferRate) Mbps ($($FileDetails.Number) of $($FileListDetails.Count))"
$FileProgressParameters.PercentComplete = $FileDetails.PercentComplete
$FileProgressParameters.SecondsRemaining = $FileDetails.SecondsRemaining
Write-Progress @FileProgressParameters
}
Default
{
$TotalProgressParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$TotalProgressParameters.ID = 1
$TotalProgressParameters.Activity = "$($FileListDetails.PercentComplete)% - Copying file $($FileDetails.Number) of $($FileListDetails.Count) ($($FileListDetails.Count - $($FileListIndex)) left)"
$TotalProgressParameters.Status = $FileObjectProperties.Source.FullName
$TotalProgressParameters.PercentComplete = $FileListDetails.PercentComplete
$TotalProgressParameters.SecondsRemaining = $FileListDetails.SecondsRemaining
Write-Progress @TotalProgressParameters
$FileProgressParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$FileProgressParameters.ParentID = $TotalProgressParameters.ID
$FileProgressParameters.ID = $TotalProgressParameters.ID + 1
$FileProgressParameters.Activity = "$($FileDetails.PercentComplete)% - Copying @ $($FileDetails.TransferRate) Mbps"
$FileProgressParameters.Status = $FileObjectProperties.Destination.FullName
$FileProgressParameters.PercentComplete = $FileDetails.PercentComplete
$FileProgressParameters.SecondsRemaining = $FileDetails.SecondsRemaining
Write-Progress @FileProgressParameters
}
}
}
}
Switch ($RandomDelay.IsPresent)
{
{($_ -eq $True)}
{
$Delay = Get-Random -Minimum 1 -Maximum 1500
$Null = Start-Sleep -Milliseconds ($Delay)
}
}
}
While ($FileDetails.SegmentBytes -gt 0)
$Null = $FileDetails.Source.Close()
$Null = $FileDetails.Destination.Close()
$Null = $StopWatchTable.Secondary.Stop()
$FileDetails = Get-Item -Path $FileObjectProperties.Destination.FullName -Force
$FileAttributeList = $FileDetails.PSObject.Properties | Where-Object {($_.MemberType -iin @('NoteProperty', 'Property')) -and ($_.TypeNameOfValue -ieq 'System.DateTime') -and ($_.IsSettable -eq $True) -and ($_.Name -inotmatch '.*UTC.*')}
ForEach ($FileAttribute In $FileAttributeList)
{
#$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to update file attribute `"$($FileAttribute.Name)`" on file `"$($FileDetails.FullName)`" from `"$($FileDetails.$($FileAttribute.Name))`" to `"$($FileObjectProperties.Source.$($FileAttribute.Name))`". Please Wait..."
#Write-Verbose -Message ($LoggingDetails.LogMessage)
$FileDetails.$($FileAttribute.Name) = $FileObjectProperties.Source.$($FileAttribute.Name)
}
$FileObjectProperties.Destination = $FileDetails
$FileObjectProperties.Status = 'Successful'
}
Default
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - File `"$($FileObjectProperties.Destination.FullName)`" already exists. Skipping."
Write-Warning -Message ($LoggingDetails.WarningMessage)
$FileObjectProperties.Status = 'Skipped'
}
}
}
Catch
{
$FileObjectProperties.Status = 'Error'
$ErrorHandlingDefinition.Invoke()
}
Finally
{
$FileObjectProperties.TimeToTransfer = $StopWatchTable.Secondary.Elapsed
$Null = $StopWatchTable.Secondary.Reset()
$FileObject = New-Object -TypeName 'PSObject' -Property ($FileObjectProperties)
$OutputObjectList.Add($FileObject)
}
}
$Null = $StopWatchTable.Primary.Stop()
$Null = $StopWatchTable.Primary.Reset()
$FileListStatusGroups = $OutputObjectList | Group-Object -Property 'Status' | Sort-Object -Property @('Name')
ForEach ($FileListStatusGroup In $FileListStatusGroups)
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - $($FileListStatusGroup.Count) of $($FileListDetails.Count) file(s) have a status of `"$($FileListStatusGroup.Name)`"."
Write-Verbose -Message ($LoggingDetails.LogMessage)
}
}
Default
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - There are $($FileListDetails.Count) file(s) to copy to `"$($Destination.FullName)`". No further action will be taken."
Write-Warning -Message ($LoggingDetails.WarningMessage)
}
}
}
Default
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - There were 0 paths specified to search. No further action will be taken."
Write-Warning -Message ($LoggingDetails.WarningMessage)
}
}
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
$Null = Start-Sleep -Seconds 3
}
}
End
{
Try
{
#Determine the date and time the function completed execution
$FunctionEndTime = (Get-Date)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($FunctionName) ended on $($FunctionEndTime.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
#Log the total script execution time
$FunctionExecutionTimespan = New-TimeSpan -Start ($FunctionStartTime) -End ($FunctionEndTime)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function execution took $($FunctionExecutionTimespan.Hours.ToString()) hour(s), $($FunctionExecutionTimespan.Minutes.ToString()) minute(s), $($FunctionExecutionTimespan.Seconds.ToString()) second(s), and $($FunctionExecutionTimespan.Milliseconds.ToString()) millisecond(s)"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($FunctionName)`' is completed."
Write-Verbose -Message ($LoggingDetails.LogMessage)
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
#Write the object to the powershell pipeline
$OutputObjectList = $OutputObjectList.ToArray()
Write-Output -InputObject ($OutputObjectList)
}
}
}
#endregion
+300
View File
@@ -0,0 +1,300 @@
## Microsoft Function Naming Convention: http://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx
#region Function Get-WindowsReleaseHistory
Function Get-WindowsReleaseHistory
{
<#
.SYNOPSIS
Retrieves the Windows release history by scraping the release information from the internet
.DESCRIPTION
Slightly more detailed description of what your function does
.EXAMPLE
Get-WindowsReleaseHistory -Verbose
.EXAMPLE
Get-WindowsReleaseHistory -Force -Verbose
.NOTES
a global variable named 'WindowsReleaseHistory' will be created that will store the release details. To keep web request traffic to a minimum, repeat executions of this function will return cached data unless the '-Force' parameter is specified.
$Global:WindowsReleaseHistory
.LINK
https://learn.microsoft.com/en-us/windows/release-health/release-information
.LINK
https://learn.microsoft.com/en-us/windows/release-health/windows11-release-information
#>
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$False)]
[Switch]$Force,
[Parameter(Mandatory=$False)]
[Switch]$ContinueOnError
)
Begin
{
Try
{
$DateTimeLogFormat = 'dddd, MMMM dd, yyyy @ hh:mm:ss.FFF tt' ###Monday, January 01, 2019 @ 10:15:34.000 AM###
[ScriptBlock]$GetCurrentDateTimeLogFormat = {(Get-Date).ToString($DateTimeLogFormat)}
$DateTimeMessageFormat = 'MM/dd/yyyy HH:mm:ss.FFF' ###03/23/2022 11:12:48.347###
[ScriptBlock]$GetCurrentDateTimeMessageFormat = {(Get-Date).ToString($DateTimeMessageFormat)}
$DateFileFormat = 'yyyyMMdd' ###20190403###
[ScriptBlock]$GetCurrentDateFileFormat = {(Get-Date).ToString($DateFileFormat)}
$DateTimeFileFormat = 'yyyyMMdd_HHmmss' ###20190403_115354###
[ScriptBlock]$GetCurrentDateTimeFileFormat = {(Get-Date).ToString($DateTimeFileFormat)}
$TextInfo = (Get-Culture).TextInfo
$LoggingDetails = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$LoggingDetails.Add('LogMessage', $Null)
$LoggingDetails.Add('WarningMessage', $Null)
$LoggingDetails.Add('ErrorMessage', $Null)
$CommonParameterList = New-Object -TypeName 'System.Collections.Generic.List[String]'
$CommonParameterList.AddRange([System.Management.Automation.PSCmdlet]::CommonParameters)
$CommonParameterList.AddRange([System.Management.Automation.PSCmdlet]::OptionalCommonParameters)
[ScriptBlock]$ErrorHandlingDefinition = {
$ErrorMessageList = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ErrorMessageList.Add('Message', $_.Exception.Message)
$ErrorMessageList.Add('Category', $_.Exception.ErrorRecord.FullyQualifiedErrorID)
$ErrorMessageList.Add('Script', $_.InvocationInfo.ScriptName)
$ErrorMessageList.Add('LineNumber', $_.InvocationInfo.ScriptLineNumber)
$ErrorMessageList.Add('LinePosition', $_.InvocationInfo.OffsetInLine)
$ErrorMessageList.Add('Code', $_.InvocationInfo.Line.Trim())
ForEach ($ErrorMessage In $ErrorMessageList.GetEnumerator())
{
$LoggingDetails.ErrorMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - ERROR: $($ErrorMessage.Key): $($ErrorMessage.Value)"
Write-Warning -Message ($LoggingDetails.ErrorMessage)
}
Switch (($ContinueOnError.IsPresent -eq $False) -or ($ContinueOnError -eq $False))
{
{($_ -eq $True)}
{
Throw
}
}
}
#Determine the date and time we executed the function
$FunctionStartTime = (Get-Date)
[String]$FunctionName = $MyInvocation.MyCommand
[System.IO.FileInfo]$FunctionPath = $PSCommandPath
[System.IO.DirectoryInfo]$FunctionDirectory = "$($FunctionPath.Directory.FullName)"
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($FunctionName)`' is beginning. Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
#Define Default Action Preferences
$ErrorActionPreference = 'Stop'
[String[]]$AvailableScriptParameters = (Get-Command -Name ($FunctionName)).Parameters.GetEnumerator() | Where-Object {($_.Value.Name -inotin $CommonParameterList)} | ForEach-Object {"-$($_.Value.Name):$($_.Value.ParameterType.Name)"}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Available Function Parameter(s) = $($AvailableScriptParameters -Join ', ')"
Write-Verbose -Message ($LoggingDetails.LogMessage)
[String[]]$SuppliedScriptParameters = $PSBoundParameters.GetEnumerator() | ForEach-Object {"-$($_.Key):$($_.Value.GetType().Name)"}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Supplied Function Parameter(s) = $($SuppliedScriptParameters -Join ', ')"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($FunctionName) began on $($FunctionStartTime.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
#region Load any required libraries
[System.IO.DirectoryInfo]$LibariesDirectory = "$($FunctionDirectory.FullName)\Libraries"
Switch ([System.IO.Directory]::Exists($LibariesDirectory.FullName))
{
{($_ -eq $True)}
{
$LibraryPatternList = New-Object -TypeName 'System.Collections.Generic.List[String]'
$LibraryPatternList.Add('HtmlAgilityPack.dll')
Switch ($LibraryPatternList.Count -gt 0)
{
{($_ -eq $True)}
{
$LibraryList = Get-ChildItem -Path ($LibariesDirectory.FullName) -Include ($LibraryPatternList.ToArray()) -Recurse -Force | Where-Object {($_ -is [System.IO.FileInfo])}
$LibraryListCount = ($LibraryList | Measure-Object).Count
Switch ($LibraryListCount -gt 0)
{
{($_ -eq $True)}
{
For ($LibraryListIndex = 0; $LibraryListIndex -lt $LibraryListCount; $LibraryListIndex++)
{
$Library = $LibraryList[$LibraryListIndex]
[Byte[]]$LibraryBytes = [System.IO.File]::ReadAllBytes($Library.FullName)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to load assembly `"$($Library.FullName)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
$Null = [System.Reflection.Assembly]::Load($LibraryBytes)
}
}
}
}
}
}
}
#endregion
#Create an object that will contain the functions output.
$OutputObjectList = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
}
}
Process
{
Try
{
Switch (($Null -ieq $Global:WindowsReleaseHistory) -or ($Force.IsPresent -eq $True))
{
{($_ -eq $True)}
{
$URLList = New-Object -TypeName 'System.Collections.Generic.List[System.URI]'
$URLList.Add('https://learn.microsoft.com/en-us/windows/release-health/release-information')
$URLList.Add('https://learn.microsoft.com/en-us/windows/release-health/windows11-release-information')
For ($URLListIndex = 0; $URLListIndex -lt $URLList.Count; $URLListIndex++)
{
$URL = $URLList[$URLListIndex]
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to retrieve data from `"$($URL.OriginalString)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$HTMLWebRequest = New-Object -TypeName 'HtmlAgilityPack.HtmlWeb'
$HTMLWebRequestObject = $HTMLWebRequest.Load($URL.OriginalString)
$HTMLDocumentObject = $HTMLWebRequestObject.DocumentNode
$MetadataList = $HTMLDocumentObject.SelectNodes('/html/head//meta') | Where-Object {($_.OuterHTML -imatch '.*og\:title.*')}
$OGTitle = ($MetadataList[0].Attributes | Where-Object {($_.Name -ieq 'Content')}).Value
$HistoryTableList = $HTMLDocumentObject.SelectNodes('//table') | Where-Object {($_.ID -imatch '(^HistoryTable_\d+$)')}
$RootNodeList = $HTMLDocumentObject.SelectNodes('//strong')
For ($RootNodeListIndex = 0; $RootNodeListIndex -lt $RootNodeList.Count; $RootNodeListIndex++)
{
$RootNode = $RootNodeList[$RootNodeListIndex]
$RootNodeRegexData = [Regex]::Match($RootNode.InnerText, '(?:.*Version\s+)(?<OSReleaseID>\w{4,4})(?:.*)(?:\s+\(OS\s+build\s+)(?<OSBuild>\d{5,5})(?:.+)')
Switch ($RootNodeRegexData.Success)
{
{($_ -eq $True)}
{
$OutputObjectProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$OutputObjectProperties.Vendor = 'Microsoft'
$OutputObjectProperties.Name = [Regex]::Match($OGTitle, 'W.+\d+').Value
$OutputObjectProperties.ReleaseID = ($RootNodeRegexData.Groups | Where-Object {($_.Name -ieq 'OSReleaseID')}).Value
$OutputObjectProperties.Build = ($RootNodeRegexData.Groups | Where-Object {($_.Name -ieq 'OSBuild')}).Value
$OutputObjectProperties.Version = "10.0.$($OutputObjectProperties.Build)" -As [System.Version]
$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
For ($HistoryTableChildNodeIndex = 0; $HistoryTableChildNodeIndex -lt $HistoryTableChildNodeList.Count; $HistoryTableChildNodeIndex++)
{
$HistoryTableChildNode = $HistoryTableChildNodeList[$HistoryTableChildNodeIndex]
$InnerTextLines = $HistoryTableChildNode.InnerText.Split("`n", [System.StringSplitOptions]::RemoveEmptyEntries).Trim()
For ($InnerTextLineIndex = 0; $InnerTextLineIndex -lt $InnerTextLines.Count; $InnerTextLineIndex++)
{
$InnerTextLine = $InnerTextLines[$InnerTextLineIndex]
#$InnerTextLine
}
}
#>
$OutputObject = New-Object -TypeName 'PSObject' -Property ($OutputObjectProperties)
$OutputObjectList.Add($OutputObject)
}
}
}
}
#Write the object to the powershell pipeline
$OutputObjectList = $OutputObjectList.ToArray()
$Global:WindowsReleaseHistory = $OutputObjectList | Sort-Object -Property @('Version')
}
Default
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - The Windows release history has already been retrieved. Returning cached results in order to reduce web request traffic."
Write-Warning -Message ($LoggingDetails.WarningMessage)
}
}
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
}
}
End
{
Try
{
#Determine the date and time the function completed execution
$FunctionEndTime = (Get-Date)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($FunctionName) ended on $($FunctionEndTime.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
#Log the total script execution time
$FunctionExecutionTimespan = New-TimeSpan -Start ($FunctionStartTime) -End ($FunctionEndTime)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function execution took $($FunctionExecutionTimespan.Hours.ToString()) hour(s), $($FunctionExecutionTimespan.Minutes.ToString()) minute(s), $($FunctionExecutionTimespan.Seconds.ToString()) second(s), and $($FunctionExecutionTimespan.Milliseconds.ToString()) millisecond(s)"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($FunctionName)`' is completed."
Write-Verbose -Message ($LoggingDetails.LogMessage)
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
Write-Output -InputObject ($Global:WindowsReleaseHistory)
}
}
}
#endregion
<#
Get-WindowsReleaseHistory -Force:$False -Verbose
#>
+343
View File
@@ -0,0 +1,343 @@
## Microsoft Function Naming Convention: http://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx
#region Function Invoke-FileDownload
Function Invoke-FileDownload
{
<#
.SYNOPSIS
Downloads the specified URL.
.DESCRIPTION
The file will only be downloaded if the last modified date of the source URL is different from the last modified date of the file that has already been downloaded or if the file have not already been downloaded.
.PARAMETER URL
The URL where the file is located.
.PARAMETER Destination
The full file path where the cabinet will be downloaded to. If not specified, a default value will be used.
.EXAMPLE
Invoke-FileDownload -URL 'https://dl.dell.com/catalog/DriverPackCatalog.cab' -Destination "$($Env:ProgramData)\Dell\DriverPackCatalog\DriverPackCatalog.cab" -Verbose
.EXAMPLE
$DownloadDetails = Invoke-FileDownload -URL 'https://dl.dell.com/catalog/DriverPackCatalog.cab' -Destination "$($Env:ProgramData)\Dell\DriverPackCatalog\DriverPackCatalog.cab" -Verbose
Write-Output -InputObject ($DownloadDetails)
.EXAMPLE
$InvokeFileDownloadParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$InvokeFileDownloadParameters.URL = 'https://dl.dell.com/catalog/DriverPackCatalog.cab' -As [System.URI]
$InvokeFileDownloadParameters.Destination = "$($Env:ProgramData)\Dell\DriverPackCatalog\DriverPackCatalog.cab" -As [System.IO.FileInfo]
$InvokeFileDownloadParameters.ContinueOnError = $False
$InvokeFileDownloadParameters.Verbose = $True
$InvokeFileDownloadResult = Invoke-FileDownload @InvokeFileDownloadParameters
Write-Output -InputObject ($InvokeFileDownloadResult)
.NOTES
NEL : {"report_to":"network-errors","max_age":3600}
Report-To : {"group":"network-errors","max_age":3600,"endpoints":[{"url":"https://www.dell.com/support/onlineapi/nellogger/log"}]}
Accept-Ranges : bytes
Content-Type : application/vnd.ms-cab-compressed
ETag : "8043933683ddd81:0"
Last-Modified : Tue, 11 Oct 2022 15:07:43 GMT
Server : Microsoft-IIS/10.0
X-Powered-By : ASP.NET
x-arr-set : arr4
Content-Length : 270867
Date : Thu, 20 Oct 2022 15:51:44 GMT
Connection : keep-alive
Akamai-Request-BC : [a=23.207.199.174,b=78861523,c=g,n=US_VA_STERLING,o=20940]
.LINK
https://learn.microsoft.com/en-us/dotnet/api/system.net.webrequest?view=netframework-4.8
.LINK
https://learn.microsoft.com/en-us/dotnet/api/system.net.webclient.downloaddata?view=netframework-4.8#system-net-webclient-downloaddata(system-uri)
#>
[CmdletBinding(ConfirmImpact = 'Low', SupportsShouldProcess = $True)]
Param
(
[Parameter(Mandatory=$True, ValueFromPipelineByPropertyName = $True)]
[ValidateNotNullOrEmpty()]
[ValidatePattern('^http(s)\:\/\/.*\/.*\.(.{3,4})$')]
[System.URI]$URL,
[Parameter(Mandatory=$False, ValueFromPipelineByPropertyName = $True)]
[ValidateNotNullOrEmpty()]
[System.IO.DirectoryInfo]$Destination,
[Parameter(Mandatory=$False, ValueFromPipelineByPropertyName = $True)]
[ValidateNotNullOrEmpty()]
[ValidatePattern('^.*\.(.*)$')]
[String]$FileName,
[Parameter(Mandatory=$False)]
[Switch]$ContinueOnError
)
Begin
{
Try
{
Switch ($True)
{
{([String]::IsNullOrEmpty($Destination) -eq $True) -or ([String]::IsNullOrWhiteSpace($Destination) -eq $True)}
{
[System.IO.DirectoryInfo]$Destination = "$($Env:Windir)\Temp"
}
{([String]::IsNullOrEmpty($FileName) -eq $True) -or ([String]::IsNullOrWhiteSpace($FileName) -eq $True)}
{
[String]$FileName = [System.IO.Path]::GetFileName($URL.OriginalString)
}
}
[System.IO.FileInfo]$DestinationPath = "$($Destination.FullName)\$($FileName)"
$DateTimeLogFormat = 'dddd, MMMM dd, yyyy @ hh:mm:ss tt' ###Monday, January 01, 2019 @ 10:15:34 AM###
[ScriptBlock]$GetCurrentDateTimeLogFormat = {(Get-Date).ToString($DateTimeLogFormat)}
$DateTimeMessageFormat = 'MM/dd/yyyy HH:mm:ss.FFF' ###03/23/2022 11:12:48.347###
[ScriptBlock]$GetCurrentDateTimeMessageFormat = {(Get-Date).ToString($DateTimeMessageFormat)}
$DateFileFormat = 'yyyyMMdd' ###20190403###
[ScriptBlock]$GetCurrentDateFileFormat = {(Get-Date).ToString($DateFileFormat)}
$DateTimeFileFormat = 'yyyyMMdd_HHmmss' ###20190403_115354###
[ScriptBlock]$GetCurrentDateTimeFileFormat = {(Get-Date).ToString($DateTimeFileFormat)}
$TextInfo = (Get-Culture).TextInfo
$LoggingDetails = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$LoggingDetails.Add('LogMessage', $Null)
$LoggingDetails.Add('WarningMessage', $Null)
$LoggingDetails.Add('ErrorMessage', $Null)
$CommonParameterList = New-Object -TypeName 'System.Collections.Generic.List[String]'
$CommonParameterList.AddRange([System.Management.Automation.PSCmdlet]::CommonParameters)
$CommonParameterList.AddRange([System.Management.Automation.PSCmdlet]::OptionalCommonParameters)
[ScriptBlock]$ErrorHandlingDefinition = {
$ErrorMessageList = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ErrorMessageList.Add('Message', $_.Exception.Message)
$ErrorMessageList.Add('Category', $_.Exception.ErrorRecord.FullyQualifiedErrorID)
$ErrorMessageList.Add('Script', $_.InvocationInfo.ScriptName)
$ErrorMessageList.Add('LineNumber', $_.InvocationInfo.ScriptLineNumber)
$ErrorMessageList.Add('LinePosition', $_.InvocationInfo.OffsetInLine)
$ErrorMessageList.Add('Code', $_.InvocationInfo.Line.Trim())
ForEach ($ErrorMessage In $ErrorMessageList.GetEnumerator())
{
$LoggingDetails.ErrorMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - ERROR: $($ErrorMessage.Key): $($ErrorMessage.Value)"
Write-Warning -Message ($LoggingDetails.ErrorMessage)
}
Switch (($ContinueOnError.IsPresent -eq $False) -or ($ContinueOnError -eq $False))
{
{($_ -eq $True)}
{
Throw
}
}
}
#Determine the date and time we executed the function
$FunctionStartTime = (Get-Date)
[String]$CmdletName = $MyInvocation.MyCommand.Name
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($CmdletName)`' is beginning. Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
#Define Default Action Preferences
$ErrorActionPreference = 'Stop'
[String[]]$AvailableScriptParameters = (Get-Command -Name ($CmdletName)).Parameters.GetEnumerator() | Where-Object {($_.Value.Name -inotin $CommonParameterList)} | ForEach-Object {"-$($_.Value.Name):$($_.Value.ParameterType.Name)"}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Available Function Parameter(s) = $($AvailableScriptParameters -Join ', ')"
Write-Verbose -Message ($LoggingDetails.LogMessage)
[String[]]$SuppliedScriptParameters = $PSBoundParameters.GetEnumerator() | ForEach-Object {"-$($_.Key):$($_.Value.GetType().Name)"}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Supplied Function Parameter(s) = $($SuppliedScriptParameters -Join ', ')"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($CmdletName) began on $($FunctionStartTime.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$OutputObjectProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$OutputObjectProperties.DownloadRequired = $False
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
}
}
Process
{
Try
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to create a web request for `"$($URL.OriginalString)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$WebRequest = [System.Net.WebRequest]::Create($URL.OriginalString)
$WebRequestResponse = $WebRequest.GetResponse()
$WebRequestResponseHeaders = $WebRequestResponse.Headers
$WebRequestHeaderProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
ForEach ($WebRequestResponseHeader In $WebRequestResponseHeaders.AllKeys)
{
$WebRequestHeaderProperties."$($WebRequestResponseHeader)" = ($WebRequestResponseHeaders.GetValues($WebRequestResponseHeader))[0]
}
$WebRequestHeaders = New-Object -TypeName 'PSObject' -Property ($WebRequestHeaderProperties)
$WebRequestHeaders.'Last-Modified' = (Get-Date -Date $WebRequestHeaders.'Last-Modified').ToUniversalTime()
$ContentLengthInMB = [System.Math]::Round(($WebRequestHeaders.'Content-Length' / 1MB), 2)
[ScriptBlock]$ExecuteDownload = {
$WebClient = New-Object -TypeName 'System.Net.WebClient'
$WebClient.UseDefaultCredentials = $True
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to download data stream from `"$($URL.OriginalString)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Download Size: $($ContentLengthInMB) MegaBytes"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$Null = Measure-Command -Expression {[Byte[]]$DownloadedData = $WebClient.DownloadData($URL.OriginalString)} -OutVariable 'DownloadExecutionTimespan'
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Stream download took $($DownloadExecutionTimespan.Hours.ToString()) hour(s), $($DownloadExecutionTimespan.Minutes.ToString()) minute(s), $($DownloadExecutionTimespan.Seconds.ToString()) second(s), and $($DownloadExecutionTimespan.Milliseconds.ToString()) millisecond(s)"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to flush the downloaded data stream to file `"$($DestinationPath.FullName)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
If ([System.IO.Directory]::Exists($DestinationPath.Directory.FullName) -eq $False) {$Null = [System.IO.Directory]::CreateDirectory($DestinationPath.Directory.FullName)}
$Null = [System.IO.File]::WriteAllBytes($DestinationPath.FullName, $DownloadedData)
[Int]$SecondsToWait = 3
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Pausing script execution for $($SecondsToWait) second(s). Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$Null = Start-Sleep -Seconds ($SecondsToWait)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to update the last modified date of `"$($DestinationPath.FullName)`" to match `"$($URL.OriginalString)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Last Modified Date (Local): $($DestinationPath.LastWriteTimeUTC.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Last Modified Date (Source): $($WebRequestHeaders.'Last-Modified'.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$Null = (Get-Item -Path $DestinationPath.FullName -Force).LastWriteTimeUTC = $WebRequestHeaders.'Last-Modified'
$Null = $WebClient.Dispose()
}
Switch ([System.IO.File]::Exists($DestinationPath.FullName))
{
{($_ -eq $True)}
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Destination path `"$($DestinationPath.FullName)`" already exists."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to check the last modified date of `"$($DestinationPath.FullName)`" to see if a download is necessary."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Last Modified Date (Source): $($WebRequestHeaders.'Last-Modified'.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Last Modified Date (Local): $($DestinationPath.LastWriteTimeUTC.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
Switch (($DestinationPath.LastWriteTimeUTC -ine $WebRequestHeaders.'Last-Modified'))
{
{($_ -eq $True)}
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - A redownload of `"$($URL.OriginalString)`" is necessary."
Write-Warning -Message ($LoggingDetails.WarningMessage)
$OutputObjectProperties.DownloadRequired = $True
$ExecuteDownload.InvokeReturnAsIs()
}
Default
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - A redownload of `"$($URL.OriginalString)`" is not necessary."
Write-Verbose -Message ($LoggingDetails.LogMessage)
}
}
}
Default
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Destination path `"$($DestinationPath.FullName)`" does not exist."
Write-Warning -Message ($LoggingDetails.WarningMessage)
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - A download of `"$($URL.OriginalString)`" is necessary."
Write-Warning -Message ($LoggingDetails.WarningMessage)
$OutputObjectProperties.DownloadRequired = $True
$ExecuteDownload.InvokeReturnAsIs()
}
}
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
Try {$Null = $WebRequestResponse.Dispose()} Catch {}
}
}
End
{
Try
{
#Determine the date and time the function completed execution
$FunctionEndTime = (Get-Date)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($CmdletName) ended on $($FunctionEndTime.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
#Log the total script execution time
$FunctionExecutionTimespan = New-TimeSpan -Start ($FunctionStartTime) -End ($FunctionEndTime)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function execution took $($FunctionExecutionTimespan.Hours.ToString()) hour(s), $($FunctionExecutionTimespan.Minutes.ToString()) minute(s), $($FunctionExecutionTimespan.Seconds.ToString()) second(s), and $($FunctionExecutionTimespan.Milliseconds.ToString()) millisecond(s)"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($CmdletName)`' is completed."
Write-Verbose -Message ($LoggingDetails.LogMessage)
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
$DestinationPathDetails = Get-Item -Path $DestinationPath.FullName -Force
$OutputObjectProperties.DownloadPath = $DestinationPathDetails
$OutputObjectProperties.URL = $URL
$OutputObjectProperties.URLHeaders = $WebRequestHeaders
$OutputObject = New-Object -TypeName 'PSObject' -Property ($OutputObjectProperties)
Write-Output -InputObject ($OutputObject)
}
}
}
#endregion
@@ -0,0 +1,565 @@
## Microsoft Function Naming Convention: http://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx
#region Function Invoke-FileDownloadWithProgress
Function Invoke-FileDownloadWithProgress
{
<#
.SYNOPSIS
Downloads the specified URL.
.DESCRIPTION
The file will only be downloaded if the last modified date of the source URL is different from the last modified date of the file that has already been downloaded or if the file have not already been downloaded.
.PARAMETER URL
The URL where the file is located.
.PARAMETER Destination
The directory path where the URL will be downloaded to. If not specified, a default value will be used.
.EXAMPLE
Invoke-FileDownloadWithProgress -URL 'https://dl.dell.com/catalog/DriverPackCatalog.cab' -Destination "$($Env:ProgramData)\Dell\DriverPackCatalog" -FileName "DriverPackCatalog.cab" -Verbose
.EXAMPLE
$DownloadDetails = Invoke-FileDownloadWithProgress -URL 'https://dl.dell.com/catalog/DriverPackCatalog.cab' -Destination "$($Env:ProgramData)\Dell\DriverPackCatalog" -Verbose
Write-Output -InputObject ($DownloadDetails)
.EXAMPLE
$InvokeFileDownloadWithProgressParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$InvokeFileDownloadWithProgressParameters.URL = 'https://dl.dell.com/catalog/DriverPackCatalog.cab' -As [System.URI]
$InvokeFileDownloadWithProgressParameters.Destination = "$($Env:ProgramData)\Dell\DriverPackCatalog" -As [System.IO.DirectoryInfo]
$InvokeFileDownloadWithProgressParameters.FileName = "DriverPackCatalog.cab"
$InvokeFileDownloadWithProgressParameters.ContinueOnError = $False
$InvokeFileDownloadWithProgressParameters.Verbose = $True
$InvokeFileDownloadWithProgressResult = Invoke-FileDownloadWithProgress @InvokeFileDownloadWithProgressParameters
Write-Output -InputObject ($InvokeFileDownloadWithProgressResult)
.NOTES
NEL : {"report_to":"network-errors","max_age":3600}
Report-To : {"group":"network-errors","max_age":3600,"endpoints":[{"url":"https://www.dell.com/support/onlineapi/nellogger/log"}]}
Accept-Ranges : bytes
Content-Type : application/vnd.ms-cab-compressed
ETag : "8043933683ddd81:0"
Last-Modified : Tue, 11 Oct 2022 15:07:43 GMT
Server : Microsoft-IIS/10.0
X-Powered-By : ASP.NET
x-arr-set : arr4
Content-Length : 270867
Date : Thu, 20 Oct 2022 15:51:44 GMT
Connection : keep-alive
Akamai-Request-BC : [a=23.207.199.174,b=78861523,c=g,n=US_VA_STERLING,o=20940]
.LINK
https://learn.microsoft.com/en-us/dotnet/api/system.net.webrequest?view=netframework-4.8
.LINK
https://learn.microsoft.com/en-us/dotnet/api/system.net.webclient.downloadfiletaskasync?view=netframework-4.8
#>
[CmdletBinding(ConfirmImpact = 'Low', SupportsShouldProcess = $True)]
Param
(
[Parameter(Mandatory=$True, ValueFromPipelineByPropertyName = $True)]
[ValidateNotNullOrEmpty()]
[ValidatePattern('^http(s)\:\/\/.*\/.*\.(.{3,4})$')]
[System.URI]$URL,
[Parameter(Mandatory=$False, ValueFromPipelineByPropertyName = $True)]
[ValidateNotNullOrEmpty()]
[System.IO.DirectoryInfo]$Destination,
[Parameter(Mandatory=$False, ValueFromPipelineByPropertyName = $True)]
[ValidateNotNullOrEmpty()]
[ValidatePattern('^.*\.(.*)$')]
[String]$FileName,
[Parameter(Mandatory=$False)]
[Switch]$ContinueOnError
)
Begin
{
Try
{
Switch ($True)
{
{([String]::IsNullOrEmpty($Destination) -eq $True) -or ([String]::IsNullOrWhiteSpace($Destination) -eq $True)}
{
[System.IO.DirectoryInfo]$Destination = "$($Env:Windir)\Temp"
}
{([String]::IsNullOrEmpty($FileName) -eq $True) -or ([String]::IsNullOrWhiteSpace($FileName) -eq $True)}
{
[String]$FileName = [System.IO.Path]::GetFileName($URL.OriginalString)
}
}
[System.IO.FileInfo]$DestinationPath = "$($Destination.FullName)\$($FileName)"
$DateTimeLogFormat = 'dddd, MMMM dd, yyyy @ hh:mm:ss tt' ###Monday, January 01, 2019 @ 10:15:34 AM###
[ScriptBlock]$GetCurrentDateTimeLogFormat = {(Get-Date).ToString($DateTimeLogFormat)}
$DateTimeMessageFormat = 'MM/dd/yyyy HH:mm:ss.FFF' ###03/23/2022 11:12:48.347###
[ScriptBlock]$GetCurrentDateTimeMessageFormat = {(Get-Date).ToString($DateTimeMessageFormat)}
$DateFileFormat = 'yyyyMMdd' ###20190403###
[ScriptBlock]$GetCurrentDateFileFormat = {(Get-Date).ToString($DateFileFormat)}
$DateTimeFileFormat = 'yyyyMMdd_HHmmss' ###20190403_115354###
[ScriptBlock]$GetCurrentDateTimeFileFormat = {(Get-Date).ToString($DateTimeFileFormat)}
$TextInfo = (Get-Culture).TextInfo
$LoggingDetails = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$LoggingDetails.Add('LogMessage', $Null)
$LoggingDetails.Add('WarningMessage', $Null)
$LoggingDetails.Add('ErrorMessage', $Null)
$CommonParameterList = New-Object -TypeName 'System.Collections.Generic.List[String]'
$CommonParameterList.AddRange([System.Management.Automation.PSCmdlet]::CommonParameters)
$CommonParameterList.AddRange([System.Management.Automation.PSCmdlet]::OptionalCommonParameters)
[ScriptBlock]$ErrorHandlingDefinition = {
$ErrorMessageList = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ErrorMessageList.Add('Message', $_.Exception.Message)
$ErrorMessageList.Add('Category', $_.Exception.ErrorRecord.FullyQualifiedErrorID)
$ErrorMessageList.Add('Script', $_.InvocationInfo.ScriptName)
$ErrorMessageList.Add('LineNumber', $_.InvocationInfo.ScriptLineNumber)
$ErrorMessageList.Add('LinePosition', $_.InvocationInfo.OffsetInLine)
$ErrorMessageList.Add('Code', $_.InvocationInfo.Line.Trim())
ForEach ($ErrorMessage In $ErrorMessageList.GetEnumerator())
{
$LoggingDetails.ErrorMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - ERROR: $($ErrorMessage.Key): $($ErrorMessage.Value)"
Write-Warning -Message ($LoggingDetails.ErrorMessage)
}
Switch (($ContinueOnError.IsPresent -eq $False) -or ($ContinueOnError -eq $False))
{
{($_ -eq $True)}
{
Throw
}
}
}
#Determine the date and time we executed the function
$FunctionStartTime = (Get-Date)
[String]$CmdletName = $MyInvocation.MyCommand.Name
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($CmdletName)`' is beginning. Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
#Define Default Action Preferences
$ErrorActionPreference = 'Stop'
[String[]]$AvailableScriptParameters = (Get-Command -Name ($CmdletName)).Parameters.GetEnumerator() | Where-Object {($_.Value.Name -inotin $CommonParameterList)} | ForEach-Object {"-$($_.Value.Name):$($_.Value.ParameterType.Name)"}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Available Function Parameter(s) = $($AvailableScriptParameters -Join ', ')"
Write-Verbose -Message ($LoggingDetails.LogMessage)
[String[]]$SuppliedScriptParameters = $PSBoundParameters.GetEnumerator() | ForEach-Object {"-$($_.Key):$($_.Value.GetType().Name)"}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Supplied Function Parameter(s) = $($SuppliedScriptParameters -Join ', ')"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($CmdletName) began on $($FunctionStartTime.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$OutputObjectProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$OutputObjectProperties.DownloadRequired = $False
#region Function Convert-FileSize
Function Convert-FileSize
{
<#
.SYSNOPSIS
Converts a size in bytes to its upper most value.
.PARAMETER Size
The size in bytes to convert
.EXAMPLE
$ConvertFileSizeParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ConvertFileSizeParameters.Size = 4294964
$ConvertFileSizeParameters.DecimalPlaces = 2
$ConvertFileSizeResult = Convert-FileSize @ConvertFileSizeParameters
Write-Output -InputObject ($ConvertFileSizeResult)
.EXAMPLE
$ConvertFileSizeResult = Convert-FileSize -Size 4294964
Write-Output -InputObject ($ConvertFileSizeResult)
.NOTES
Size : 429496456565656
DecimalPlaces : 0
Divisor : 1099511627776
SizeUnit : TB
SizeUnitAlias : Terabytes
CalculatedSize : 391
CalculatedSizeStr : 391 TB
#>
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[Alias("Length")]
$Size,
[Parameter(Mandatory=$False)]
[ValidateNotNullOrEmpty()]
[Alias("DP")]
[Int]$DecimalPlaces
)
Try
{
Switch ($True)
{
{([String]::IsNullOrEmpty($DecimalPlaces) -eq $True) -or ([String]::IsNullOrWhiteSpace($DecimalPlaces) -eq $True)}
{
[Int]$DecimalPlaces = 2
}
}
$OutputObjectProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$OutputObjectProperties.Size = $Size
$OutputObjectProperties.DecimalPlaces = $DecimalPlaces
Switch ($Size)
{
{($_ -lt 1MB)}
{
$OutputObjectProperties.Divisor = 1KB
$OutputObjectProperties.SizeUnit = 'KB'
$OutputObjectProperties.SizeUnitAlias = 'Kilobytes'
Break
}
{($_ -lt 1GB)}
{
$OutputObjectProperties.Divisor = 1MB
$OutputObjectProperties.SizeUnit = 'MB'
$OutputObjectProperties.SizeUnitAlias = 'Megabytes'
Break
}
{($_ -lt 1TB)}
{
$OutputObjectProperties.Divisor = 1GB
$OutputObjectProperties.SizeUnit = 'GB'
$OutputObjectProperties.SizeUnitAlias = 'Gigabytes'
Break
}
{($_ -ge 1TB)}
{
$OutputObjectProperties.Divisor = 1TB
$OutputObjectProperties.SizeUnit = 'TB'
$OutputObjectProperties.SizeUnitAlias = 'Terabytes'
Break
}
}
$OutputObjectProperties.CalculatedSize = [System.Math]::Round(($Size / $OutputObjectProperties.Divisor), $OutputObjectProperties.DecimalPlaces)
$OutputObjectProperties.CalculatedSizeStr = "$($OutputObjectProperties.CalculatedSize) $($OutputObjectProperties.SizeUnit)"
}
Catch
{
Write-Error -Exception $_
}
Finally
{
$OutputObject = New-Object -TypeName 'PSObject' -Property ($OutputObjectProperties)
Write-Output -InputObject ($OutputObject)
}
}
#endregion
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
}
}
Process
{
Try
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to create a web request for `"$($URL.OriginalString)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$WebRequest = [System.Net.WebRequest]::Create($URL.OriginalString)
$WebRequestResponse = $WebRequest.GetResponse()
$WebRequestResponseHeaders = $WebRequestResponse.Headers
$WebRequestHeaderProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
ForEach ($WebRequestResponseHeader In $WebRequestResponseHeaders.AllKeys)
{
$WebRequestHeaderProperties."$($WebRequestResponseHeader)" = ($WebRequestResponseHeaders.GetValues($WebRequestResponseHeader))[0]
}
$WebRequestHeaders = New-Object -TypeName 'PSObject' -Property ($WebRequestHeaderProperties)
$WebRequestHeaders.'Last-Modified' = (Get-Date -Date $WebRequestHeaders.'Last-Modified').ToUniversalTime()
$ContentLengthInMB = [System.Math]::Round(($WebRequestHeaders.'Content-Length' / 1MB), 2)
[ScriptBlock]$ExecuteDownload = {
Try
{
$DownloadExecutionStopwatch = New-Object -TypeName 'System.Diagnostics.Stopwatch'
$WebClient = New-Object -TypeName 'System.Net.WebClient'
$WebClient.UseDefaultCredentials = $True
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to download URL `"$($URL.OriginalString)`" to `"$($DestinationPath.FullName)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Download Size: $($ContentLengthInMB) MB"
Write-Verbose -Message ($LoggingDetails.LogMessage)
If ([System.IO.Directory]::Exists($DestinationPath.Directory.FullName) -eq $False) {$Null = [System.IO.Directory]::CreateDirectory($DestinationPath.Directory.FullName)}
$Downloader = $WebClient.DownloadFileTaskAsync($URL.OriginalString, $DestinationPath.FullName)
$Null = Register-ObjectEvent -InputObject ($WebClient) -EventName 'DownloadProgressChanged' -SourceIdentifier 'WebClient.DownloadProgressChanged'
$Null = Start-Sleep -Seconds 3
$Null = $DownloadExecutionStopwatch.Start()
Switch ($Downloader.IsFaulted)
{
{($_ -eq $True)}
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - A download error has occured. Attempting to generate the error record. Please Wait..."
Write-Warning -Message ($LoggingDetails.WarningMessage)
Write-Error -Message ($Downloader.GetAwaiter().GetResult())
}
}
While ($Downloader.IsCompleted -eq $False)
{
Switch ($Downloader.IsFaulted)
{
{($_ -eq $True)}
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - A download error has occured. Attempting to generate the error record. Please Wait..."
Write-Warning -Message ($LoggingDetails.WarningMessage)
Write-Error -Message ($Downloader.GetAwaiter().GetResult())
Break
}
}
$EventData = Get-Event -SourceIdentifier 'WebClient.DownloadProgressChanged' | Select-Object -ExpandProperty 'SourceEventArgs' -Last 1
$EventDetails = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$EventDetails.Received = Convert-FileSize -Size ($EventData.BytesReceived) -DecimalPlaces 2
$EventDetails.TotalToReceive = Convert-FileSize -Size ($EventData.TotalBytesToReceive) -DecimalPlaces 2
$EventDetails.ProgressPercentage = $EventData.ProgressPercentage
Switch ($DownloadExecutionStopwatch.Elapsed.Seconds -gt 0)
{
{($_ -eq $True)}
{
[Single]$TransferRate = [System.Math]::Round(($EventDetails.TotalToReceive.Size / $DownloadExecutionStopwatch.Elapsed.Seconds / 1MB), 2)
}
Default
{
[Single]$TransferRate = 0.00
}
}
$WriteProgressParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$WriteProgressParameters.Activity = "Downloading `"$($DestinationPath.Name)`""
$WriteProgressParameters.Status = "Completion Percentage: $($EventDetails.ProgressPercentage)%"
$WriteProgressParameters.PercentComplete = $EventDetails.ProgressPercentage
$WriteProgressParameters.CurrentOperation = "Downloaded $($EventDetails.Received.CalculatedSizeStr) of $($EventDetails.TotalToReceive.CalculatedSizeStr) @ $($TransferRate) Mbps"
Write-Progress @WriteProgressParameters
}
}
Catch
{
Write-Error -Exception $_
$Null = Unregister-Event -SourceIdentifier 'WebClient.DownloadProgressChanged'
$Null = $DownloadExecutionStopwatch.Stop()
$Null = $DownloadExecutionStopwatch.Reset()
Break
}
Finally
{
$WriteProgressParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$WriteProgressParameters.Activity = "Downloading `"$($DestinationPath.Name)`""
$WriteProgressParameters.Completed = $True
Write-Progress @WriteProgressParameters
$Null = Unregister-Event -SourceIdentifier 'WebClient.DownloadProgressChanged'
Switch (($Downloader.IsCompleted -eq $False) -or ($Downloader.IsFaulted -eq $True))
{
{($_ -eq $True)}
{
$Null = $Downloader.CancelAsync()
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Download failed. Attempting to remove incomplete file `"$($DestinationPath.FullName)`". Please Wait..."
Write-Warning -Message ($LoggingDetails.WarningMessage)
$Null = [System.IO.File]::Delete($DestinationPath.FullName)
}
}
$Null = $WebClient.Dispose()
$Null = $DownloadExecutionStopwatch.Stop()
}
$DownloadExecutionTimespan = $DownloadExecutionStopwatch.Elapsed
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Download completed in $($DownloadExecutionTimespan.Hours.ToString()) hour(s), $($DownloadExecutionTimespan.Minutes.ToString()) minute(s), $($DownloadExecutionTimespan.Seconds.ToString()) second(s), and $($DownloadExecutionTimespan.Milliseconds.ToString()) millisecond(s)."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$Null = $DownloadExecutionStopwatch.Reset()
[Int]$SecondsToWait = 3
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Pausing script execution for $($SecondsToWait) second(s). Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$Null = Start-Sleep -Seconds ($SecondsToWait)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to update the last modified date of `"$($DestinationPath.FullName)`" to match the last modified date of `"$($URL.OriginalString)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Last Modified Date UTC (Local File): $($DestinationPath.LastWriteTimeUTC.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Last Modified Date UTC (URL Header): $($WebRequestHeaders.'Last-Modified'.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$DestinationPathDetails = Get-Item -Path $DestinationPath.FullName -Force
$Null = $DestinationPathDetails.LastWriteTimeUTC = $WebRequestHeaders.'Last-Modified'
}
Switch ([System.IO.File]::Exists($DestinationPath.FullName))
{
{($_ -eq $True)}
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Destination path `"$($DestinationPath.FullName)`" already exists."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to check the last modified date of `"$($DestinationPath.FullName)`" to see if a download is necessary."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Last Modified Date UTC (Local File): $($DestinationPath.LastWriteTimeUTC.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Last Modified Date UTC (URL Header): $($WebRequestHeaders.'Last-Modified'.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
Switch (($DestinationPath.LastWriteTimeUTC -ine $WebRequestHeaders.'Last-Modified'))
{
{($_ -eq $True)}
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - A redownload of `"$($URL.OriginalString)`" is necessary."
Write-Warning -Message ($LoggingDetails.WarningMessage)
$OutputObjectProperties.DownloadRequired = $True
$ExecuteDownload.InvokeReturnAsIs()
}
Default
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - A redownload of `"$($URL.OriginalString)`" is not necessary."
Write-Verbose -Message ($LoggingDetails.LogMessage)
}
}
}
Default
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Destination path `"$($DestinationPath.FullName)`" does not exist."
Write-Warning -Message ($LoggingDetails.WarningMessage)
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - A download of `"$($URL.OriginalString)`" is necessary."
Write-Warning -Message ($LoggingDetails.WarningMessage)
$OutputObjectProperties.DownloadRequired = $True
$ExecuteDownload.InvokeReturnAsIs()
}
}
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
Try {$Null = $WebRequestResponse.Dispose()} Catch {}
}
}
End
{
Try
{
#Determine the date and time the function completed execution
$FunctionEndTime = (Get-Date)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($CmdletName) ended on $($FunctionEndTime.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
#Log the total script execution time
$FunctionExecutionTimespan = New-TimeSpan -Start ($FunctionStartTime) -End ($FunctionEndTime)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function execution took $($FunctionExecutionTimespan.Hours.ToString()) hour(s), $($FunctionExecutionTimespan.Minutes.ToString()) minute(s), $($FunctionExecutionTimespan.Seconds.ToString()) second(s), and $($FunctionExecutionTimespan.Milliseconds.ToString()) millisecond(s)."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($CmdletName)`' is completed."
Write-Verbose -Message ($LoggingDetails.LogMessage)
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
$DestinationPathDetails = Get-Item -Path $DestinationPath.FullName -Force
$OutputObjectProperties.DownloadPath = $DestinationPathDetails
$OutputObjectProperties.URL = $URL
$OutputObjectProperties.URLHeaders = $WebRequestHeaders
$OutputObject = New-Object -TypeName 'PSObject' -Property ($OutputObjectProperties)
Write-Output -InputObject ($OutputObject)
}
}
}
#endregion
+355
View File
@@ -0,0 +1,355 @@
## Microsoft Function Naming Convention: http://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx
#region Function Invoke-RegistryHiveAction
Function Invoke-RegistryHiveAction
{
<#
.SYNOPSIS
A brief overview of what your function does
.DESCRIPTION
Slightly more detailed description of what your function does
.PARAMETER HivePath
A valid file path to a valid registry hive.
.PARAMETER KeyPath
One or more registry key paths that are relative to the specified registry hive.
.PARAMETER ValueNameExpression
One or more regular expressions that will determine which registry value names will be extracted from the specified registry hive.
.EXAMPLE
Invoke-RegistryHiveAction -HivePath "$($Env:Userprofile)\Downloads\RegistryHives\SOFTWARE" -KeyPath @('Root\Microsoft\Windows NT\CurrentVersion') -ValueNameExpression @('.*') -Verbose
.EXAMPLE
$InvokeRegistryHiveActionParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$InvokeRegistryHiveActionParameters.HivePath = "$($Env:Userprofile)\Downloads\RegistryHives\SOFTWARE"
$InvokeRegistryHiveActionParameters.KeyPath = New-Object -TypeName 'System.Collections.Generic.List[String]'
$InvokeRegistryHiveActionParameters.KeyPath.Add('Root\Microsoft\Windows NT\CurrentVersion')
$InvokeRegistryHiveActionParameters.ValueNameExpression = New-Object -TypeName 'System.Collections.Generic.List[Regex]'
$InvokeRegistryHiveActionParameters.ValueNameExpression.Add('.*')
$InvokeRegistryHiveActionParameters.ContinueOnError = $False
$InvokeRegistryHiveActionParameters.Verbose = $True
$InvokeRegistryHiveActionResult = Invoke-RegistryHiveAction @InvokeRegistryHiveActionParameters
Write-Output -InputObject ($InvokeRegistryHiveActionResult)
.NOTES
Please ensure that the specified registry hive is not in use!
.LINK
https://github.com/EricZimmerman/Registry
#>
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[ValidateScript({(Test-Path -Path $_)})]
[System.IO.FileInfo]$HivePath,
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[ValidatePattern('^Root\\.+')]
[String[]]$KeyPath,
[Parameter(Mandatory=$False)]
[Regex[]]$ValueNameExpression,
[Parameter(Mandatory=$False)]
[Switch]$ContinueOnError
)
Begin
{
Try
{
$DateTimeLogFormat = 'dddd, MMMM dd, yyyy @ hh:mm:ss.FFF tt' ###Monday, January 01, 2019 @ 10:15:34.000 AM###
[ScriptBlock]$GetCurrentDateTimeLogFormat = {(Get-Date).ToString($DateTimeLogFormat)}
$DateTimeMessageFormat = 'MM/dd/yyyy HH:mm:ss.FFF' ###03/23/2022 11:12:48.347###
[ScriptBlock]$GetCurrentDateTimeMessageFormat = {(Get-Date).ToString($DateTimeMessageFormat)}
$DateFileFormat = 'yyyyMMdd' ###20190403###
[ScriptBlock]$GetCurrentDateFileFormat = {(Get-Date).ToString($DateFileFormat)}
$DateTimeFileFormat = 'yyyyMMdd_HHmmss' ###20190403_115354###
[ScriptBlock]$GetCurrentDateTimeFileFormat = {(Get-Date).ToString($DateTimeFileFormat)}
$TextInfo = (Get-Culture).TextInfo
$LoggingDetails = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$LoggingDetails.Add('LogMessage', $Null)
$LoggingDetails.Add('WarningMessage', $Null)
$LoggingDetails.Add('ErrorMessage', $Null)
$CommonParameterList = New-Object -TypeName 'System.Collections.Generic.List[String]'
$CommonParameterList.AddRange([System.Management.Automation.PSCmdlet]::CommonParameters)
$CommonParameterList.AddRange([System.Management.Automation.PSCmdlet]::OptionalCommonParameters)
[System.IO.DirectoryInfo]$System32Directory = [System.Environment]::SystemDirectory
$RegexOptionList = New-Object -TypeName 'System.Collections.Generic.List[System.Text.RegularExpressions.RegexOptions]'
$RegexOptionList.Add([System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
$ValueNameExpressionList = New-Object -TypeName 'System.Collections.Generic.List[System.Text.RegularExpressions.Regex]'
[ScriptBlock]$ErrorHandlingDefinition = {
$ErrorMessageList = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ErrorMessageList.Add('Message', $_.Exception.Message)
$ErrorMessageList.Add('Category', $_.Exception.ErrorRecord.FullyQualifiedErrorID)
$ErrorMessageList.Add('Script', $_.InvocationInfo.ScriptName)
$ErrorMessageList.Add('LineNumber', $_.InvocationInfo.ScriptLineNumber)
$ErrorMessageList.Add('LinePosition', $_.InvocationInfo.OffsetInLine)
$ErrorMessageList.Add('Code', $_.InvocationInfo.Line.Trim())
ForEach ($ErrorMessage In $ErrorMessageList.GetEnumerator())
{
$LoggingDetails.ErrorMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - ERROR: $($ErrorMessage.Key): $($ErrorMessage.Value)"
Write-Warning -Message ($LoggingDetails.ErrorMessage)
}
Switch (($ContinueOnError.IsPresent -eq $False) -or ($ContinueOnError -eq $False))
{
{($_ -eq $True)}
{
Throw
}
}
}
#Determine the date and time we executed the function
$FunctionStartTime = (Get-Date)
[String]$FunctionName = $MyInvocation.MyCommand
[System.IO.FileInfo]$InvokingScriptPath = $MyInvocation.PSCommandPath
[System.IO.DirectoryInfo]$InvokingScriptDirectory = $InvokingScriptPath.Directory.FullName
[System.IO.FileInfo]$FunctionPath = "$($InvokingScriptDirectory.FullName)\Functions\$($FunctionName).ps1"
[System.IO.DirectoryInfo]$FunctionDirectory = "$($FunctionPath.Directory.FullName)"
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($FunctionName)`' is beginning. Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
#Define Default Action Preferences
$ErrorActionPreference = 'Stop'
[String[]]$AvailableScriptParameters = (Get-Command -Name ($FunctionName)).Parameters.GetEnumerator() | Where-Object {($_.Value.Name -inotin $CommonParameterList)} | ForEach-Object {"-$($_.Value.Name):$($_.Value.ParameterType.Name)"}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Available Function Parameter(s) = $($AvailableScriptParameters -Join ', ')"
Write-Verbose -Message ($LoggingDetails.LogMessage)
[String[]]$SuppliedScriptParameters = $PSBoundParameters.GetEnumerator() | ForEach-Object {"-$($_.Key):$($_.Value.GetType().Name)"}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Supplied Function Parameter(s) = $($SuppliedScriptParameters -Join ', ')"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($FunctionName) began on $($FunctionStartTime.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
#region Load any required libraries
[System.IO.DirectoryInfo]$LibariesDirectory = "$($FunctionDirectory.FullName)\Libraries"
Switch ([System.IO.Directory]::Exists($LibariesDirectory.FullName))
{
{($_ -eq $True)}
{
$LibraryPatternList = New-Object -TypeName 'System.Collections.Generic.List[String]'
$LibraryPatternList.Add('NFluent.dll')
$LibraryPatternList.Add('NLog.dll')
$LibraryPatternList.Add('Registry.dll')
Switch ($LibraryPatternList.Count -gt 0)
{
{($_ -eq $True)}
{
$LibraryList = Get-ChildItem -Path ($LibariesDirectory.FullName) -Include ($LibraryPatternList.ToArray()) -Recurse -Force | Where-Object {($_ -is [System.IO.FileInfo])}
$LibraryListCount = ($LibraryList | Measure-Object).Count
Switch ($LibraryListCount -gt 0)
{
{($_ -eq $True)}
{
For ($LibraryListIndex = 0; $LibraryListIndex -lt $LibraryListCount; $LibraryListIndex++)
{
$Library = $LibraryList[$LibraryListIndex]
[Byte[]]$LibraryBytes = [System.IO.File]::ReadAllBytes($Library.FullName)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to load assembly `"$($Library.FullName)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$Null = [System.Reflection.Assembly]::Load($LibraryBytes)
}
}
}
}
}
}
}
#endregion
#Create an object that will contain the functions output.
$OutputObjectList = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'
#Set default parameter values
Switch ($True)
{
{($Null -ieq $ValueNameExpression) -or ($ValueNameExpression.Count -eq 0)}
{
$ValueNameExpression += '.*'
}
{($Null -ine $ValueNameExpression) -or ($ValueNameExpression.Count -gt 0)}
{
$ValueNameExpression | ForEach-Object {$ValueNameExpressionList.Add((New-Object -TypeName 'System.Text.RegularExpressions.Regex' -ArgumentList @($_, $RegexOptionList)))}
}
}
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
}
}
Process
{
Try
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to load registry hive `"$($HivePath.FullName)`" on demand. Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$RegistryHive = New-Object -TypeName 'Registry.RegistryHiveOnDemand' -ArgumentList ($HivePath.FullName)
ForEach ($Key In $KeyPath)
{
Try
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to retrieve the details of registry key path `"$($Key)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$RegistryKeyProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$RegistryKeyProperties.Path = $Key
$RegistryKeyProperties.ValueList = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'
$RegistryKey = $RegistryHive.GetKey($Key)
ForEach ($Item In $RegistryKey.Values)
{
ForEach ($Expression In $ValueNameExpressionList)
{
$ExpressionEvaluation = $Expression.Match($Item.ValueName)
Switch ($ExpressionEvaluation.Success)
{
{($_ -eq $True)}
{
$ValueProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ValueProperties.Name = $Item.ValueName
$ValueProperties.Alias = $ValueProperties.Name -ireplace '(\s+)', ''
$ValueProperties.Type = $Item.ValueType
$ValueProperties.Value = $Null
$ValueProperties.ValueAsDecimal = $Null
$ValueProperties.ValueAsHex = $Null
#$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to retrieve the registry key value of `"$($ValueProperties.Name)`" because the value name matches the regular expression of `"$($Expression.ToString())`". Please Wait..."
#Write-Verbose -Message ($LoggingDetails.LogMessage)
Switch ($Null -ine $Item.ValueData)
{
{($_ -eq $True)}
{
$ValueProperties.Value = $Item.ValueData
Switch ($ValueProperties.Type)
{
{($_ -iin @('RegDword', 'RegQword'))}
{
$ValueProperties.ValueAsDecimal = Try {[System.Convert]::ToString($ValueProperties.Value, 10)} Catch {}
$ValueProperties.ValueAsHex = Try {'0x' + [System.Convert]::ToString($ValueProperties.Value, 16).PadLeft(8, '0').ToUpper()} Catch {}
}
{($_ -iin @('RegBinary'))}
{
#$ValueProperties.ValueAsDecimal = Try {} Catch {}
#$ValueProperties.ValueAsHex = Try {} Catch {}
}
}
}
}
$ValueObject = New-Object -TypeName 'PSObject' -Property ($ValueProperties)
$RegistryKeyProperties.ValueList.Add($ValueObject)
}
}
}
}
$RegistryKeyObject = New-Object -TypeName 'PSObject' -Property ($RegistryKeyProperties)
$OutputObjectList.Add($RegistryKeyObject)
}
Catch
{
$ErrorMessageList = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ErrorMessageList.Add('Message', $_.Exception.Message)
$ErrorMessageList.Add('Category', $_.Exception.ErrorRecord.FullyQualifiedErrorID)
$ErrorMessageList.Add('LineNumber', $_.InvocationInfo.ScriptLineNumber)
$ErrorMessageList.Add('LinePosition', $_.InvocationInfo.OffsetInLine)
$ErrorMessageList.Add('Code', $_.InvocationInfo.Line.Trim())
ForEach ($ErrorMessage In $ErrorMessageList.GetEnumerator())
{
$LoggingDetails.ErrorMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - ERROR: $($ErrorMessage.Key): $($ErrorMessage.Value)"
Write-Warning -Message ($LoggingDetails.ErrorMessage)
}
}
Finally
{
}
}
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
}
}
End
{
Try
{
#Determine the date and time the function completed execution
$FunctionEndTime = (Get-Date)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($FunctionName) ended on $($FunctionEndTime.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
#Log the total script execution time
$FunctionExecutionTimespan = New-TimeSpan -Start ($FunctionStartTime) -End ($FunctionEndTime)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function execution took $($FunctionExecutionTimespan.Hours.ToString()) hour(s), $($FunctionExecutionTimespan.Minutes.ToString()) minute(s), $($FunctionExecutionTimespan.Seconds.ToString()) second(s), and $($FunctionExecutionTimespan.Milliseconds.ToString()) millisecond(s)"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($FunctionName)`' is completed."
Write-Verbose -Message ($LoggingDetails.LogMessage)
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
#Write the object to the powershell pipeline
$OutputObjectList = $OutputObjectList.ToArray()
Write-Output -InputObject ($OutputObjectList)
}
}
}
#endregion
+436
View File
@@ -0,0 +1,436 @@
## Microsoft Function Naming Convention: http://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx
#region Function Invoke-SQLDBQuery
Function Invoke-SQLDBQuery
{
<#
.SYNOPSIS
This function is able to execute one or more queries against an the specified Microsoft SQL database using either Windows or SQL authentication.
.DESCRIPTION
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 Instance
.PARAMETER Port
.PARAMETER UserID
.PARAMETER Password
.PARAMETER Database
.PARAMETER DBQueryList
.EXAMPLE
$DBQueryResults = Invoke-SQLDBQuery -Server 'MyDBServer.mydomain.com' -UserID 'SQLAuthUser' -Password 'SQLAuthUserPassword' -Database 'YourDatabaseName' -DBQueryList @('Select * From YourTableName') -Verbose
Write-Output -InputObject ($DBQueryResults)
.EXAMPLE
$DBQueryList = [System.Collections.Generic.List[String]]@()
$DBQueryList.Add(@"
Select Distinct
dbo.v_Add_Remove_Programs.DisplayName0 As 'DisplayName'
From
dbo.v_Add_Remove_Programs
Order By
dbo.v_Add_Remove_Programs.DisplayName0
"@)
$DBQueryResults = Invoke-SQLDBQuery -Server 'MyDBServer.mydomain.com' -Database 'YourDatabaseName' -DBQueryList ($DBQueryList) -Verbose
.EXAMPLE
$DBQueryResults = Invoke-SQLDBQuery -Server 'MyDBServer.mydomain.com' -Instance 'MyDBInstance' -Database 'YourDatabaseName' -DBQueryList @('Select * From YourTableName')
Write-Output -InputObject ($DBQueryResults)
.EXAMPLE
$DBQueryResults = Invoke-SQLDBQuery -Server 'MyDBServer.mydomain.com' -Port '4530' -Database 'YourDatabaseName' -DBQueryList @('Select * From YourTableName1', 'Select * From YourTableName2')
Write-Output -InputObject ($DBQueryResults)
.LINK
https://www.SQLshack.com/connecting-powershell-to-SQL-server/
.LINK
https://stackoverflow.com/questions/64681003/fetch-a-whole-row-from-SQL-server-with-powershell
#>
[CmdletBinding(ConfirmImpact = 'Low', HelpURI = '', DefaultParameterSetName = '_AllParameterSets', SupportsShouldProcess = $True, PositionalBinding = $True)]
Param
(
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[String]$Server,
[Parameter(Mandatory=$False)]
[ValidateNotNullOrEmpty()]
[String]$Instance,
[Parameter(Mandatory=$False)]
[ValidateNotNullOrEmpty()]
[String]$Port,
[Parameter(Mandatory=$False)]
[ValidateNotNullOrEmpty()]
[String]$UserID,
[Parameter(Mandatory=$False)]
[ValidateNotNullOrEmpty()]
[String]$Password,
[Parameter(Mandatory=$False)]
[ValidateNotNullOrEmpty()]
[String]$Database,
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[String[]]$DBQueryList,
[Parameter(Mandatory=$False, ParameterSetName = 'Export')]
[Switch]$ExportJSON,
[Parameter(Mandatory=$False, ParameterSetName = 'Export')]
[System.IO.DirectoryInfo]$ExportDirectory,
[Parameter(Mandatory=$False)]
[Switch]$ContinueOnError
)
Begin
{
[ScriptBlock]$ErrorHandlingDefinition = {
If ([String]::IsNullOrEmpty($_.Exception.Message)) {$ExceptionMessage = "$($_.Exception.Errors.Message -Join "`r`n`r`n")"} Else {$ExceptionMessage = "$($_.Exception.Message)"}
[String]$ErrorMessage = "[Error Message: $($ExceptionMessage)]`r`n`r`n[ScriptName: $($_.InvocationInfo.ScriptName)]`r`n[Line Number: $($_.InvocationInfo.ScriptLineNumber)]`r`n[Line Position: $($_.InvocationInfo.OffsetInLine)]`r`n[Code: $($_.InvocationInfo.Line.Trim())]"
If ($ContinueOnError.IsPresent -eq $True)
{
Write-Warning -Message ($ErrorMessage)
}
ElseIf ($ContinueOnError.IsPresent -eq $False)
{
Throw ($ErrorMessage)
}
}
Try
{
$DateTimeMessageFormat = 'MM/dd/yyyy HH:mm:ss.FFF' ###03/23/2022 11:12:48.347###
[ScriptBlock]$GetCurrentDateTimeMessageFormat = {(Get-Date).ToString($DateTimeMessageFormat)}
$DateTimeLogFormat = 'dddd, MMMM dd, yyyy @ hh:mm:ss.FFF tt' ###Monday, January 01, 2019 @ 10:15:34.000 AM###
[ScriptBlock]$GetCurrentDateTimeLogFormat = {(Get-Date).ToString($DateTimeLogFormat)}
$DateFileFormat = 'yyyyMMdd' ###20190403###
[ScriptBlock]$GetCurrentDateFileFormat = {(Get-Date).ToString($DateFileFormat)}
$DateTimeFileFormat = 'yyyyMMdd_HHmmss' ###20190403_115354###
[ScriptBlock]$GetCurrentDateTimeFileFormat = {(Get-Date).ToString($DateTimeFileFormat)}
$TextInfo = (Get-Culture).TextInfo
#Determine the date and time we executed the function
$FunctionStartTime = (Get-Date)
[String]$CmdletName = $MyInvocation.MyCommand.Name
$LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($CmdletName)`' is beginning. Please Wait..."
Write-Verbose -Message $LogMessage
#Define Default Action Preferences
$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))"
Write-Verbose -Message $LogMessage
#Create an array list that will contain the functions output
$OutputObjectProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
#Define Variable(s)
$LoggingDetails = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$LoggingDetails.Add('LogMessage', $Null)
$LoggingDetails.Add('WarningMessage', $Null)
$LoggingDetails.Add('ErrorMessage', $Null)
#Create a database connection string builder
$DBConnectionStringBuilder = [System.Data.SQLClient.SQLConnectionStringBuilder]::New()
#Create a database data source builder
$DataSourceBuilder = [System.Text.StringBuilder]::New()
#Dynamically build the connection string based on parameter values
Switch ($True)
{
{([String]::IsNullOrEmpty($Server) -eq $False) -and ([String]::IsNullOrWhiteSpace($Server) -eq $False)}
{
$Null = $DataSourceBuilder.Append($Server)
}
{([String]::IsNullOrEmpty($Instance) -eq $False) -and ([String]::IsNullOrWhiteSpace($Instance) -eq $False)}
{
$Null = $DataSourceBuilder.Append("\$($Instance)")
}
{([String]::IsNullOrEmpty($Port) -eq $False) -and ([String]::IsNullOrWhiteSpace($Port) -eq $False)}
{
$Null = $DataSourceBuilder.Append(",$($Port)")
}
{([String]::IsNullOrEmpty($Database) -eq $False) -and ([String]::IsNullOrWhiteSpace($Database) -eq $False)}
{
$DBConnectionStringBuilder.PSBase.InitialCatalog = $Database
}
{([String]::IsNullOrEmpty($ExportDirectory) -eq $True) -and ([String]::IsNullOrWhiteSpace($ExportDirectory) -eq $True)}
{
[System.IO.DirectoryInfo]$ExportDirectory = "$($Env:Public)\Documents\Reports\$($CmdletName)"
}
}
$DBConnection = [System.Data.SQLClient.SQLConnection]::New()
Switch (([String]::IsNullOrEmpty($UserID) -eq $True) -or ([String]::IsNullOrWhiteSpace($UserID) -eq $True) -or ([String]::IsNullOrEmpty($Password) -eq $True) -or ([String]::IsNullOrWhiteSpace($Password) -eq $True))
{
{($_ -eq $True)}
{
$DBConnectionStringBuilder.PSBase.IntegratedSecurity = $True
}
Default
{
$DBConnectionStringBuilder.PSBase.IntegratedSecurity = $False
$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)
}
}
$DBConnectionStringBuilder.PSBase.DataSource = $DataSourceBuilder.ToString()
$DBConnectionString = $DBConnectionStringBuilder.ConnectionString
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - " + "Database Connection String = $($DBConnectionString)"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$DBConnection.ConnectionString = ($DBConnectionString)
$LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to open the database connection. Please Wait..."
Write-Verbose -Message $LogMessage
$DBConnection.Open()
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
}
Process
{
For ($DBQueryListIndex = 0; $DBQueryListIndex -lt $DBQueryList.Count; $DBQueryListIndex++)
{
Try
{
[String]$DBQuery = $DBQueryList[$DBQueryListIndex]
[Int]$DBQueryNumber = $DBQueryListIndex + 1
$DBCommand = [System.Data.SQLClient.SQLCommand]::New()
$DBCommand.Connection = ($DBConnection)
$DBCommand.CommandText = ($DBQuery)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - " + "Attempting to execute database query #$($DBQueryNumber). Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$Null = $DBCommand.ExecuteScalar()
$DBQueryResults = [System.Data.DataTable]::New()
$DBDataAdapter = [System.Data.SQLClient.SQLDataAdapter]::New($DBCommand)
$Null = $DBDataAdapter.Fill($DBQueryResults)
$DBQueryRowCount = $DBQueryResults.Rows.Count
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - " + "$($DBQueryRowCount) row(s) were returned from the database query."
Write-Verbose -Message ($LoggingDetails.LogMessage)
Switch ($DBQueryRowCount -gt 0)
{
{($_ -eq $True)}
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - " + "Database Query Column Names = $($DBQueryResults.Columns.ColumnName -Join ', ')"
Write-Verbose -Message ($LoggingDetails.LogMessage)
}
}
[String]$ResultSetNumber = ($DBQueryNumber).ToString('000')
[String]$ResultSetPropertyName = "ResultSet$($ResultSetNumber)"
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - " + "Attempting to add the result(s) from database query #$($DBQueryNumber) to property `"$($ResultSetPropertyName)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$PropertyInclusionList = [System.Collections.Generic.List[Object]]@()
$Null = $PropertyInclusionList.Add('*')
$PropertyExclusionList = [System.Collections.Generic.List[Object]]@()
$Null = $PropertyExclusionList.AddRange(('HasErrors', 'ItemArray', 'RowError', 'RowState', 'Table'))
$DBQueryRows = $DBQueryResults.Rows | Select-Object -Property ($PropertyInclusionList) -ExcludeProperty ($PropertyExclusionList)
$Null = $OutputObjectProperties.Add($ResultSetPropertyName, $DBQueryRows)
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
Try
{
$Null = $DBQueryResults.Dispose()
$Null = $DBDataAdapter.Dispose()
}
Catch
{
}
}
}
}
End
{
Try
{
#Close the database connection
$LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to close the database connection. Please Wait..."
Write-Verbose -Message $LogMessage
$Null = $DBConnection.Close()
#Create the powershell object that will be exported to the powershell pipeline
$OutputObject = New-Object -TypeName 'PSObject' -Property ($OutputObjectProperties)
#If specified, export each result set to a separate JSON file
Switch ($True)
{
{($ExportJSON.IsPresent)}
{
$ExportParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ExportParameters.Add('Compress', $False)
$ExportParameters.Add('Encoding', [System.Text.Encoding]::Default)
$ExportParameters.Add('Depth', 10)
[String[]]$OutputObjectPropertyList = $OutputObject.PSObject.Properties.Name
For ($OutputObjectPropertyListIndex = 0; $OutputObjectPropertyListIndex -lt $OutputObjectPropertyList.Count; $OutputObjectPropertyListIndex++)
{
[String]$OutputObjectPropertyName = $OutputObjectPropertyList[$OutputObjectPropertyListIndex]
[System.IO.FileInfo]$OutputObjectExportPath = "$($ExportDirectory.FullName)\$($OutputObjectPropertyName).json"
Switch ([System.IO.File]::Exists($OutputObjectExportPath.FullName))
{
{($_ -eq $True)}
{
[String]$JSONContents = [System.IO.File]::ReadAllText($OutputObjectExportPath.FullName, $ExportParameters.Encoding)
$JSONObject = ConvertFrom-JSON -InputObject ($JSONContents)
$OutputObjectPropertyValue = $OutputObject.$($OutputObjectPropertyName)
$JSONObject.$($OutputObjectPropertyName) = ($OutputObjectPropertyValue)
[String]$OutputObjectPropertyValueAsJSON = $JSONObject | ConvertTo-JSON -Depth ($ExportParameters.Depth) -Compress:($ExportParameters.Compress)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - " + "Attempting to update the result set `"$($OutputObjectPropertyName)`" within the file of `"$($OutputObjectExportPath.FullName)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$Null = [System.IO.File]::WriteAllText($OutputObjectExportPath.FullName, $OutputObjectPropertyValueAsJSON, $ExportParameters.Encoding)
}
{($_ -eq $False)}
{
$OutputObjectPropertyValue = $OutputObject | Select-Object -Property @($OutputObjectPropertyName)
[String]$OutputObjectPropertyValueAsJSON = $OutputObjectPropertyValue | ConvertTo-JSON -Depth ($ExportParameters.Depth) -Compress:($ExportParameters.Compress)
Switch ([System.IO.Directory]::Exists($OutputObjectExportPath.Directory.FullName))
{
{($_ -eq $False)}
{
$Null = [System.IO.Directory]::CreateDirectory($OutputObjectExportPath.Directory.FullName)
}
}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - " + "Attempting to export the result set `"$($OutputObjectPropertyName)`" to the file of `"$($OutputObjectExportPath.FullName)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$Null = [System.IO.File]::WriteAllText($OutputObjectExportPath.FullName, $OutputObjectPropertyValueAsJSON, $ExportParameters.Encoding)
}
}
}
}
}
#Write the object to the powershell pipeline
Write-Output -InputObject ($OutputObject)
#Determine the date and time the function completed execution
$FunctionEndTime = (Get-Date)
$LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($CmdletName) ended on $($FunctionEndTime.ToString($DateTimeLogFormat))"
Write-Verbose -Message $LogMessage
#Log the total script execution time
$FunctionExecutionTimespan = New-TimeSpan -Start ($FunctionStartTime) -End ($FunctionEndTime)
$LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function execution took $($FunctionExecutionTimespan.Hours.ToString()) hour(s), $($FunctionExecutionTimespan.Minutes.ToString()) minute(s), $($FunctionExecutionTimespan.Seconds.ToString()) second(s), and $($FunctionExecutionTimespan.Milliseconds.ToString()) millisecond(s)"
Write-Verbose -Message $LogMessage
$LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($CmdletName)`' is completed."
Write-Verbose -Message $LogMessage
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
}
}
#endregion
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+366
View File
@@ -0,0 +1,366 @@
#region Start-ProcessWithOutput
Function Start-ProcessWithOutput
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[String]$FilePath,
[Parameter(Mandatory=$False)]
[AllowEmptyCollection()]
[AllowNull()]
[String[]]$ArgumentList,
[Parameter(Mandatory=$False)]
[AllowEmptyCollection()]
[AllowNull()]
[String[]]$AcceptableExitCodeList,
[Parameter(Mandatory=$False)]
[ValidateNotNullOrEmpty()]
[ValidateSet('Normal', 'Hidden', 'Minimized', 'Maximized')]
[String]$WindowStyle,
[Parameter(Mandatory=$False)]
[Switch]$CreateNoWindow,
[Parameter(Mandatory=$False, ParameterSetName = 'ParseOutput')]
[Switch]$ParseOutput,
[Parameter(Mandatory=$False, ParameterSetName = 'ParseOutput')]
[ValidateNotNullOrEmpty()]
[Alias('StandardOutputParsingExpression')]
[Regex]$ParsingExpression,
[Parameter(Mandatory=$False)]
[Switch]$LogOutput
)
Try
{
$DateTimeLogFormat = 'dddd, MMMM dd, yyyy @ hh:mm:ss.FFF tt' ###Monday, January 01, 2019 @ 10:15:34.000 AM###
[ScriptBlock]$GetCurrentDateTimeLogFormat = {(Get-Date).ToString($DateTimeLogFormat)}
$DateTimeMessageFormat = 'MM/dd/yyyy HH:mm:ss.FFF' ###03/23/2022 11:12:48.347###
[ScriptBlock]$GetCurrentDateTimeMessageFormat = {(Get-Date).ToString($DateTimeMessageFormat)}
$DateFileFormat = 'yyyyMMdd' ###20190403###
[ScriptBlock]$GetCurrentDateFileFormat = {(Get-Date).ToString($DateFileFormat)}
$DateTimeFileFormat = 'yyyyMMdd_HHmmss' ###20190403_115354###
[ScriptBlock]$GetCurrentDateTimeFileFormat = {(Get-Date).ToString($DateTimeFileFormat)}
$LoggingDetails = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$LoggingDetails.LogMessage = $Null
$LoggingDetails.WarningMessage = $Null
$LoggingDetails.ErrorMessage = $Null
#Determine the date and time we executed the function
$FunctionStartTime = (Get-Date)
[String]$CmdletName = $MyInvocation.MyCommand.Name
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($CmdletName)`' is beginning. Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
#Define Default Action Preferences
$ErrorActionPreference = 'Stop'
[String[]]$AvailableScriptParameters = (Get-Command -Name ($CmdletName)).Parameters.GetEnumerator() | Where-Object {($_.Value.Name -inotin $CommonParameterList)} | ForEach-Object {"-$($_.Value.Name):$($_.Value.ParameterType.Name)"}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Available Function Parameter(s) = $($AvailableScriptParameters -Join ', ')"
Write-Verbose -Message ($LoggingDetails.LogMessage)
[String[]]$SuppliedScriptParameters = $PSBoundParameters.GetEnumerator() | ForEach-Object {"-$($_.Key):$($_.Value.GetType().Name)"}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Supplied Function Parameter(s) = $($SuppliedScriptParameters -Join ', ')"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($CmdletName) began on $($FunctionStartTime.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
#Set default parameter values (If necessary)
Switch ($True)
{
{([String]::IsNullOrEmpty($WindowStyle) -eq $True) -or ([String]::IsNullOrWhiteSpace($WindowStyle) -eq $True)}
{
[String]$WindowStyle = 'Hidden'
}
{([String]::IsNullOrEmpty($ParsingExpression) -eq $True) -or ([String]::IsNullOrWhiteSpace($ParsingExpression) -eq $True)}
{
[Regex]$ParsingExpression = '(?:\s+)(?<PropertyName>.+)(?:\s+\:\s+)(?<PropertyValue>.+)'
}
}
$OutputObjectProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$OutputObjectProperties.ExitCode = $Null
$OutputObjectProperties.ExitCodeAsHex = $Null
$OutputObjectProperties.ExitCodeAsInteger = $Null
$OutputObjectProperties.ExitCodeAsDecimal = $Null
$OutputObjectProperties.ProcessObject = $Null
$OutputObjectProperties.StandardOutput = $Null
$OutputObjectProperties.StandardOutputObject = $Null
$OutputObjectProperties.StandardError = $Null
$OutputObjectProperties.StandardErrorObject = $Null
$Process = New-Object -TypeName 'System.Diagnostics.Process'
$Process.StartInfo.FileName = $FilePath
$Process.StartInfo.UseShellExecute = $False
$Process.StartInfo.RedirectStandardOutput = $True
$Process.StartInfo.RedirectStandardError = $True
Switch ($CreateNoWindow.IsPresent)
{
{($_ -eq $True)}
{
$Process.StartInfo.CreateNoWindow = ($CreateNoWindow.IsPresent)
}
Default
{
$Process.StartInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::$($WindowStyle)
}
}
Switch (($Null -ieq $AcceptableExitCodeList) -or ($AcceptableExitCodeList.Count -eq 0))
{
{($_ -eq $True)}
{
$AcceptableExitCodeList += '0'
$AcceptableExitCodeList += '3010'
}
}
Switch (($Null -ine $ArgumentList) -and ($ArgumentList.Count -gt 0))
{
{($_ -eq $True)}
{
$Process.StartInfo.Arguments = $ArgumentList -Join ' '
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to execute the following command: `"$($Process.StartInfo.FileName)`" $($Process.StartInfo.Arguments)"
Write-Verbose -Message ($LoggingDetails.LogMessage)
}
Default
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to execute the following command: `"$($Process.StartInfo.FileName)`""
Write-Verbose -Message ($LoggingDetails.LogMessage)
}
}
$Null = $Process.Start()
$OutputObjectProperties.StandardOutput = $Process.StandardOutput.ReadToEnd()
$OutputObjectProperties.StandardError = $Process.StandardError.ReadToEnd()
$Null = $Process.WaitForExit()
$OutputObjectProperties.ExitCode = $Process.ExitCode
$OutputObjectProperties.ExitCodeAsHex = Try {'0x' + [System.Convert]::ToString($OutputObjectProperties.ExitCode, 16).PadLeft(8, '0').ToUpper()} Catch {$Null}
$OutputObjectProperties.ExitCodeAsInteger = Try {$OutputObjectProperties.ExitCodeAsHex -As [Int]} Catch {$Null}
$OutputObjectProperties.ExitCodeAsDecimal = Try {[System.Convert]::ToString($OutputObjectProperties.ExitCodeAsHex, 10)} Catch {$Null}
$ExitCodeMessageList = New-Object -TypeName 'System.Collections.Generic.List[String]'
$Null = $OutputObjectProperties.GetEnumerator() | Where-Object {($_.Key -imatch '(^ExitCode.*$)')} | Sort-Object -Property @('Key') | ForEach-Object {$ExitCodeMessageList.Add("[$($_.Key): $($_.Value)]")}
$StartProcessExecutionTimespan = New-TimeSpan -Start ($Process.StartTime) -End ($Process.ExitTime)
$OutputObjectProperties.ProcessObject = $Process
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - The command execution took $($StartProcessExecutionTimespan.Hours.ToString()) hour(s), $($StartProcessExecutionTimespan.Minutes.ToString()) minute(s), $($StartProcessExecutionTimespan.Seconds.ToString()) second(s), and $($StartProcessExecutionTimespan.Milliseconds.ToString()) millisecond(s)."
Write-Verbose -Message ($LoggingDetails.LogMessage)
Switch (($OutputObjectProperties.ExitCode.ToString() -iin $AcceptableExitCodeList) -or ($OutputObjectProperties.ExitCodeAsHex.ToString() -iin $AcceptableExitCodeList) -or ($OutputObjectProperties.ExitCodeAsInteger.ToString() -iin $AcceptableExitCodeList) -or ($OutputObjectProperties.ExitCodeAsDecimal.ToString() -iin $AcceptableExitCodeList))
{
{($_ -eq $True)}
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - The command execution was successful. $($ExitCodeMessageList -Join ' ')"
Write-Verbose -Message ($LoggingDetails.LogMessage)
}
{($_ -eq $False)}
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - The command execution was unsuccessful. $($ExitCodeMessageList -Join ' ')"
Write-Warning -Message ($LoggingDetails.WarningMessage) -Verbose
$ErrorMessage = "$($LoggingDetails.WarningMessage)"
$Exception = [System.Exception]::New($ErrorMessage)
$ErrorRecord = [System.Management.Automation.ErrorRecord]::New($Exception, [System.Management.Automation.ErrorCategory]::InvalidResult.ToString(), [System.Management.Automation.ErrorCategory]::InvalidResult, $Process)
$PSCmdlet.ThrowTerminatingError($ErrorRecord)
}
}
Switch (($OutputObjectProperties.ExitCode.ToString() -iin $AcceptableExitCodeList) -or ($OutputObjectProperties.ExitCodeAsHex.ToString() -iin $AcceptableExitCodeList) -or ($OutputObjectProperties.ExitCodeAsInteger.ToString() -iin $AcceptableExitCodeList) -or ($OutputObjectProperties.ExitCodeAsDecimal.ToString() -iin $AcceptableExitCodeList))
{
{($_ -eq $True)}
{
[String]$CommandContents = $OutputObjectProperties.StandardOutput
Switch (($ParseOutput.IsPresent -eq $True) -and ([String]::IsNullOrEmpty($StandardOutputParsingExpression) -eq $False) -and ([String]::IsNullOrWhiteSpace($StandardOutputParsingExpression) -eq $False))
{
{($_ -eq $True)}
{
$RegexOptions = New-Object -TypeName 'System.Collections.Generic.List[System.Text.RegularExpressions.RegexOptions]'
$RegexOptions.Add([System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
$RegexOptions.Add([System.Text.RegularExpressions.RegexOptions]::Multiline)
[System.Text.RegularExpressions.Regex]$RegularExpression = [System.Text.RegularExpressions.Regex]::New($StandardOutputParsingExpression, $RegexOptions.ToArray())
[String[]]$RegularExpressionGroups = $RegularExpression.GetGroupNames() | Where-Object {($_ -notin @('0'))}
[System.Text.RegularExpressions.MatchCollection]$RegularExpressionMatches = $RegularExpression.Matches($CommandContents)
$StandardOutputObjectProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
For ($RegularExpressionMatchIndex = 0; $RegularExpressionMatchIndex -lt $RegularExpressionMatches.Count; $RegularExpressionMatchIndex++)
{
[System.Text.RegularExpressions.Match]$RegularExpressionMatch = $RegularExpressionMatches[$RegularExpressionMatchIndex]
For ($RegularExpressionGroupIndex = 0; $RegularExpressionGroupIndex -lt $RegularExpressionGroups.Count; $RegularExpressionGroupIndex++)
{
[String]$RegularExpressionGroup = $RegularExpressionGroups[$RegularExpressionGroupIndex]
Switch ($RegularExpressionGroup)
{
{($_ -imatch '(^PropertyName$)')}
{
$PropertyDetails = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$PropertyDetails.Add('Name', $Null)
$PropertyDetails.Add('Value', $Null)
$PropertyDetails.Name = ($RegularExpressionMatch.Groups[$($RegularExpressionGroup)].Value) -ireplace '(\s+)|(\-)|(_)', ''
}
{($_ -imatch '(^PropertyValue$)')}
{
$PropertyDetails.Value = $RegularExpressionMatch.Groups[$($RegularExpressionGroup)].Value
Switch ($True)
{
{($PropertyDetails.Value -imatch '\+(\-){1,}\+')}
{
$PropertyDetails.Value = $Null
}
{($PropertyDetails.Value -imatch '(.+\,\s+.+){1,}')}
{
#$PropertyDetails.Value = $PropertyDetails.Value.Split(',').Trim()
}
{($PropertyDetails.Value -imatch '.+\(.+\).+')}
{
#$PropertyDetails.Value = ($PropertyDetails.Value.Split('()', [System.StringSplitOptions]::RemoveEmptyEntries) -ireplace 'bytes', '')[1]
}
}
Switch ($Null -ine $PropertyDetails.Value)
{
{($_ -eq $True)}
{
$PropertyDetails.Value = $PropertyDetails.Value.Trim()
}
}
}
}
}
Switch ($StandardOutputObjectProperties.Contains($PropertyDetails.Name))
{
{($_ -eq $False)}
{
$Null = $StandardOutputObjectProperties.Add($PropertyDetails.Name, $PropertyDetails.Value)
}
}
}
$OutputObjectProperties.StandardOutputObject = New-Object -TypeName 'PSObject' -Property ($StandardOutputObjectProperties)
}
}
}
}
}
Catch
{
$ErrorMessageList = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ErrorMessageList.Add('Message', $_.Exception.Message)
$ErrorMessageList.Add('Category', $_.Exception.ErrorRecord.FullyQualifiedErrorID)
$ErrorMessageList.Add('Script', $_.InvocationInfo.ScriptName)
$ErrorMessageList.Add('LineNumber', $_.InvocationInfo.ScriptLineNumber)
$ErrorMessageList.Add('LinePosition', $_.InvocationInfo.OffsetInLine)
$ErrorMessageList.Add('Code', $_.InvocationInfo.Line.Trim())
ForEach ($ErrorMessage In $ErrorMessageList.GetEnumerator())
{
$LoggingDetails.ErrorMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - ERROR: $($ErrorMessage.Key): $($ErrorMessage.Value)"
Write-Warning -Message ($LoggingDetails.ErrorMessage) -Verbose
}
Throw "$($_.Exception.Message)"
}
Finally
{
#Dispose of the process object
Try {$Null = $Process.Dispose()} Catch {}
#Determine the date and time the function completed execution
$FunctionEndTime = (Get-Date)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($CmdletName) ended on $($FunctionEndTime.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
#Log the total script execution time
$FunctionExecutionTimespan = New-TimeSpan -Start ($FunctionStartTime) -End ($FunctionEndTime)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function execution took $($FunctionExecutionTimespan.Hours.ToString()) hour(s), $($FunctionExecutionTimespan.Minutes.ToString()) minute(s), $($FunctionExecutionTimespan.Seconds.ToString()) second(s), and $($FunctionExecutionTimespan.Milliseconds.ToString()) millisecond(s)."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($CmdletName)`' is completed."
Write-Verbose -Message ($LoggingDetails.LogMessage)
$OutputObject = New-Object -TypeName 'PSObject' -Property ($OutputObjectProperties)
Switch (($LogOutput.IsPresent -eq $True) -or ($LogOutput -eq $True))
{
{($_ -eq $True)}
{
ForEach ($Property In $OutputObject.PSObject.Properties)
{
Switch ($Property.Name)
{
{($_ -iin @('StandardOutput', 'StandardError'))}
{
Switch (([String]::IsNullOrEmpty($Property.Value) -eq $False) -and ([String]::IsNullOrWhiteSpace($Property.Value) -eq $False))
{
{($_ -eq $True)}
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - $($Property.Name): $($Property.Value)"
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
}
Default
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - $($Property.Name): N/A"
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
}
}
}
}
}
}
}
Write-Output -InputObject ($OutputObject)
}
}
#endregion
<#
$ProcessOutput = Start-ProcessWithOutput -FilePath 'dsregcmd.exe' -ArgumentList '/status' -CreateNoWindow -Verbose
$ProcessOutput.StandardOutputObject | ConvertTo-JSON -Depth 10 -OutVariable 'AzureADDetails'
$ProcessOutput
#>
+913
View File
@@ -0,0 +1,913 @@
#Requires -Version 3
<#
.SYNOPSIS
Dynamically generates the XML required for the Invoke-DriverPackageCreation powershell script.
.DESCRIPTION
This script greatly reduces the amount of time it would take to build the XML by hand after determining how many models are deployed within the current environment.
.PARAMETER QuerySQLDatabase
Determines whether or not to enable the SQL database querying functionality.
.PARAMETER SQLDatabaseFQDN
The fully qualified domain name of the SQL database that will be queried. Windows authentication will be used by default, but SQL authentication can be used if modifications are made to the 'Invoke-SQLDBQuery' parameters.
.PARAMETER SQLDatabaseBName
The name of the SQL database that will be queried.
.PARAMETER LogDir
A valid folder path. If the folder does not exist, it will be created. This parameter can also be specified by the alias "LogPath".
.PARAMETER ContinueOnError
Ignore failures.
.EXAMPLE
Use this command to execute a VBSCript that will launch this powershell script automatically with the specified parameters. This is useful to avoid powershell execution complexities.
cscript.exe /nologo "%FolderPathContainingScript%\%ScriptName%.vbs" /SwitchParameter /ScriptParameter:"%ScriptParameterValue%" /ScriptParameterArray:"%ScriptParameterValue1%,%ScriptParameterValue2%"
wscript.exe /nologo "%FolderPathContainingScript%\%ScriptName%.vbs" /SwitchParameter /ScriptParameter:"%ScriptParameterValue%" /ScriptParameterArray:"%ScriptParameterValue1%,%ScriptParameterValue2%"
.EXAMPLE
powershell.exe -ExecutionPolicy Bypass -NoProfile -NoLogo -File "%FolderPathContainingScript%\%ScriptName%.ps1" -SwitchParameter -ScriptParameter "%ScriptParameterValue%"
.EXAMPLE
powershell.exe -ExecutionPolicy Bypass -NonInteractive -NoProfile -NoLogo -WindowStyle Hidden -Command "& '%FolderPathContainingScript%\%ScriptName%.ps1' -ScriptParameter1 '%ScriptParameter1Value%' -ScriptParameter2 %ScriptParameter2Value% -SwitchParameter"
.NOTES
If using the database query functionality to get the model list, just ensure that the following columns are returned in order for the XML schema to be generated correctly.
BaseboardProduct
SystemFamily
SystemManufacturer
SystemProductName
SystemSKU
SystemVersion
.LINK
Place any useful link here where your function or cmdlet can be referenced
#>
[CmdletBinding(SupportsShouldProcess=$True)]
Param
(
[Parameter(Mandatory=$False)]
[ValidateNotNullOrEmpty()]
[Switch]$QuerySQLDatabase,
[Parameter(Mandatory=$False)]
[ValidateNotNullOrEmpty()]
[String]$SQLDatabaseFQDN,
[Parameter(Mandatory=$False)]
[ValidateNotNullOrEmpty()]
[String]$SQLDatabaseBName,
[Parameter(Mandatory=$False)]
[ValidateNotNullOrEmpty()]
[Alias('LogDir', 'LogPath')]
[System.IO.DirectoryInfo]$LogDirectory,
[Parameter(Mandatory=$False)]
[Switch]$ContinueOnError
)
Function Get-AdministrativePrivilege
{
$Identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$Principal = New-Object System.Security.Principal.WindowsPrincipal($Identity)
Write-Output -InputObject ($Principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator))
}
If ((Get-AdministrativePrivilege) -eq $False)
{
[System.IO.FileInfo]$ScriptPath = "$($MyInvocation.MyCommand.Path)"
$ArgumentList = New-Object -TypeName 'System.Collections.Generic.List[String]'
$ArgumentList.Add('-ExecutionPolicy Bypass')
$ArgumentList.Add('-NoProfile')
$ArgumentList.Add('-NoExit')
$ArgumentList.Add('-NoLogo')
$ArgumentList.Add("-File `"$($ScriptPath.FullName)`"")
$Null = Start-Process -FilePath "$([System.Environment]::SystemDirectory)\WindowsPowershell\v1.0\powershell.exe" -WorkingDirectory "$([System.Environment]::SystemDirectory)" -ArgumentList ($ArgumentList.ToArray()) -WindowStyle Normal -Verb RunAs -PassThru
}
Else
{
#Determine the date and time we executed the function
$ScriptStartTime = (Get-Date)
#Define Default Action Preferences
$Script:DebugPreference = 'SilentlyContinue'
$Script:ErrorActionPreference = 'Stop'
$Script:VerbosePreference = 'SilentlyContinue'
$Script:WarningPreference = 'Continue'
$Script:ConfirmPreference = 'None'
$Script:WhatIfPreference = $False
#Load WMI Classes
$Baseboard = Get-WmiObject -Namespace "root\CIMv2" -Class "Win32_Baseboard" -Property *
$Bios = Get-WmiObject -Namespace "root\CIMv2" -Class "Win32_Bios" -Property *
$ComputerSystem = Get-WmiObject -Namespace "root\CIMv2" -Class "Win32_ComputerSystem" -Property *
$OperatingSystem = Get-WmiObject -Namespace "root\CIMv2" -Class "Win32_OperatingSystem" -Property *
$MSSystemInformation = Get-WmiObject -Namespace "root\WMI" -Class "MS_SystemInformation" -Property *
#Retrieve property values
$OSArchitecture = $($OperatingSystem.OSArchitecture).Replace("-bit", "").Replace("32", "86").Insert(0,"x").ToUpper()
#Define variable(s)
$DateTimeLogFormat = 'dddd, MMMM dd, yyyy @ hh:mm:ss.FFF tt' ###Monday, January 01, 2019 @ 10:15:34.000 AM###
[ScriptBlock]$GetCurrentDateTimeLogFormat = {(Get-Date).ToString($DateTimeLogFormat)}
$DateTimeMessageFormat = 'MM/dd/yyyy HH:mm:ss.FFF' ###03/23/2022 11:12:48.347###
[ScriptBlock]$GetCurrentDateTimeMessageFormat = {(Get-Date).ToString($DateTimeMessageFormat)}
$DateFileFormat = 'yyyyMMdd' ###20190403###
[ScriptBlock]$GetCurrentDateFileFormat = {(Get-Date).ToString($DateFileFormat)}
$DateTimeFileFormat = 'yyyyMMdd_HHmmss' ###20190403_115354###
[ScriptBlock]$GetCurrentDateTimeFileFormat = {(Get-Date).ToString($DateTimeFileFormat)}
[System.IO.FileInfo]$ScriptPath = "$($MyInvocation.MyCommand.Definition)"
[System.IO.DirectoryInfo]$ScriptDirectory = "$($ScriptPath.Directory.FullName)"
[System.IO.DirectoryInfo]$ContentDirectory = "$($ScriptDirectory.FullName)\Content"
[System.IO.DirectoryInfo]$FunctionsDirectory = "$($ScriptDirectory.FullName)\Functions"
[System.IO.DirectoryInfo]$ModulesDirectory = "$($ScriptDirectory.FullName)\Modules"
[System.IO.DirectoryInfo]$ToolsDirectory = "$($ScriptDirectory.FullName)\Tools"
[System.IO.DirectoryInfo]$ToolsDirectory_OSAll = "$($ToolsDirectory.FullName)\All"
[System.IO.DirectoryInfo]$ToolsDirectory_OSArchSpecific = "$($ToolsDirectory.FullName)\$($OSArchitecture)"
[System.IO.DirectoryInfo]$System32Directory = [System.Environment]::SystemDirectory
[System.IO.DirectoryInfo]$ProgramFilesDirectory = "$($Env:SystemDrive)\Program Files"
[System.IO.DirectoryInfo]$ProgramFilesx86Directory = "$($Env:SystemDrive)\Program Files (x86)"
[System.IO.FileInfo]$PowershellPath = "$($System32Directory.FullName)\WindowsPowershell\v1.0\powershell.exe"
[System.IO.DirectoryInfo]$System32Directory = "$([System.Environment]::SystemDirectory)"
$IsWindowsPE = Test-Path -Path 'HKLM:\SYSTEM\ControlSet001\Control\MiniNT' -ErrorAction SilentlyContinue
[System.Text.RegularExpressions.RegexOptions[]]$RegexOptions = [System.Text.RegularExpressions.RegexOptions]::IgnoreCase, [System.Text.RegularExpressions.RegexOptions]::Multiline
[ScriptBlock]$GetRandomGUID = {[System.GUID]::NewGUID().GUID.ToString().ToUpper()}
[String]$ParameterSetName = "$($PSCmdlet.ParameterSetName)"
$TextInfo = (Get-Culture).TextInfo
$Script:LASTEXITCODE = 0
$TerminationCodes = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$TerminationCodes.Add('Success', @(0))
$TerminationCodes.Add('Warning', @(5000..5999))
$TerminationCodes.Add('Error', @(6000..6999))
$Script:WarningCodeIndex = 0
[ScriptBlock]$GetAvailableWarningCode = {$TerminationCodes.Warning[$Script:WarningCodeIndex]; $Script:WarningCodeIndex++}
$Script:ErrorCodeIndex = 0
[ScriptBlock]$GetAvailableErrorCode = {$TerminationCodes.Error[$Script:ErrorCodeIndex]; $Script:ErrorCodeIndex++}
$LoggingDetails = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$LoggingDetails.Add('LogMessage', $Null)
$LoggingDetails.Add('WarningMessage', $Null)
$LoggingDetails.Add('ErrorMessage', $Null)
$RegularExpressionTable = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$RegularExpressionTable.Base64 = '^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$' -As [Regex]
$CommonParameterList = New-Object -TypeName 'System.Collections.Generic.List[String]'
$CommonParameterList.AddRange([System.Management.Automation.PSCmdlet]::CommonParameters)
$CommonParameterList.AddRange([System.Management.Automation.PSCmdlet]::OptionalCommonParameters)
$HashAlgorithm = 'SHA256'
#Define the error handling definition
[ScriptBlock]$ErrorHandlingDefinition = {
If (($Null -ieq $Script:LASTEXITCODE) -or ($Script:LASTEXITCODE -eq 0))
{
[Int]$Script:LASTEXITCODE = $GetAvailableErrorCode.InvokeReturnAsIs()
}
$ErrorMessageList = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ErrorMessageList.Add('Message', $_.Exception.Message)
$ErrorMessageList.Add('Category', $_.Exception.ErrorRecord.FullyQualifiedErrorID)
$ErrorMessageList.Add('ExitCode', $Script:LASTEXITCODE)
$ErrorMessageList.Add('Script', $_.InvocationInfo.ScriptName)
$ErrorMessageList.Add('LineNumber', $_.InvocationInfo.ScriptLineNumber)
$ErrorMessageList.Add('LinePosition', $_.InvocationInfo.OffsetInLine)
$ErrorMessageList.Add('Code', $_.InvocationInfo.Line.Trim())
ForEach ($ErrorMessage In $ErrorMessageList.GetEnumerator())
{
$LoggingDetails.ErrorMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - ERROR: $($ErrorMessage.Key): $($ErrorMessage.Value)"
Write-Warning -Message ($LoggingDetails.ErrorMessage) -Verbose
}
Switch (($ContinueOnError.IsPresent -eq $False) -or ($ContinueOnError -eq $False))
{
{($_ -eq $True)}
{
Throw
}
}
}
#Determine default parameter value(s)
Switch ($True)
{
{([String]::IsNullOrEmpty($LogDirectory) -eq $True) -or ([String]::IsNullOrWhiteSpace($LogDirectory) -eq $True)}
{
[System.IO.DirectoryInfo]$ApplicationDataRootDirectory = "$($Env:ProgramData)\Invoke-DriverPackageCreator"
[System.IO.DirectoryInfo]$LogDirectory = "$($ApplicationDataRootDirectory.FullName)\Logs"
}
}
#Start transcripting (Logging)
[System.IO.FileInfo]$ScriptLogPath = "$($LogDirectory.FullName)\$($ScriptPath.BaseName)_$($GetCurrentDateFileFormat.Invoke()).log"
If ($ScriptLogPath.Directory.Exists -eq $False) {$Null = [System.IO.Directory]::CreateDirectory($ScriptLogPath.Directory.FullName)}
Start-Transcript -Path "$($ScriptLogPath.FullName)" -Force -WhatIf:$False
#Log any useful information
[String]$CmdletName = $MyInvocation.MyCommand.Name
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of script `"$($CmdletName)`" began on $($ScriptStartTime.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Script Path = $($ScriptPath.FullName)"
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
[String[]]$AvailableScriptParameters = (Get-Command -Name ($ScriptPath.FullName)).Parameters.GetEnumerator() | Where-Object {($_.Value.Name -inotin $CommonParameterList)} | ForEach-Object {"-$($_.Value.Name):$($_.Value.ParameterType.Name)"}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Available Script Parameter(s) = $($AvailableScriptParameters -Join ', ')"
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
[String[]]$SuppliedScriptParameters = $PSBoundParameters.GetEnumerator() | ForEach-Object {"-$($_.Key):$($_.Value.GetType().Name)"}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Supplied Script Parameter(s) = $($SuppliedScriptParameters -Join ', ')"
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
Switch ($True)
{
{([String]::IsNullOrEmpty($ParameterSetName) -eq $False)}
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Parameter Set Name = $($ParameterSetName)"
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
}
}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Command Line: $((Get-WMIObject -Namespace 'Root\CIMv2' -Class 'Win32_Process' -Filter "ProcessID = $($PID)").CommandLine)"
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - $($PSBoundParameters.Count) command line parameter(s) were specified."
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
$OperatingSystemDetailsTable = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$OperatingSystemDetailsTable.ProductName = $OperatingSystem.Caption -ireplace '(Microsoft\s+)', ''
$OperatingSystemDetailsTable.Version = $OperatingSystem.Version
$OperatingSystemDetailsTable.Architecture = $OperatingSystem.OSArchitecture
$OperatingSystemRegistryDetails = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'
$OperatingSystemRegistryDetails.Add((New-Object -TypeName 'PSObject' -Property @{Alias = ''; Path = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion'; ValueName = 'UBR'; Value = $Null}))
$OperatingSystemRegistryDetails.Add((New-Object -TypeName 'PSObject' -Property @{Alias = 'ReleaseVersion'; Path = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion'; ValueName = 'ReleaseID'; Value = $Null}))
$OperatingSystemRegistryDetails.Add((New-Object -TypeName 'PSObject' -Property @{Alias = 'ReleaseID'; Path = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion'; ValueName = 'DisplayVersion'; Value = $Null}))
ForEach ($OperatingSystemRegistryDetail In $OperatingSystemRegistryDetails)
{
$OperatingSystemRegistryDetail.Value = Try {(Get-Item -Path $OperatingSystemRegistryDetail.Path).GetValue($OperatingSystemRegistryDetail.ValueName)} Catch {}
:NextOSDetail Switch (([String]::IsNullOrEmpty($OperatingSystemRegistryDetail.Value) -eq $False) -and ([String]::IsNullOrWhiteSpace($OperatingSystemRegistryDetail.Value) -eq $False))
{
{($_ -eq $True)}
{
Switch ($OperatingSystemRegistryDetail.ValueName)
{
{($_ -ieq 'UBR')}
{
$OperatingSystemDetailsTable.Version = $OperatingSystemDetailsTable.Version + '.' + $OperatingSystemRegistryDetail.Value
Break NextOSDetail
}
}
Switch (([String]::IsNullOrEmpty($OperatingSystemRegistryDetail.Alias) -eq $False) -and ([String]::IsNullOrWhiteSpace($OperatingSystemRegistryDetail.Alias) -eq $False))
{
{($_ -eq $True)}
{
$OperatingSystemDetailsTable.$($OperatingSystemRegistryDetail.Alias) = $OperatingSystemRegistryDetail.Value
}
Default
{
$OperatingSystemDetailsTable.$($OperatingSystemRegistryDetail.ValueName) = $OperatingSystemRegistryDetail.Value
}
}
}
Default
{
$OperatingSystemDetailsTable.$($OperatingSystemRegistryDetail.ValueName) = $OperatingSystemRegistryDetail.Value
}
}
}
ForEach ($OperatingSystemDetail In $OperatingSystemDetailsTable.GetEnumerator())
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - $($OperatingSystemDetail.Key): $($OperatingSystemDetail.Value)"
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Powershell Version: $($PSVersionTable.PSVersion.ToString())"
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
$ExecutionPolicyList = Get-ExecutionPolicy -List
For ($ExecutionPolicyListIndex = 0; $ExecutionPolicyListIndex -lt $ExecutionPolicyList.Count; $ExecutionPolicyListIndex++)
{
$ExecutionPolicy = $ExecutionPolicyList[$ExecutionPolicyListIndex]
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - The powershell execution policy is currently set to `"$($ExecutionPolicy.ExecutionPolicy.ToString())`" for the `"$($ExecutionPolicy.Scope.ToString())`" scope."
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
}
#Log hardware information
$MSSystemInformationMembers = $MSSystemInformation.PSObject.Properties | Where-Object {($_.MemberType -imatch '^NoteProperty$|^Property$') -and ($_.Name -imatch '^Base.*|Bios.*|System.*$') -and ($_.Name -inotmatch '^.*Major.*|.*Minor.*|.*Properties.*$')} | Sort-Object -Property @('Name')
Switch ($MSSystemInformationMembers.Count -gt 0)
{
{($_ -eq $True)}
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to display device information properties from the `"$($MSSystemInformation.__CLASS)`" WMI class located within the `"$($MSSystemInformation.__NAMESPACE)`" WMI namespace. Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
ForEach ($MSSystemInformationMember In $MSSystemInformationMembers)
{
[String]$MSSystemInformationMemberName = ($MSSystemInformationMember.Name)
[String]$MSSystemInformationMemberValue = $MSSystemInformation.$($MSSystemInformationMemberName)
Switch ([String]::IsNullOrEmpty($MSSystemInformationMemberValue))
{
{($_ -eq $False)}
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - $($MSSystemInformationMemberName) = $($MSSystemInformationMemberValue)"
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
}
}
}
}
Default
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - The `"MSSystemInformation`" WMI class could not be found."
Write-Warning -Message ($LoggingDetails.WarningMessage) -Verbose
}
}
#region Log Cleanup
[Int]$MaximumLogHistory = 3
$LogList = Get-ChildItem -Path ($LogDirectory.FullName) -Filter "$($ScriptPath.BaseName)_*" -Recurse -Force | Where-Object {($_ -is [System.IO.FileInfo])}
$SortedLogList = $LogList | Sort-Object -Property @('LastWriteTime') -Descending | Select-Object -Skip ($MaximumLogHistory)
Switch ($SortedLogList.Count -gt 0)
{
{($_ -eq $True)}
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - There are $($SortedLogList.Count) log file(s) requiring cleanup."
Write-Warning -Message ($LoggingDetails.WarningMessage) -Verbose
For ($SortedLogListIndex = 0; $SortedLogListIndex -lt $SortedLogList.Count; $SortedLogListIndex++)
{
Try
{
$Log = $SortedLogList[$SortedLogListIndex]
$LogAge = New-TimeSpan -Start ($Log.LastWriteTime) -End (Get-Date)
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to cleanup log file `"$($Log.FullName)`". Please Wait... [Last Modified: $($Log.LastWriteTime.ToString($DateTimeMessageFormat))] [Age: $($LogAge.Days.ToString()) day(s); $($LogAge.Hours.ToString()) hours(s); $($LogAge.Minutes.ToString()) minute(s); $($LogAge.Seconds.ToString()) second(s)]."
Write-Warning -Message ($LoggingDetails.WarningMessage) -Verbose
$Null = [System.IO.File]::Delete($Log.FullName)
}
Catch
{
}
}
}
Default
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - There are $($SortedLogList.Count) log file(s) requiring cleanup."
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
}
}
#endregion
#region Import Dependency Modules
If (($ModulesDirectory.Exists -eq $True) -and ($ModulesDirectory.GetDirectories().Count -gt 0))
{
$Modules = Get-Module -Name "$($ModulesDirectory.FullName)\*" -ListAvailable -ErrorAction Stop
$ModuleGroups = $Modules | Group-Object -Property @('Name')
ForEach ($ModuleGroup In $ModuleGroups)
{
$LatestModuleVersion = $ModuleGroup.Group | Sort-Object -Property @('Version') -Descending | Select-Object -First 1
If ($Null -ine $LatestModuleVersion)
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to import dependency powershell module `"$($LatestModuleVersion.Name)`" [Version: $($LatestModuleVersion.Version.ToString())]. Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
Try {$Null = Import-Module -Name "$($LatestModuleVersion.Path)" -Global -DisableNameChecking -Force -Verbose:$False} Catch {}
}
}
}
#endregion
#region Dot Source Dependency Scripts
#Dot source any additional script(s) from the functions directory. This will provide flexibility to add additional functions without adding complexity to the main script and to maintain function consistency.
Try
{
If ($FunctionsDirectory.Exists -eq $True)
{
$AdditionalFunctionsFilter = New-Object -TypeName 'System.Collections.Generic.List[String]'
$AdditionalFunctionsFilter.Add('*.ps1')
$AdditionalFunctionsToImport = Get-ChildItem -Path "$($FunctionsDirectory.FullName)" -Include ($AdditionalFunctionsFilter) -Recurse -Force | Where-Object {($_ -is [System.IO.FileInfo])}
$AdditionalFunctionsToImportCount = $AdditionalFunctionsToImport | Measure-Object | Select-Object -ExpandProperty Count
If ($AdditionalFunctionsToImportCount -gt 0)
{
ForEach ($AdditionalFunctionToImport In $AdditionalFunctionsToImport)
{
Try
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to dot source the functions contained within the dependency script `"$($AdditionalFunctionToImport.Name)`". Please Wait... [Script Path: `"$($AdditionalFunctionToImport.FullName)`"]"
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
. "$($AdditionalFunctionToImport.FullName)"
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
}
}
}
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
#endregion
#region Load any required libraries
[System.IO.DirectoryInfo]$LibariesDirectory = "$($FunctionsDirectory.FullName)\Libraries"
Switch ([System.IO.Directory]::Exists($LibariesDirectory.FullName))
{
{($_ -eq $True)}
{
$LibraryPatternList = New-Object -TypeName 'System.Collections.Generic.List[String]'
#$LibraryPatternList.Add('')
Switch ($LibraryPatternList.Count -gt 0)
{
{($_ -eq $True)}
{
$LibraryList = Get-ChildItem -Path ($LibariesDirectory.FullName) -Include ($LibraryPatternList.ToArray()) -Recurse -Force | Where-Object {($_ -is [System.IO.FileInfo])}
$LibraryListCount = ($LibraryList | Measure-Object).Count
Switch ($LibraryListCount -gt 0)
{
{($_ -eq $True)}
{
For ($LibraryListIndex = 0; $LibraryListIndex -lt $LibraryListCount; $LibraryListIndex++)
{
$Library = $LibraryList[$LibraryListIndex]
[Byte[]]$LibraryBytes = [System.IO.File]::ReadAllBytes($Library.FullName)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to load assembly `"$($Library.FullName)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
$Null = [System.Reflection.Assembly]::Load($LibraryBytes)
}
}
}
}
}
}
}
#endregion
#Perform script action(s)
Try
{
#region Define the driver package creation settings XML schema
$GetXMLDateCreated = {(Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm')}
$ManufacturerList = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'
$ManufacturerListEntry = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ManufacturerListEntry.Enabled = $True
$ManufacturerListEntry.Name = 'Dell'
$ManufacturerListEntry.EligibilityExpression = '(^.*Dell.*$)'
$ManufacturerListEntry.ProductIDExpression = @{Name = 'BaseboardProduct'; Expression = {If ($_.SystemSKU.Length -lt 6) {$_.SystemSKU} Else {$Null}}}
$ManufacturerListEntry.ProductIDPropertyName = 'SystemSKU'
$ManufacturerListEntry.URLs = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ManufacturerListEntry.URLs.DriverPackCatalog = 'https://dl.dell.com/catalog/DriverPackCatalog.cab'
$ManufacturerListEntry.URLs.DownloadBase = 'https://dl.dell.com'
$ManufacturerListEntry.ModelList = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'
If ($QuerySQLDatabase.IsPresent -eq $False)
{
$ManufacturerListEntry.ModelList.Add((New-Object -TypeName 'PSObject' -Property @{Enabled = $False; SystemProductName = 'Latitude 5430'; ProductID = '0B04'; BaseboardProduct = '01Y2TP'; SystemSKU = '0B04'; SystemVersion = ''; SystemFamily = 'Latitude'; SystemManufacturer = $ManufacturerListEntry.Name}))
}
$ManufacturerListObject = New-Object -TypeName 'PSObject' -Property ($ManufacturerListEntry)
$ManufacturerList.Add($ManufacturerListEntry)
$ManufacturerListEntry = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ManufacturerListEntry.Enabled = $True
$ManufacturerListEntry.Name = 'HP'
$ManufacturerListEntry.EligibilityExpression = '(^.*HP.*$)|(^.*Hewlett.*Packard.*$)'
$ManufacturerListEntry.ProductIDExpression = @{Name = 'BaseboardProduct'; Expression = {[Regex]::Match($_.BaseboardProduct, '^\w{4}').Value.ToUpper()}}
$ManufacturerListEntry.ProductIDPropertyName = 'BaseboardProduct'
$ManufacturerListEntry.URLs = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ManufacturerListEntry.URLs.DriverPackCatalog = 'https://ftp.hp.com/pub/caps-softpaq/cmit/HPClientDriverPackCatalog.cab'
$ManufacturerListEntry.URLs.DownloadBase = ''
$ManufacturerListEntry.ModelList = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'
If ($QuerySQLDatabase.IsPresent -eq $False)
{
$ManufacturerListEntry.ModelList.Add((New-Object -TypeName 'PSObject' -Property @{Enabled = $False; SystemProductName = 'HP ZBook Studio G7 Mobile Workstation'; ProductID = '8736'; BaseboardProduct = '8736'; SystemSKU = '8YP41AV'; SystemVersion = ''; SystemFamily = '103C_5336AN HP ZBook'; SystemManufacturer = $ManufacturerListEntry.Name}))
}
$ManufacturerListObject = New-Object -TypeName 'PSObject' -Property ($ManufacturerListEntry)
$ManufacturerList.Add($ManufacturerListEntry)
$ManufacturerListEntry = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ManufacturerListEntry.Enabled = $True
$ManufacturerListEntry.Name = 'Lenovo'
$ManufacturerListEntry.EligibilityExpression = '(^.*LENOVO.*$)'
$ManufacturerListEntry.ProductIDExpression = @{Name = 'BaseboardProduct'; Expression = {[Regex]::Match($_.SystemProductName, '^\w{4}').Value.ToUpper()}}
$ManufacturerListEntry.ProductIDPropertyName = 'SystemProductName'
$ManufacturerListEntry.URLs = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ManufacturerListEntry.URLs.DriverPackCatalog = 'https://download.lenovo.com/cdrt/td/catalogv2.xml'
$ManufacturerListEntry.URLs.DownloadBase = ''
$ManufacturerListEntry.ModelList = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'
If ($QuerySQLDatabase.IsPresent -eq $False)
{
$ManufacturerListEntry.ModelList.Add((New-Object -TypeName 'PSObject' -Property @{Enabled = $False; SystemProductName = '10AXS2CQ00'; ProductID = '10AX'; BaseboardProduct = '10AXS2CQ00'; SystemSKU = 'LENOVO_MT_10AX'; SystemVersion = 'ThinkCentre M73'; SystemFamily = 'To be filled by O.E.M.'; SystemManufacturer = $ManufacturerListEntry.Name}))
}
$ManufacturerListObject = New-Object -TypeName 'PSObject' -Property ($ManufacturerListEntry)
$ManufacturerList.Add($ManufacturerListObject)
Switch ($QuerySQLDatabase.IsPresent)
{
{($_ -eq $True)}
{
Switch (Test-Connection -ComputerName $SQLDatabaseFQDN -Count 1 -Quiet)
{
{($_ -eq $True)}
{
$ModelListConfigurationDetails = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ModelListConfigurationDetails.ModelListQueryPath = "$($ContentDirectory.FullName)\DBQueries\GetProductIDList.sql" -As [System.IO.FileInfo]
Switch ([System.IO.File]::Exists($ModelListConfigurationDetails.ModelListQueryPath.FullName))
{
{($_ -eq $True)}
{
$ModelListConfigurationDetails.ModelListQueryContents = [System.IO.File]::ReadAllText($ModelListConfigurationDetails.ModelListQueryPath.FullName)
$InvokeSQLDBQueryParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$InvokeSQLDBQueryParameters.Server = $SQLDatabaseFQDN
$InvokeSQLDBQueryParameters.Database = $SQLDatabaseBName
$InvokeSQLDBQueryParameters.DBQueryList = New-Object -TypeName 'System.Collections.Generic.List[String]'
$InvokeSQLDBQueryParameters.DBQueryList.Add($ModelListConfigurationDetails.ModelListQueryContents)
$InvokeSQLDBQueryParameters.ContinueOnError = $False
$InvokeSQLDBQueryParameters.Verbose = $True
$SQLDBQueryResultSet = (Invoke-SQLDBQuery @InvokeSQLDBQueryParameters).ResultSet001 | Sort-Object -Property {$_.SystemProductName.Length} -Descending
$SQLDBQueryResultSetCount = ($SQLDBQueryResultSet | Measure-Object).Count
Switch ($SQLDBQueryResultSetCount -gt 0)
{
{($_ -eq $True)}
{
ForEach ($SQLDBQueryResult In $SQLDBQueryResultSet)
{
$SQLDBQueryResultDetails = $ManufacturerList | Where-Object {($SQLDBQueryResult.SystemManufacturer -imatch $_.EligibilityExpression.ToString())}
Switch ($Null -ine $SQLDBQueryResultDetails)
{
{($_ -eq $True)}
{
$ProductID = Try {($SQLDBQueryResult | Select-Object -Property ($SQLDBQueryResultDetails.ProductIDExpression)).BaseBoardProduct} Catch {$Null}
Switch (([String]::IsNullOrEmpty($ProductID) -eq $False) -and ([String]::IsNullOrWhiteSpace($ProductID) -eq $False))
{
{($_ -eq $True)}
{
$SQLDBQueryResult.SystemManufacturer = $SQLDBQueryResultDetails.Name
$SQLDBQueryResult | Add-Member -Name 'Enabled' -Value $True -MemberType NoteProperty
$SQLDBQueryResult | Add-Member -Name 'ProductID' -Value ($ProductID) -MemberType NoteProperty
Switch ($SQLDBQueryResultDetails.ModelList.ProductID -inotcontains $SQLDBQueryResult.ProductID)
{
{($_ -eq $True)}
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to add product ID `"$($SQLDBQueryResult.ProductID)`" [Model: $($SQLDBQueryResult.SystemProductName)] manufactured by `"$($SQLDBQueryResultDetails.Name)`" to the model list. Please Wait..."
Write-Warning -Message ($LoggingDetails.WarningMessage) -Verbose
$SQLDBQueryResultDetails.ModelList.Add($SQLDBQueryResult)
}
}
}
}
}
Default
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Manufacturer `"$($SQLDBQueryResult.SystemManufacturer)`" is currently unsupported."
Write-Warning -Message ($LoggingDetails.WarningMessage) -Verbose
}
}
}
}
}
}
Default
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - The SQL query file does not exist. [Path: $($ModelListConfigurationDetails.ModelListQueryPath.FullName)]"
Write-Warning -Message ($LoggingDetails.WarningMessage) -Verbose
}
}
}
Default
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Unable to contact the specified SQL database server. [Server: $($SQLDatabaseFQDN)]"
Write-Warning -Message ($LoggingDetails.WarningMessage) -Verbose
}
}
}
}
$XMLWriterSettings = New-Object -TypeName 'System.XML.XMLWriterSettings'
$XMLWriterSettings.Indent = $True
$XMLWriterSettings.IndentChars = "`t" * 1
$XMLWriterSettings.Encoding = [System.Text.Encoding]::Default
$XMLWriterSettings.NewLineHandling = [System.XML.NewLineHandling]::None
$XMLWriterSettings.ConformanceLevel = [System.XML.ConformanceLevel]::Auto
$XMLStringBuilder = New-Object -TypeName 'System.Text.StringBuilder'
$XMLWriter = [System.XML.XMLTextWriter]::Create($XMLStringBuilder, $XMLWritersettings)
[ScriptBlock]$AddXMLWriterNewLine = {$XMLWriter.WriteWhitespace(("`r`n" * 2))}
$XMLWriter.WriteStartDocument()
$AddXMLWriterNewLine.Invoke()
$XMLWriter.WriteProcessingInstruction("xml-stylesheet", "type='text/xsl' href='style.xsl'")
$AddXMLWriterNewLine.Invoke()
$XMLWriter.WriteComment(@'
Please specify the configuration settings that will be used by the driver package creation powershell script.
'@)
$AddXMLWriterNewLine.Invoke()
$XMLWriter.WriteComment(@'
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 :
'@)
$AddXMLWriterNewLine.Invoke()
$XMLWriter.WriteStartElement('Settings')
$XMLWriter.WriteElementString('GeneratedBy', [System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
$XMLWriter.WriteElementString('GeneratedOn', $Env:ComputerName.ToUpper())
$XMLWriter.WriteElementString('GeneratedDate', $GetXMLDateCreated.InvokeReturnAsIs())
$XMLWriter.WriteStartElement('OperatingSystemList')
$OperatingSystemList = Get-WindowsReleaseHistory | Sort-Object -Property @('Name') -Unique
ForEach ($OperatingSystem In $OperatingSystemList)
{
$XMLWriter.WriteStartElement('OperatingSystem')
$XMLWriter.WriteAttributeString('Enabled', $True)
$XMLWriter.WriteAttributeString('Vendor', $OperatingSystem.Vendor)
$XMLWriter.WriteAttributeString('Name', $OperatingSystem.Name)
$XMLWriter.WriteAttributeString('NameExpression', ".*$([Regex]::Match($OperatingSystem.Name, '\d+').Value).*")
$XMLWriter.WriteAttributeString('ArchitectureExpression', '.*64.*')
$XMLWriter.WriteAttributeString('ReleaseExpression', '.*')
$XMLWriter.WriteAttributeString('LatestReleaseOnly', $True)
$XMLWriter.WriteEndElement()
}
$XMLWriter.WriteEndElement()
$XMLWriter.WriteStartElement('ManufacturerList')
$ManufacturerListGroups = $ManufacturerList | Group-Object -Property {$_.Name}
ForEach ($ManufacturerListGroup In $ManufacturerListGroups)
{
$ManufacturerListGroupDetails = $ManufacturerListGroup.Group
$XMLWriter.WriteStartElement('Manufacturer')
$XMLWriter.WriteAttributeString('Enabled', $ManufacturerListGroupDetails.Enabled)
$XMLWriter.WriteAttributeString('Name', $ManufacturerListGroupDetails.Name)
$XMLWriter.WriteAttributeString('EligibilityExpression', $ManufacturerListGroupDetails.EligibilityExpression)
$XMLWriter.WriteAttributeString('ProductIDPropertyName', $ManufacturerListGroupDetails.ProductIDPropertyName)
$XMLWriter.WriteStartElement('URLs')
$XMLWriter.WriteAttributeString('DriverPackCatalog', $ManufacturerListGroupDetails.URLs.DriverPackCatalog)
$XMLWriter.WriteAttributeString('DownloadBase', $ManufacturerListGroupDetails.URLs.DownloadBase)
$XMLWriter.WriteEndElement()
$XMLWriter.WriteStartElement('ModelList')
ForEach ($Model In $ManufacturerListGroupDetails.ModelList)
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to add a XML node for product ID `"$($Model.ProductID)`" [Model: $($Model.SystemProductName)] manufactured by `"$($ManufacturerListGroupDetails.Name)`". Please Wait..."
Write-Warning -Message ($LoggingDetails.WarningMessage) -Verbose
$XMLWriter.WriteStartElement('Model')
$XMLWriter.WriteAttributeString('Enabled', $Model.Enabled)
$XMLWriter.WriteAttributeString('SystemProductName', $Model.SystemProductName)
$XMLWriter.WriteAttributeString('ProductID', $Model.ProductID)
$XMLWriter.WriteAttributeString('BaseboardProduct', $Model.BaseboardProduct)
$XMLWriter.WriteAttributeString('SystemSKU', $Model.SystemSKU)
$XMLWriter.WriteAttributeString('SystemVersion', $Model.SystemVersion)
$XMLWriter.WriteAttributeString('SystemFamily', $Model.SystemFamily)
$XMLWriter.WriteAttributeString('SystemManufacturer', $Model.SystemManufacturer)
$XMLWriter.WriteEndElement()
}
$XMLWriter.WriteEndElement()
$XMLWriter.WriteEndElement()
}
$XMLWriter.WriteEndElement()
$XMLWriter.WriteEndElement()
$XMLWriter.WriteEndDocument()
$XMLWriter.Flush()
$XMLWriter.Close()
$DriverPackageCreationXMLContents = $XMLStringBuilder.ToString()
[System.IO.FileInfo]$DriverPackageCreationXMLExportPath = "$($ContentDirectory.FullName)\Templates\SettingsTemplate.xml"
[Scriptblock]$ExportDriverPackageCreationXML = {
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to export the driver package settings XML to `"$($DriverPackageCreationXMLExportPath.FullName)`". Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
If ([System.IO.Directory]::Exists($DriverPackageCreationXMLExportPath.Directory.FullName) -eq $False) {$Null = [System.IO.Directory]::CreateDirectory($DriverPackageCreationXMLExportPath.Directory.FullName)}
$Null = [System.IO.File]::WriteAllText($DriverPackageCreationXMLExportPath.FullName, $DriverPackageCreationXMLContents, $XMLWriterSettings.Encoding)
}
Switch ([System.IO.File]::Exists($DriverPackageCreationXMLExportPath.FullName))
{
{($_ -eq $True)}
{
$MemoryStream = New-Object -TypeName 'System.IO.MemoryStream'
$StreamWriter = New-Object -TypeName 'System.IO.StreamWriter' -ArgumentList ($MemoryStream)
$Null = $StreamWriter.Write($DriverPackageCreationXMLContents)
$Null = $StreamWriter.Flush()
$Null = $MemoryStream.Position = 0
$DriverPackageCreationXMLContentHash = Get-FileHash -InputStream $MemoryStream -Algorithm ($HashAlgorithm)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - New Driver Package Settings XML Hash: $($DriverPackageCreationXMLContentHash.Hash)"
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
$DriverPackageCreationXMLExportPathHash = Get-FileHash -Path ($DriverPackageCreationXMLExportPath.FullName) -Algorithm ($HashAlgorithm)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Current Driver Package Settings XML Hash: $($DriverPackageCreationXMLExportPathHash.Hash)"
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
Switch ($DriverPackageCreationXMLContentHash.Hash -ne $DriverPackageCreationXMLExportPathHash.Hash)
{
{($_ -eq $True)}
{
$LoggingDetails.WarningMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - The XML metadata file `"$($DriverPackageCreationXMLExportPath.FullName)`" requires an update."
Write-Warning -Message ($LoggingDetails.WarningMessage) -Verbose
$Null = $ExportDriverPackageCreationXML.InvokeReturnAsIs()
}
Default
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - The XML metadata file `"$($DriverPackageCreationXMLExportPath.FullName)`" does not require an update."
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
}
}
}
Default
{
$Null = $ExportDriverPackageCreationXML.InvokeReturnAsIs()
}
}
#endregion
$Script:LASTEXITCODE = $TerminationCodes.Success[0]
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
Try
{
#Determine the date and time the function completed execution
$ScriptEndTime = (Get-Date)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Script execution of `"$($CmdletName)`" ended on $($ScriptEndTime.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
#Log the total script execution time
$ScriptExecutionTimespan = New-TimeSpan -Start ($ScriptStartTime) -End ($ScriptEndTime)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Script execution took $($ScriptExecutionTimespan.Hours.ToString()) hour(s), $($ScriptExecutionTimespan.Minutes.ToString()) minute(s), $($ScriptExecutionTimespan.Seconds.ToString()) second(s), and $($ScriptExecutionTimespan.Milliseconds.ToString()) millisecond(s)"
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Exiting script `"$($ScriptPath.FullName)`" with exit code $($Script:LASTEXITCODE)."
Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose
Stop-Transcript
}
Catch
{
}
}
}
+145
View File
@@ -0,0 +1,145 @@
'Set object values
Set oArguments = WScript.Arguments.Named
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oShell = CreateObject("WScript.Shell")
Set oCMD = oFSO.GetFile(oShell.ExpandEnvironmentStrings("%COMSPEC%"))
Set oPowershell = oFSO.GetFile(oShell.ExpandEnvironmentStrings("%WINDIR%") & "\System32\WindowsPowershell\v1.0\powershell.exe")
'Define ASCII Characters
chrSpace = Chr(32)
chrSingleQuote = Chr(39)
chrDoubleQuote = Chr(34)
'Define Variable(s)
ScriptInterpreter = CreateObject("Scripting.FileSystemObject").GetFileName(WScript.FullName)
If (oArguments.Exists("Debug") = True) Then DebugMode = True End If
'Dynamically convert named VBScript arguments to their eqivalent powershell format
oArgumentCount = oArguments.Count
If (oArgumentCount > 0) Then
StringBuilder = ""
oArgumentCounter = 1
Set ArgumentNameExpression = New RegExp
With ArgumentNameExpression
.Pattern = "^Debug$"
.IgnoreCase = True
.Global = False
.Multiline = False
End With
Set ArgumentValueExpression = New RegExp
With ArgumentValueExpression
.Pattern = "^.*True|.*False$"
.IgnoreCase = True
.Global = False
.Multiline = False
End With
For Each oArgument In oArguments
ArgumentName = Trim(oArgument)
ArgumentValue = oArguments.Item(oArgument)
If (Not(ArgumentNameExpression.Test(ArgumentName))) Then
Select Case ((Len(ArgumentValue) > 0) And (Not(ArgumentValueExpression.Test(ArgumentValue))))
Case True
If (InStr(ArgumentValue, ",") > 0) Then
ArgumentValueParts = Split(ArgumentValue, ",")
ArgumentValuePartsCount = UBound(ArgumentValueParts)
ArgumentValuePartStringBuilder = ""
ArgumentValuePartCounter = 0
For Each ArgumentValuePart In ArgumentValueParts
ArgumentValuePartFormat = chrDoubleQuote & ArgumentValuePart & chrDoubleQuote
ArgumentValuePartStringBuilder = ArgumentValuePartStringBuilder & ArgumentValuePartFormat
If ((ArgumentValuePartsCount > 0) And (ArgumentValuePartCounter < ArgumentValuePartsCount)) Then
ArgumentValuePartStringBuilder = ArgumentValuePartStringBuilder & ","
ArgumentValuePartCounter = ArgumentValuePartCounter + 1
End If
Next
ParameterFormat = "-" & ArgumentName & chrSpace & ArgumentValuePartStringBuilder
ElseIf (IsNumeric(ArgumentValue) = True) Then
ParameterFormat = "-" & ArgumentName & chrSpace & ArgumentValue
Else
ParameterFormat = "-" & ArgumentName & chrSpace & chrDoubleQuote & ArgumentValue & chrDoubleQuote
End If
Case False
ParameterFormat = "-" & ArgumentName
End Select
If (Len(ParameterFormat) > 0) Then
If ((oArgumentCount > 1) And (oArgumentCounter < oArgumentCount)) Then
StringBuilder = StringBuilder & chrSpace
End If
StringBuilder = StringBuilder & ParameterFormat
ArgumentCounter = oArgumentCounter + 1
ParameterFormat = Null
End If
End If
Next
StringBuilderResult = Trim(StringBuilder)
If (Len(StringBuilderResult) > 0) Then
PowershellScriptParameters = StringBuilderResult & ";" & chrSpace & "[System.Environment]::Exit(($LASTEXITCODE -Bor [Int](-Not $? -And -Not $LASTEXITCODE)))"
Else
If (DebugMode = True) Then
WScript.Echo("Debug mode is enabled. The specified command will NOT be executed.")
End If
PowershellScriptParameters = ";" & chrSpace & "[System.Environment]::Exit(($LASTEXITCODE -Bor [Int](-Not $? -And -Not $LASTEXITCODE)))"
End If
Set ArgumentNameExpression = Nothing
Set ArgumentValueExpression = Nothing
Else
If (DebugMode = True) Then
WScript.Echo(oArgumentCount & chrSpace & "arguments were specified.")
End If
End If
'Define Additional Variable(s)
Set ScriptPath = oFSO.GetFile(WScript.ScriptFullName)
ScriptDirectory = ScriptPath.ParentFolder
System32Directory = oShell.ExpandEnvironmentStrings("%WINDIR%") & "\System32"
CommandPromptExecutionParameters = oCMD.Name & chrSpace & "/c"
PowershellExecutionParameters = chrDoubleQuote & oPowershell.Path & chrDoubleQuote & chrSpace & "-ExecutionPolicy Bypass -NonInteractive -NoProfile -NoLogo -WindowStyle Hidden -Command"
PowershellScriptPath = ScriptDirectory & "\" & oFSO.GetBaseName(ScriptPath) & ".ps1"
'Execute Powershell Script
If (Len(PowershellScriptParameters) > 0) Then
Command = PowershellExecutionParameters & chrSpace & chrDoubleQuote & "&" & chrSpace & chrSingleQuote & PowershellScriptPath & chrSingleQuote & chrSpace & PowershellScriptParameters & chrDoubleQuote
Else
Command = PowershellExecutionParameters & chrSpace & chrDoubleQuote & "&" & chrSpace & chrSingleQuote & PowershellScriptPath & chrSingleQuote & chrDoubleQuote
End If
If ((ScriptInterpreter = "cscript.exe") Or (DebugMode = True)) Then
WScript.Echo("Command:" & chrSpace & Command)
End If
If (DebugMode = False) Then
RunCommand = oShell.Run(Command, 0, True)
End If
If ((ScriptInterpreter = "cscript.exe") Or (DebugMode = True)) And (IsEmpty(RunCommand) = False) Then
WScript.Echo("Exit Code:" & chrSpace & RunCommand)
End If
If (DebugMode = False) Then
WScript.Quit(RunCommand)
End If
File diff suppressed because it is too large Load Diff
+145
View File
@@ -0,0 +1,145 @@
'Set object values
Set oArguments = WScript.Arguments.Named
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oShell = CreateObject("WScript.Shell")
Set oCMD = oFSO.GetFile(oShell.ExpandEnvironmentStrings("%COMSPEC%"))
Set oPowershell = oFSO.GetFile(oShell.ExpandEnvironmentStrings("%WINDIR%") & "\System32\WindowsPowershell\v1.0\powershell.exe")
'Define ASCII Characters
chrSpace = Chr(32)
chrSingleQuote = Chr(39)
chrDoubleQuote = Chr(34)
'Define Variable(s)
ScriptInterpreter = CreateObject("Scripting.FileSystemObject").GetFileName(WScript.FullName)
If (oArguments.Exists("Debug") = True) Then DebugMode = True End If
'Dynamically convert named VBScript arguments to their eqivalent powershell format
oArgumentCount = oArguments.Count
If (oArgumentCount > 0) Then
StringBuilder = ""
oArgumentCounter = 1
Set ArgumentNameExpression = New RegExp
With ArgumentNameExpression
.Pattern = "^Debug$"
.IgnoreCase = True
.Global = False
.Multiline = False
End With
Set ArgumentValueExpression = New RegExp
With ArgumentValueExpression
.Pattern = "^.*True|.*False$"
.IgnoreCase = True
.Global = False
.Multiline = False
End With
For Each oArgument In oArguments
ArgumentName = Trim(oArgument)
ArgumentValue = oArguments.Item(oArgument)
If (Not(ArgumentNameExpression.Test(ArgumentName))) Then
Select Case ((Len(ArgumentValue) > 0) And (Not(ArgumentValueExpression.Test(ArgumentValue))))
Case True
If (InStr(ArgumentValue, ",") > 0) Then
ArgumentValueParts = Split(ArgumentValue, ",")
ArgumentValuePartsCount = UBound(ArgumentValueParts)
ArgumentValuePartStringBuilder = ""
ArgumentValuePartCounter = 0
For Each ArgumentValuePart In ArgumentValueParts
ArgumentValuePartFormat = chrDoubleQuote & ArgumentValuePart & chrDoubleQuote
ArgumentValuePartStringBuilder = ArgumentValuePartStringBuilder & ArgumentValuePartFormat
If ((ArgumentValuePartsCount > 0) And (ArgumentValuePartCounter < ArgumentValuePartsCount)) Then
ArgumentValuePartStringBuilder = ArgumentValuePartStringBuilder & ","
ArgumentValuePartCounter = ArgumentValuePartCounter + 1
End If
Next
ParameterFormat = "-" & ArgumentName & chrSpace & ArgumentValuePartStringBuilder
ElseIf (IsNumeric(ArgumentValue) = True) Then
ParameterFormat = "-" & ArgumentName & chrSpace & ArgumentValue
Else
ParameterFormat = "-" & ArgumentName & chrSpace & chrDoubleQuote & ArgumentValue & chrDoubleQuote
End If
Case False
ParameterFormat = "-" & ArgumentName
End Select
If (Len(ParameterFormat) > 0) Then
If ((oArgumentCount > 1) And (oArgumentCounter < oArgumentCount)) Then
StringBuilder = StringBuilder & chrSpace
End If
StringBuilder = StringBuilder & ParameterFormat
ArgumentCounter = oArgumentCounter + 1
ParameterFormat = Null
End If
End If
Next
StringBuilderResult = Trim(StringBuilder)
If (Len(StringBuilderResult) > 0) Then
PowershellScriptParameters = StringBuilderResult & ";" & chrSpace & "[System.Environment]::Exit(($LASTEXITCODE -Bor [Int](-Not $? -And -Not $LASTEXITCODE)))"
Else
If (DebugMode = True) Then
WScript.Echo("Debug mode is enabled. The specified command will NOT be executed.")
End If
PowershellScriptParameters = ";" & chrSpace & "[System.Environment]::Exit(($LASTEXITCODE -Bor [Int](-Not $? -And -Not $LASTEXITCODE)))"
End If
Set ArgumentNameExpression = Nothing
Set ArgumentValueExpression = Nothing
Else
If (DebugMode = True) Then
WScript.Echo(oArgumentCount & chrSpace & "arguments were specified.")
End If
End If
'Define Additional Variable(s)
Set ScriptPath = oFSO.GetFile(WScript.ScriptFullName)
ScriptDirectory = ScriptPath.ParentFolder
System32Directory = oShell.ExpandEnvironmentStrings("%WINDIR%") & "\System32"
CommandPromptExecutionParameters = oCMD.Name & chrSpace & "/c"
PowershellExecutionParameters = chrDoubleQuote & oPowershell.Path & chrDoubleQuote & chrSpace & "-ExecutionPolicy Bypass -NonInteractive -NoProfile -NoLogo -WindowStyle Hidden -Command"
PowershellScriptPath = ScriptDirectory & "\" & oFSO.GetBaseName(ScriptPath) & ".ps1"
'Execute Powershell Script
If (Len(PowershellScriptParameters) > 0) Then
Command = PowershellExecutionParameters & chrSpace & chrDoubleQuote & "&" & chrSpace & chrSingleQuote & PowershellScriptPath & chrSingleQuote & chrSpace & PowershellScriptParameters & chrDoubleQuote
Else
Command = PowershellExecutionParameters & chrSpace & chrDoubleQuote & "&" & chrSpace & chrSingleQuote & PowershellScriptPath & chrSingleQuote & chrDoubleQuote
End If
If ((ScriptInterpreter = "cscript.exe") Or (DebugMode = True)) Then
WScript.Echo("Command:" & chrSpace & Command)
End If
If (DebugMode = False) Then
RunCommand = oShell.Run(Command, 0, True)
End If
If ((ScriptInterpreter = "cscript.exe") Or (DebugMode = True)) And (IsEmpty(RunCommand) = False) Then
WScript.Echo("Exit Code:" & chrSpace & RunCommand)
End If
If (DebugMode = False) Then
WScript.Quit(RunCommand)
End If
File diff suppressed because it is too large Load Diff
+145
View File
@@ -0,0 +1,145 @@
'Set object values
Set oArguments = WScript.Arguments.Named
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oShell = CreateObject("WScript.Shell")
Set oCMD = oFSO.GetFile(oShell.ExpandEnvironmentStrings("%COMSPEC%"))
Set oPowershell = oFSO.GetFile(oShell.ExpandEnvironmentStrings("%WINDIR%") & "\System32\WindowsPowershell\v1.0\powershell.exe")
'Define ASCII Characters
chrSpace = Chr(32)
chrSingleQuote = Chr(39)
chrDoubleQuote = Chr(34)
'Define Variable(s)
ScriptInterpreter = CreateObject("Scripting.FileSystemObject").GetFileName(WScript.FullName)
If (oArguments.Exists("Debug") = True) Then DebugMode = True End If
'Dynamically convert named VBScript arguments to their eqivalent powershell format
oArgumentCount = oArguments.Count
If (oArgumentCount > 0) Then
StringBuilder = ""
oArgumentCounter = 1
Set ArgumentNameExpression = New RegExp
With ArgumentNameExpression
.Pattern = "^Debug$"
.IgnoreCase = True
.Global = False
.Multiline = False
End With
Set ArgumentValueExpression = New RegExp
With ArgumentValueExpression
.Pattern = "^.*True|.*False$"
.IgnoreCase = True
.Global = False
.Multiline = False
End With
For Each oArgument In oArguments
ArgumentName = Trim(oArgument)
ArgumentValue = oArguments.Item(oArgument)
If (Not(ArgumentNameExpression.Test(ArgumentName))) Then
Select Case ((Len(ArgumentValue) > 0) And (Not(ArgumentValueExpression.Test(ArgumentValue))))
Case True
If (InStr(ArgumentValue, ",") > 0) Then
ArgumentValueParts = Split(ArgumentValue, ",")
ArgumentValuePartsCount = UBound(ArgumentValueParts)
ArgumentValuePartStringBuilder = ""
ArgumentValuePartCounter = 0
For Each ArgumentValuePart In ArgumentValueParts
ArgumentValuePartFormat = chrDoubleQuote & ArgumentValuePart & chrDoubleQuote
ArgumentValuePartStringBuilder = ArgumentValuePartStringBuilder & ArgumentValuePartFormat
If ((ArgumentValuePartsCount > 0) And (ArgumentValuePartCounter < ArgumentValuePartsCount)) Then
ArgumentValuePartStringBuilder = ArgumentValuePartStringBuilder & ","
ArgumentValuePartCounter = ArgumentValuePartCounter + 1
End If
Next
ParameterFormat = "-" & ArgumentName & chrSpace & ArgumentValuePartStringBuilder
ElseIf (IsNumeric(ArgumentValue) = True) Then
ParameterFormat = "-" & ArgumentName & chrSpace & ArgumentValue
Else
ParameterFormat = "-" & ArgumentName & chrSpace & chrDoubleQuote & ArgumentValue & chrDoubleQuote
End If
Case False
ParameterFormat = "-" & ArgumentName
End Select
If (Len(ParameterFormat) > 0) Then
If ((oArgumentCount > 1) And (oArgumentCounter < oArgumentCount)) Then
StringBuilder = StringBuilder & chrSpace
End If
StringBuilder = StringBuilder & ParameterFormat
ArgumentCounter = oArgumentCounter + 1
ParameterFormat = Null
End If
End If
Next
StringBuilderResult = Trim(StringBuilder)
If (Len(StringBuilderResult) > 0) Then
PowershellScriptParameters = StringBuilderResult & ";" & chrSpace & "[System.Environment]::Exit(($LASTEXITCODE -Bor [Int](-Not $? -And -Not $LASTEXITCODE)))"
Else
If (DebugMode = True) Then
WScript.Echo("Debug mode is enabled. The specified command will NOT be executed.")
End If
PowershellScriptParameters = ";" & chrSpace & "[System.Environment]::Exit(($LASTEXITCODE -Bor [Int](-Not $? -And -Not $LASTEXITCODE)))"
End If
Set ArgumentNameExpression = Nothing
Set ArgumentValueExpression = Nothing
Else
If (DebugMode = True) Then
WScript.Echo(oArgumentCount & chrSpace & "arguments were specified.")
End If
End If
'Define Additional Variable(s)
Set ScriptPath = oFSO.GetFile(WScript.ScriptFullName)
ScriptDirectory = ScriptPath.ParentFolder
System32Directory = oShell.ExpandEnvironmentStrings("%WINDIR%") & "\System32"
CommandPromptExecutionParameters = oCMD.Name & chrSpace & "/c"
PowershellExecutionParameters = chrDoubleQuote & oPowershell.Path & chrDoubleQuote & chrSpace & "-ExecutionPolicy Bypass -NonInteractive -NoProfile -NoLogo -WindowStyle Hidden -Command"
PowershellScriptPath = ScriptDirectory & "\" & oFSO.GetBaseName(ScriptPath) & ".ps1"
'Execute Powershell Script
If (Len(PowershellScriptParameters) > 0) Then
Command = PowershellExecutionParameters & chrSpace & chrDoubleQuote & "&" & chrSpace & chrSingleQuote & PowershellScriptPath & chrSingleQuote & chrSpace & PowershellScriptParameters & chrDoubleQuote
Else
Command = PowershellExecutionParameters & chrSpace & chrDoubleQuote & "&" & chrSpace & chrSingleQuote & PowershellScriptPath & chrSingleQuote & chrDoubleQuote
End If
If ((ScriptInterpreter = "cscript.exe") Or (DebugMode = True)) Then
WScript.Echo("Command:" & chrSpace & Command)
End If
If (DebugMode = False) Then
RunCommand = oShell.Run(Command, 0, True)
End If
If ((ScriptInterpreter = "cscript.exe") Or (DebugMode = True)) And (IsEmpty(RunCommand) = False) Then
WScript.Echo("Exit Code:" & chrSpace & RunCommand)
End If
If (DebugMode = False) Then
WScript.Quit(RunCommand)
End If
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.