Last active
August 29, 2015 14:16
-
-
Save adbertram/5d20635c863fb9b8259e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Get-LoggedOnUserSID { | |
<# | |
.SYNOPSIS | |
This function queries the registry to find the SID of the user that's currently logged onto the computer interactively. | |
#> | |
[CmdletBinding()] | |
param () | |
process { | |
try { | |
New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS | Out-Null | |
(Get-ChildItem HKU: | where { $_.Name -match 'S-\d-\d+-(\d+-){1,14}\d+$' }).PSChildName | |
} catch { | |
Write-Log -Message "Error: $($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)" -LogLevel '3' | |
$false | |
} | |
} | |
} | |
function Import-RegistryFile { | |
<# | |
.SYNOPSIS | |
A function that uses the utility reg.exe to do a bulk import of registry changes. | |
.DESCRIPTION | |
This function allows the user to import registry changes in bulk by means of a .reg file. This | |
.reg file should only contain 1 set of registry keys such as HKLM or HKCU. If the .reg file | |
contains HKLM, HKCU, HKCR or HKCC key references, the file will be imported directly with no modification. If the | |
.reg file contains HKCU references, it will be modified to account for the currently logged on interactive | |
user, copied to a location on the computer and will be imported under each HKCU hive when another user | |
logs on. | |
.PARAMETER FilePath | |
The file path to the .reg file | |
#> | |
[CmdletBinding()] | |
param ( | |
[Parameter()] | |
[ValidateScript({ Test-Path -Path $_ -PathType 'Leaf' })] | |
[string]$FilePath | |
) | |
begin { | |
try { | |
## Detect if this is a registry file for HKCU, HKLM, HKU, HKCR or HKCC keys | |
$Regex = 'HKEY_CURRENT_USER|HKEY_CLASSES_ROOT|HKEY_LOCAL_MACHINE|HKEY_USERS|HKEY_CURRENT_CONFIG' | |
$HiveNames = Select-String -Path $FilePath -Pattern $Regex | foreach { $_.Matches.Value } | |
$RegFileHive = $HiveNames | Select-Object -Unique | |
if ($RegFileHive -is [array]) { | |
throw "The registry file at '$FilePath' contains more than one hive reference." | |
} else { | |
Write-Log -Message "Detected hive type as $RegFileHive" | |
} | |
if ((Get-Architecture) -eq 'x64') { | |
$RegPath = 'syswow64' | |
} else { | |
$RegPath = 'System32' | |
} | |
} catch { | |
Write-Log -Message "Error: $($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)" -LogLevel '3' | |
return $false | |
} | |
} | |
process { | |
try { | |
if ($RegFileHive -ne 'HKEY_CURRENT_USER') { | |
Write-Log -Message "Starting registry import of reg file $FilePath..." | |
($Result = Start-Process "$($env:Systemdrive)\Windows\$RegPath\reg.exe" -Args "import `"$FilePath`"" -Wait -NoNewWindow -PassThru) | Out-Null | |
Check-Process -Process $Result | |
Write-Log -Message 'Registry file import done' | |
} else { | |
######### | |
## Import the registry file for the currently logged on user | |
######### | |
$LoggedOnSids = Get-LoggedOnUserSID | |
if ($LoggedOnSids.Count -gt 0) { | |
Write-Log -Message "Found $($LoggedOnSids.Count) logged on user SIDs" | |
foreach ($sid in $LoggedOnSids) { | |
## Replace all HKEY_CURRENT_USER references to HKCU\%SID% so that it can be applied to HKCU while not | |
## actually running under that context. Create a new reg file with the replacements in the system's temp folder | |
$HkcuRegFilePath = "$(Get-SystemTempFilePath)\$($FilePath | Split-Path -Leaf)" | |
Write-Log -Message "Replacing HKEY_CURRENT_USER references with HKEY_USERS\$sid and placing temp file in $HkcuRegFilePath" | |
Find-InTextFile -FilePath $FilePath -Find $RegFileHive -Replace "HKEY_USERS\$sid" -NewFilePath $HkcuRegFilePath -Force | |
## Perform a recursive function call to itself to import the newly created reg file | |
Write-Log -Message "Importing reg file $HkcuRegFilePath" | |
Import-RegistryFile -FilePath $HkcuRegFilePath | |
Write-Log -Message "Removing temporary registry file $HkcuRegFilePath" | |
Remove-Item $HkcuRegFilePath -Force | |
} | |
} else { | |
Write-Log -Message 'No users currently logged on. Skipping current user registry import' | |
} | |
######## | |
## Use Active Setup to create a registry value to perform an import of the registry file for each logged on user | |
######## | |
Write-Log -Message "Copying $FilePath to systemp temp folder for later user" | |
Copy-Item -Path $FilePath -Destination "$(Get-SystemTempFilePath)\$($FilePath | Split-Path -Leaf)" | |
Write-Log -Message "Setting Everyone full control on temp registry file so all users can import it" | |
$Params = @{ | |
'Path' = "$(Get-SystemTempFilePath)\$($FilePath | Split-Path -Leaf)" | |
'Identity' = 'Everyone' | |
'Right' = 'Modify'; | |
'InheritanceFlags' = 'None'; | |
'PropagationFlags' = 'NoPropagateInherit'; | |
'Type' = 'Allow'; | |
} | |
Set-MyFileSystemAcl @Params | |
Write-Log -Message "Setting registry file to import for each user" | |
## This isn't the *best* way to do this because this doesn't prevent a user from clearing out all the temp files | |
Set-AllUserStartupAction -CommandLine "reg import `"$(Get-SystemTempFilePath)\$($FilePath | Split-Path -Leaf)`"" | |
} | |
} catch { | |
Write-Log -Message "Error: $($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)" -LogLevel '3' | |
$false | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment