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

Sa 3041 retain default app protocol associations #105

Merged
merged 72 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from 71 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
4ec5794
pta/fta functions
kmaranionjc Dec 22, 2023
aada1a7
Added fta/pta
kmaranionjc Jan 11, 2024
c901d10
uwp
kmaranionjc Jan 16, 2024
8afefd6
Added load/unload error check
kmaranionjc Jan 23, 2024
877b466
Version
kmaranionjc Jan 23, 2024
584b16f
test matrix
kmaranionjc Jan 23, 2024
b99b661
name fix
kmaranionjc Jan 24, 2024
4fc92c4
Load before pta/fta
kmaranionjc Jan 24, 2024
2ace2cf
test
kmaranionjc Jan 24, 2024
5233449
form
kmaranionjc Jan 24, 2024
66a4bdb
test
kmaranionjc Jan 24, 2024
678e7d2
long path test
kmaranionjc Jan 24, 2024
8e4bda2
test
kmaranionjc Jan 24, 2024
60c9dcf
test
kmaranionjc Jan 24, 2024
c0ccec2
test
kmaranionjc Jan 24, 2024
0f50fdd
test
kmaranionjc Jan 25, 2024
2984f4a
test
kmaranionjc Jan 25, 2024
2420832
test association
kmaranionjc Jan 25, 2024
f0341fd
test
kmaranionjc Jan 25, 2024
c3d7269
test
kmaranionjc Jan 25, 2024
5714f0d
test
kmaranionjc Jan 25, 2024
59b27ab
cleanup
kmaranionjc Jan 26, 2024
b6f327a
UWP progress
kmaranionjc Jan 29, 2024
748589d
added tests and fixed get functions
kmaranionjc Jan 29, 2024
7025d39
appx validation
kmaranionjc Jan 29, 2024
8bab40f
test
kmaranionjc Jan 30, 2024
2ff8978
test
kmaranionjc Jan 30, 2024
b4b77d2
sid test
kmaranionjc Jan 30, 2024
165cec7
test
kmaranionjc Jan 30, 2024
e2b2c52
cleanup + test
kmaranionjc Jan 30, 2024
830e0bb
test
kmaranionjc Jan 30, 2024
a64613c
test
kmaranionjc Jan 31, 2024
ce036d5
test
kmaranionjc Jan 31, 2024
50940cd
test
kmaranionjc Jan 31, 2024
962dc92
test
kmaranionjc Jan 31, 2024
b05da38
test
kmaranionjc Jan 31, 2024
4ffd7d2
test
kmaranionjc Jan 31, 2024
86fb10c
GC
kmaranionjc Jan 31, 2024
8355325
gc test
kmaranionjc Jan 31, 2024
131db86
unload
kmaranionjc Jan 31, 2024
5ccffa4
gc
kmaranionjc Jan 31, 2024
5e00f52
test
kmaranionjc Feb 1, 2024
3cf9460
functions test
kmaranionjc Feb 1, 2024
f4c73b0
test
kmaranionjc Feb 1, 2024
1abd9b3
fix csv
kmaranionjc Feb 1, 2024
49c543a
fta
kmaranionjc Feb 1, 2024
61f8d44
functions
kmaranionjc Feb 1, 2024
f086f51
testtest
kmaranionjc Feb 1, 2024
a8c20af
test
kmaranionjc Feb 1, 2024
22826e9
test
kmaranionjc Feb 1, 2024
09ea933
uncomment tests
kmaranionjc Feb 5, 2024
a9a6fbe
fta/pta to csv
kmaranionjc Feb 6, 2024
bd791b2
fix
kmaranionjc Feb 6, 2024
b01c5d0
test
kmaranionjc Feb 6, 2024
c5781fd
test
kmaranionjc Feb 6, 2024
d78d9aa
test
kmaranionjc Feb 6, 2024
3fb8f3a
test
kmaranionjc Feb 6, 2024
2ba62a4
test
kmaranionjc Feb 6, 2024
75e94de
test
kmaranionjc Feb 6, 2024
5ca27df
test
kmaranionjc Feb 6, 2024
e3b15eb
path
kmaranionjc Feb 6, 2024
6f5757c
path
kmaranionjc Feb 6, 2024
f639538
path change
kmaranionjc Feb 6, 2024
2e2f6b8
path
kmaranionjc Feb 6, 2024
563e049
test
kmaranionjc Feb 6, 2024
675069c
cleanup
kmaranionjc Feb 6, 2024
65af2da
test
kmaranionjc Feb 7, 2024
2a237d5
Update ModuleChangelog.md
jworkmanjc Feb 7, 2024
1872c2e
Update ModuleChangelog.md
jworkmanjc Feb 7, 2024
3ef8cd7
cleanup [skip ci]
kmaranionjc Feb 7, 2024
c6bd06d
module changelog date [skip ci]
kmaranionjc Feb 7, 2024
d05a9c8
changelog date [skip ci]
kmaranionjc Feb 7, 2024
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
Binary file modified Deploy/uwp_jcadmu.ps1
kmaranionjc marked this conversation as resolved.
Show resolved Hide resolved
Binary file not shown.
15 changes: 15 additions & 0 deletions ModuleChangelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
## 2.6.0

Release Date: February 8, 2024

#### RELEASE NOTES

```
* Added a feature to migrate default applications (file associations) and protocol associations
```

#### Bug Fixes:
```
* Addressed a issue where a registry hive fails to load, the tool will now halt migration instead of continuing
* Fixed a bug with Module Changelog version test where release type number is not properly outputted
```
## 2.5.1

Release Date: December 18, 2023
Expand Down
2 changes: 1 addition & 1 deletion jumpcloud-ADMU/JumpCloud.ADMU.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
RootModule = 'JumpCloud.ADMU.psm1'

# Version number of this module.
ModuleVersion = '2.5.1'
ModuleVersion = '2.6.0'

# Supported PSEditions
# CompatiblePSEditions = @()
Expand Down
2 changes: 1 addition & 1 deletion jumpcloud-ADMU/Powershell/Form.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ function show-mtpSelection {
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="JumpCloud ADMU 2.5.1"
Title="JumpCloud ADMU 2.6.0"
WindowStyle="SingleBorderWindow"
ResizeMode="NoResize"
Background="White" ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Visible" Width="1000" Height="520">
Expand Down
181 changes: 165 additions & 16 deletions jumpcloud-ADMU/Powershell/Start-Migration.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -401,23 +401,39 @@ function Set-UserRegistryLoadState {
[ValidatePattern("^S-\d-\d+-(\d+-){1,14}\d+$")]
[System.String]$UserSid
)
Begin {
$regQuery = REG QUERY HKU *>&1
}
process {
switch ($op) {
"Load" {

# Current loaded profiles before loading NTUSER.DAT.BAK and USRClass.dat.bak
Write-ToLog -Message:('Current Loaded Profiles Before Loading: ' + $regQuery)

Start-Sleep -Seconds 1
$lastModified = Get-Item -path "$ProfilePath\NTUSER.DAT.BAK" -Force | Select-Object -ExpandProperty LastWriteTime
Write-ToLog -Message:("Last Modified Time of $ProfilePath\NTUSER.DAT.BAK is $lastModified")
$results = REG LOAD HKU\$($UserSid)_admu "$ProfilePath\NTUSER.DAT.BAK" *>&1
# Get the last modified time of the NTUSER.DAT.BAK file
if ($?) {
Write-ToLog -Message:('Load Profile: ' + "$ProfilePath\NTUSER.DAT.BAK")
} else {
Write-ToLog -Message:('Could not load profile: ' + "$ProfilePath\NTUSER.DAT.BAK")
Throw "Could not load profile: $ProfilePath\NTUSER.DAT.BAK"
}

Start-Sleep -Seconds 1
$lastModified = Get-Item -path "$ProfilePath\AppData\Local\Microsoft\Windows\UsrClass.dat.bak" -Force | Select-Object -ExpandProperty LastWriteTime
Write-ToLog -Message:("Last Modified Time of $ProfilePath\AppData\Local\Microsoft\Windows\UsrClass.dat.bak is $lastModified")
$results = REG LOAD HKU\"$($UserSid)_Classes_admu" "$ProfilePath\AppData\Local\Microsoft\Windows\UsrClass.dat.bak" *>&1
# Get the last modified time of the USRClass.dat.bak file
if ($?) {
Write-ToLog -Message:('Load Profile: ' + "$ProfilePath\AppData\Local\Microsoft\Windows\UsrClass.dat.bak")
} else {
Write-ToLog -Message:('Could not load profile: ' + "$ProfilePath\AppData\Local\Microsoft\Windows\UsrClass.dat.bak")
Throw "Could not load profile: $ProfilePath\AppData\Local\Microsoft\Windows\UsrClass.dat.bak"
}


}
"Unload" {
[gc]::collect()
Expand Down Expand Up @@ -456,39 +472,42 @@ Function Test-UserRegistryLoadState {
# Tests to check that the reg items are not loaded
If ($results -match $UserSid) {
Write-ToLog "REG Keys are loaded, attempting to unload"
Set-UserRegistryLoadState -op "Unload" -ProfilePath $ProfilePath -UserSid $UserSid
try {
Set-UserRegistryLoadState -op "Unload" -ProfilePath $ProfilePath -UserSid $UserSid
}
catch {
Throw "Could Not Unload User Registry During Test-UserRegistryLoadState Unload Process"
}
}
}
process {
# Load New User Profile Registry Keys
try {
Set-UserRegistryLoadState -op "Load" -ProfilePath $ProfilePath -UserSid $UserSid
} catch {
Write-Error "Could Not Load"
Throw "Could Not Load User Registry During Test-UserRegistryLoadState Load Process"
}
# Load Selected User Profile Keys
# Unload "Selected" and "NewUser"
try {
Set-UserRegistryLoadState -op "Unload" -ProfilePath $ProfilePath -UserSid $UserSid
} catch {
Write-Error "Could Not Unload"
Write-Error "Could Not Unload User Registry During Test-UserRegistryLoadState Unload Process"
}
}
end {
$results = REG QUERY HKU *>&1
# Tests to check that the reg items are not loaded
If ($results -match $UserSid) {
Write-ToLog "REG Keys are loaded, attempting to unload"
Set-UserRegistryLoadState -op "Unload" -ProfilePath $ProfilePath -UserSid $UserSid
}
$results = REG QUERY HKU *>&1
# Tests to check that the reg items are not loaded
If ($results -match $UserSid) {
Write-ToLog "REG Keys are loaded at the end of testing, exiting..." -level Warn
throw "REG Keys are loaded at the end of testing, exiting..."
try {
Set-UserRegistryLoadState -op "Unload" -ProfilePath $ProfilePath -UserSid $UserSid
}
catch {
throw "Registry Keys are still loaded after Test-UserRegistryLoadState Testing Exiting..."
}
}
}

}


Expand Down Expand Up @@ -1368,6 +1387,85 @@ function Set-ADMUScheduledTask {
}
}
#endregion Agent Install Helper Functions


##### MIT License #####
# MIT License

# Copyright © 2022, Danysys
# Modified by JumpCloud

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# Get user file type associations
function Get-UserFileTypeAssociation {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, HelpMessage = 'The SID of the user to capture file type associations')]
[System.String]
$UserSid
)
$manifestList = @()
# Test path for file type associations
$pathRoot = "HKEY_USERS:\$($UserSid)_admu\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\"
if (Test-Path $pathRoot) {
$exts = Get-ChildItem $pathRoot*
foreach ($ext in $exts) {
$indivExtension = $ext.PSChildName
$progId = (Get-ItemProperty "$($pathRoot)\$indivExtension\UserChoice" -ErrorAction SilentlyContinue).ProgId
$manifestList += [PSCustomObject]@{
extension = $indivExtension
programId = $progId
}
}
}
return $manifestList
}

# Get user protocol associations

function Get-ProtocolTypeAssociation{
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, HelpMessage = 'The SID of the user to capture file type associations')]
[System.String]
$UserSid
)
$manifestList = @()

$pathRoot = "HKEY_USERS:\$($UserSid)_admu\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\"
if (Test-Path $pathRoot) {
Get-ChildItem $pathRoot* |
ForEach-Object {

$progId = (Get-ItemProperty "$($_.PSParentPath)\$($_.PSChildName)\UserChoice" -ErrorAction SilentlyContinue).ProgId
if ($progId) {
$manifestList += [PSCustomObject]@{
extension = $_.PSChildName
programId = $progId
}
}
}
}
return $manifestList
}
##### END MIT License #####

Function Start-Migration {
[CmdletBinding(HelpURI = "https://github.com/TheJumpCloud/jumpcloud-ADMU/wiki/Start-Migration")]
Param (
Expand All @@ -1389,7 +1487,7 @@ Function Start-Migration {
Begin {
Write-ToLog -Message:('####################################' + (get-date -format "dd-MMM-yyyy HH:mm") + '####################################')
# Start script
$admuVersion = '2.5.1'
$admuVersion = '2.6.0'
Write-ToLog -Message:('Running ADMU: ' + 'v' + $admuVersion)
Write-ToLog -Message:('Script starting; Log file location: ' + $jcAdmuLogFile)
Write-ToLog -Message:('Gathering system & profile information')
Expand Down Expand Up @@ -1641,7 +1739,7 @@ Function Start-Migration {
Test-UserRegistryLoadState -ProfilePath $newUserProfileImagePath -UserSid $newUserSid
Test-UserRegistryLoadState -ProfilePath $oldUserProfileImagePath -UserSid $SelectedUserSID
} catch {
Write-ToLog -Message:('could not load and unload registry of migration user, exiting') -level Warn
Write-ToLog -Message:('Could not load and unload registry of migration user during Test-UserRegistryLoadState, exiting') -level Warn
$admuTracker.testRegLoadUnload.fail = $true
break
}
Expand Down Expand Up @@ -1729,7 +1827,7 @@ Function Start-Migration {
break
}
# Validate file permissions on registry item
if ((Get-psdrive | select-object name) -notmatch "HKEY_USERS") {
if ("HKEY_USERS" -notin (Get-psdrive | select-object name).Name) {
Write-ToLog "Mounting HKEY_USERS to check USER UWP keys"
New-PSDrive -Name:("HKEY_USERS") -PSProvider:("Registry") -Root:("HKEY_USERS")
}
Expand Down Expand Up @@ -1783,8 +1881,31 @@ Function Start-Migration {
Set-ValueToKey -registryRoot Users -keyPath "$($newusersid)_admu\SOFTWARE\JCADMU" -Name "previousProfilePath" -value "$oldUserProfileImagePath" -regValueKind String
}
### End reg key check for new user
$path = $oldUserProfileImagePath + '\AppData\Local\JumpCloudADMU'
If (!(test-path $path)) {
New-Item -ItemType Directory -Force -Path $path
}

# SelectedUserSid
# Validate file permissions on registry item
if ("HKEY_USERS" -notin (Get-psdrive | select-object name).Name) {
Write-ToLog "Mounting HKEY_USERS to check USER UWP keys"
New-PSDrive -Name:("HKEY_USERS") -PSProvider:("Registry") -Root:("HKEY_USERS")
}


$fileTypeAssociations = Get-UserFileTypeAssociation -UserSid $SelectedUserSid
Write-ToLog -Message:('Found ' + $fileTypeAssociations.count + ' File Type Associations')
$fileTypeAssociations | Export-Csv -Path "$path\fileTypeAssociations.csv" -NoTypeInformation -Force

$protocolTypeAssociations = Get-ProtocolTypeAssociation -UserSid $SelectedUserSid
Write-ToLog -Message:('Found ' + $protocolTypeAssociations.count + ' Protocol Type Associations')
$protocolTypeAssociations | Export-Csv -Path "$path\protocolTypeAssociations.csv" -NoTypeInformation -Force


$regQuery = REG QUERY HKU *>&1
# Unload "Selected" and "NewUser"
Write-ToLog -Message:('Loaded profiles before unloading: ' + $regQuery)
Set-UserRegistryLoadState -op "Unload" -ProfilePath $newUserProfileImagePath -UserSid $NewUserSID
Set-UserRegistryLoadState -op "Unload" -ProfilePath $oldUserProfileImagePath -UserSid $SelectedUserSID

Expand All @@ -1807,6 +1928,30 @@ Function Start-Migration {
try {
Rename-Item -Path "$oldUserProfileImagePath\NTUSER.DAT" -NewName "$oldUserProfileImagePath\NTUSER_original_$renameDate.DAT" -Force -ErrorAction Stop
Rename-Item -Path "$oldUserProfileImagePath\AppData\Local\Microsoft\Windows\UsrClass.dat" -NewName "$oldUserProfileImagePath\AppData\Local\Microsoft\Windows\UsrClass_original_$renameDate.dat" -Force -ErrorAction Stop

# Validate the file have timestamps
$ntuserOriginal = Get-Item "$oldUserProfileImagePath\NTUSER_original_$renameDate.DAT" -Force
$usrClassOriginal = Get-Item "$oldUserProfileImagePath\AppData\Local\Microsoft\Windows\UsrClass_original_$renameDate.dat" -Force

# Get the name of the file
$ntuserOriginalName = $ntuserOriginal.Name
$usrClassOriginalName = $usrClassOriginal.Name

if ($ntuserOriginalName -match "ntuser_original_$($renameDate).DAT") {
Write-ToLog -Message:("Successfully renamed $ntuserOriginalName with timestamp $renameDate")
} else {
Write-ToLog -Message:("Failed to rename $ntuserOriginalName with timestamp $renameDate")
$admuTracker.renameOriginalFiles.fail = $true
break
}

if ($usrClassOriginalName -match "UsrClass_original_$($renameDate).dat") {
Write-ToLog -Message:("Successfully renamed $usrClassOriginalName with timestamp $renameDate")
} else {
Write-ToLog -Message:("Failed to rename $usrClassOriginalName with timestamp $renameDate")
$admuTracker.renameOriginalFiles.fail = $true
break
}
} catch {
Write-ToLog -Message("Could not rename original registry files for backup purposes: Exiting...")
Write-ToLog -Message($_.Exception.Message)
Expand All @@ -1819,6 +1964,9 @@ Function Start-Migration {
try {
Rename-Item -Path "$oldUserProfileImagePath\NTUSER.DAT.BAK" -NewName "$oldUserProfileImagePath\NTUSER.DAT" -Force -ErrorAction Stop
Rename-Item -Path "$oldUserProfileImagePath\AppData\Local\Microsoft\Windows\UsrClass.dat.bak" -NewName "$oldUserProfileImagePath\AppData\Local\Microsoft\Windows\UsrClass.dat" -Force -ErrorAction Stop



} catch {
Write-ToLog -Message("Could not rename backup registry files to a system recognizable name: Exiting...")
Write-ToLog -Message($_.Exception.Message)
Expand Down Expand Up @@ -1966,6 +2114,7 @@ Function Start-Migration {

Write-ToLog -Message:('Updating UWP Apps for new user')
$newUserProfileImagePath = Get-ItemPropertyValue -Path ('HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\' + $newusersid) -Name 'ProfileImagePath'

$path = $newUserProfileImagePath + '\AppData\Local\JumpCloudADMU'
If (!(test-path $path)) {
New-Item -ItemType Directory -Force -Path $path
Expand Down
5 changes: 4 additions & 1 deletion jumpcloud-ADMU/Powershell/Tests/Build.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,12 @@ Describe "Module Validation Tests" {
It 'Module Changlog Version should be correct' {
$ModuleChangelogVersionRegex = "([0-9]+)\.([0-9]+)\.([0-9]+)"
$ModuleChangelogVersionMatch = ($ModuleChangelogContent | Select-Object -First 1) | Select-String -Pattern:($ModuleChangelogVersionRegex)
Write-Host "Module Changelog Content: $ModuleChangelogVersionMatch"
$ModuleChangelogVersion = $ModuleChangelogVersionMatch.Matches.Value
Write-Host "Module Changelog Version: $ModuleChangelogVersion"
# Compare
([version]$ModuleChangelogVersion).$($env:ModuleVersionType) | Should -Be ($lastestModule.version.$($env:ModuleVersionType) + 1)
$latestVersion = [version]$lastestModule.version
([version]$ModuleChangelogVersion).$($env:ModuleVersionType) | Should -Be ($latestVersion.$($env:ModuleVersionType) + 1)

}
It 'Module Changelog should not contain placeholder values' {
Expand Down
23 changes: 23 additions & 0 deletions jumpcloud-ADMU/Powershell/Tests/Functions.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,29 @@ Describe 'Functions' {
Test-RegistryValueMatch -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' -Value 'Public' -stringmatch 'Private' | Should -Be $false
}
}
Context 'Set-PTA/FTA Test'{
BeforeAll{
# Import /Deploy/uwp_jcadmu.ps1 and use the function Set-FTA
. $PSScriptRoot\..\..\..\Deploy\uwp_jcadmu.ps1
}
It 'Set-FTA should be changed after migration'{
$protocol = "http"
$fileType = ".txt"

Set-FTA "wordpad" $fileType
Set-PTA -ProgId "notepad" -Protocol $protocol

$fta = Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$($fileType)\UserChoice"
jworkmanjc marked this conversation as resolved.
Show resolved Hide resolved
$pta = Get-ItemProperty "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\$($protocol)\UserChoice"
jworkmanjc marked this conversation as resolved.
Show resolved Hide resolved
# Write out the contents of the FTA and PTA
Write-Host "FTA: $($fta)"
Write-Host "PTA: $($pta)"
# Check if programId is wordpad
$fta.ProgId | Should -Contain "wordpad"
$pta.ProgId | Should -Contain "notepad"

}
}
Context 'Test-JumpCloudUsername Function' {
It 'Valid Username Returns True' {
# Get the first user
Expand Down
Loading