Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #31 enhancement #144

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
169 changes: 169 additions & 0 deletions Modules/Log/Get-RegistryKeyValData.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
<#
.SYNOPSIS
Get-RegistryKeyValData.ps1 retrieves the value of the provided key as
well as the last modified time of the key.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a .PARAMETER attribute.

.NOTES
Next line needed by Kansa.ps1 for proper handling of this script's data
OUTPUT tsv

HKEY_LOCAL_MACHINE
HKEY_USERS
HKEY_CURRENT_USER is a subkey of HKEY_USERS
HKEY_CURRENT_CONFIG is a subkey (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Hardware Profiles\Current)
HKEY_CLASSES_ROOT is a subkey (HKEY_LOCAL_MACHINE\SOFTWARE\Classes)
#>
param(
[string]$Key
)

$Error.Clear()
$ErrorActionPreference = "SilentlyContinue"

## The following code is from
## Name: Get-RegistryKeyTimestamp
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What license was this script released under? Attribution is great, but we need to make sure it's compatible as well.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting this will keep any of your catch blocks from doing anything.

$Orrig_EAP = $ErrorActionPreference
$ErrorActionPreference = "SilentlyContinue"

Write-Host "before try"

try
{
    Write-Host "In try"
    Write-Error "Bad stuff happened"
    Write-Host "After error"
}
catch
{
    Write-Host "In catch"
}
finally
{
    Write-Host "In finally"
    $ErrorActionPreference = $Orrig_EAP
}

Write-Host "after try"
before try
In try
After error
In finally
after try

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$ErrorActionPreference affects non-terminating errors.
Try/Catch/Finally is for handling terminating exceptions.

## Author: Boe Prox
## Version History:
## 1.0 -- Boe Prox 17 Dec 2014
## -Initial Build
#region Create Win32 API Object
Try {
[void][advapi32]
}

Catch {
#region Module Builder
$Domain = [AppDomain]::CurrentDomain
$DynAssembly = New-Object System.Reflection.AssemblyName('RegAssembly')
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run) # Only run in memory
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('RegistryTimeStampModule', $False)
#endregion Module Builder

#region DllImport
$TypeBuilder = $ModuleBuilder.DefineType('advapi32', 'Public, Class')

#region RegQueryInfoKey Method
$PInvokeMethod = $TypeBuilder.DefineMethod(
'RegQueryInfoKey', #Method Name
[Reflection.MethodAttributes] 'PrivateScope, Public, Static, HideBySig, PinvokeImpl', #Method Attributes
[IntPtr], #Method Return Type
[Type[]] @(
[Microsoft.Win32.SafeHandles.SafeRegistryHandle], #Registry Handle
[System.Text.StringBuilder], #Class Name
[UInt32 ].MakeByRefType(), #Class Length
[UInt32], #Reserved
[UInt32 ].MakeByRefType(), #Subkey Count
[UInt32 ].MakeByRefType(), #Max Subkey Name Length
[UInt32 ].MakeByRefType(), #Max Class Length
[UInt32 ].MakeByRefType(), #Value Count
[UInt32 ].MakeByRefType(), #Max Value Name Length
[UInt32 ].MakeByRefType(), #Max Value Name Length
[UInt32 ].MakeByRefType(), #Security Descriptor Size
[long].MakeByRefType() #LastWriteTime
) #Method Parameters
)

$DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String]))
$FieldArray = [Reflection.FieldInfo[]] @(
[Runtime.InteropServices.DllImportAttribute].GetField('EntryPoint'),
[Runtime.InteropServices.DllImportAttribute].GetField('SetLastError')
)

$FieldValueArray = [Object[]] @(
'RegQueryInfoKey', #CASE SENSITIVE!!
$True
)

$SetLastErrorCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder(
$DllImportConstructor,
@('advapi32.dll'),
$FieldArray,
$FieldValueArray
)

$PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute)
#endregion RegQueryInfoKey Method

[void]$TypeBuilder.CreateType()
#endregion DllImport
} ## End of Name: Get-RegistryKeyTimestamp

# Test to make sure the provide key is valid.
Try{
# If valid, get property and set RegistryKey value
If (test-path -Path registry::$Key) {
Get-ItemProperty -Path Registry::$Key
$RegistryKey = Get-Item -Path Registry::$Key

## The following code is from
## Name: Get-RegistryKeyTimestamp
## Author: Boe Prox
## Version History:
## 1.0 -- Boe Prox 17 Dec 2014
## -Initial Build
#region Constant Variables
$ClassLength = 255
[long]$TimeStamp = $null
#endregion Constant Variables

$ClassName = New-Object System.Text.StringBuilder $RegistryKey.Name
$RegistryHandle = $RegistryKey.Handle
#endregion Registry Key Data

#region Retrieve timestamp
$Return = [advapi32]::RegQueryInfoKey(
$RegistryHandle,
$ClassName,
[ref]$ClassLength,
$Null,
[ref]$Null,
[ref]$Null,
[ref]$Null,
[ref]$Null,
[ref]$Null,
[ref]$Null,
[ref]$Null,
[ref]$TimeStamp
)
Switch ($Return) {
0 {
#Convert High/Low date to DateTime Object
$LastWriteTime = [datetime]::FromFileTime($TimeStamp)

#Return object
$Object = [pscustomobject]@{
FullName = $RegistryKey.Name
Name = $RegistryKey.Name -replace '.*\\(.*)','$1'
LastWriteTime = $LastWriteTime
}
$Object.pstypenames.insert(0,'Microsoft.Registry.Timestamp')
$Object
}
122 {
Throw "ERROR_INSUFFICIENT_BUFFER (0x7a)"
}
Default {
Throw "Error ($return) occurred"
}
}
#endregion Retrieve timestamp
## End of Name: Get-RegistryKeyTimestamp
}
# if not, write error message
else {
Write-Error -Message "Key does not exist"
}
}

# If for some reason everything fails, write error message
Catch{
Write-Error -Message "Unable to retrieve data from registry"
}

if ($Error) {
# Write the $Error to the $Errorlog
Write-Error "Get-RegistryKeyValData Error on $env:COMPUTERNAME"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't need to explicitly add the target's computer name. Error handling in the main script already takes care of that.

Write-Error $Error
$Error.Clear()
}
Write-Debug "Exiting $($MyInvocation.MyCommand)"