mirror of
https://github.com/freedbygrace/ADDAP.git
synced 2026-07-26 11:08:13 +00:00
355 lines
23 KiB
PowerShell
355 lines
23 KiB
PowerShell
## 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 |