mirror of
https://github.com/freedbygrace/ADDAP.git
synced 2026-07-26 11:08:13 +00:00
Initial Upload
This commit is contained in:
@@ -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
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
#>
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
@@ -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
|
||||
#>
|
||||
@@ -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
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user