Public/Add-MSIXRegAccessFix.ps1
|
function Add-MSIXRegAccessFix { <# .SYNOPSIS Adds registry access fix for an expanded MSIX folder. .DESCRIPTION The Add-MSIXRegAccessFix function adds registry access fix for an expanded MSIX folder. It sets the necessary permissions on the registry keys to allow access. .PARAMETER MSIXFolder Specifies the expanded MSIX folder. This parameter is mandatory. .PARAMETER Force Indicates whether to force the script to run with administrator privileges. If not specified, the script will output an error message if it is not run as an administrator. .PARAMETER CustomScript Specifies a custom script block to be executed after setting the registry access fix. The script block is called with the parameter $TempHive, which represents the temporary registry hive. .EXAMPLE >>> The Custom script is optional! Add-MSIXRegAccessFix -MSIXFolder "C:\Path\To\MSIXFolder" -Force -CustomScript { param($TempHive) # Wrong key here. Do not use!!! $key = "HKLM:$TempHive\SOFTWARE\Policies\Adobe\Acrobat Reader\DC\FeatureLockDown" $name = "bEnableProtectedModeAppContainer" $value = 1 New-Item -Path $key -Force New-ItemProperty -Path $key -Name $name -Value $value -PropertyType DWORD -Force } } .NOTES Idea source url's for the solution: https://techcommunity.microsoft.com/t5/modern-work-app-consult-blog/packaging-adobe-reader-dc-for-avd-msix-appattach/ba-p/3572098 https://www.advancedinstaller.com/package-adobe-reader-dc-for-avd-msix-appattach.html >> someone has made a copy ;-) https://www.nick-it.de Andreas Nick, 2024 #> [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] [System.IO.DirectoryInfo] $MSIXFolder, [Switch] $Force, # For Open Reg File. Set RegKeys here. The hive is loaded in HKLM\TempHive\Software # {} [scriptblock] $CustomScript #Called with parameter $TempHive ) if (-not (Test-Path $MSIXFolder)) { throw "The specified expanded MSIX folder $($MSIXFolder.FullName) does not exist." } # Check is Admin? $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { Write-Warning "This script must be run as an administrator." } $SetACLScriptBlock = { param( [string] $MSIXFolder ) Write-Output "Folder Path : $MSIXFolder" $HiveTempName = 'TempHive'# + [GUID]::NewGuid().ToString() Start-Sleep -Seconds 2 & reg.exe load $('HKLM\' + $HiveTempName) (Join-Path $MSIXFolder -ChildPath "User.dat") Start-Sleep -Seconds 2 $everyone = New-Object System.Security.Principal.SecurityIdentifier 'S-1-1-0' $acl = Get-Acl -Path $('HKLM:\' + $HiveTempName + '\Software') $acType = [System.Security.AccessControl.AccessControlType]::Allow $regRights = [System.Security.AccessControl.RegistryRights]::FullControl $inhFlags = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit $prFlags = [System.Security.AccessControl.PropagationFlags]::None $accessRule = New-Object System.Security.AccessControl.RegistryAccessRule ($everyone, $regRights, $inhFlags, $prFlags, $acType) $acl.AddAccessRule($accessRule) Set-Acl -Path $('HKLM:\' + $HiveTempName + '\Software') -AclObject $acl Start-Sleep -Seconds 2 } $UnloadRegHive = { $HiveTempName = 'TempHive' $counter = 0 while(Test-Path('HKLM:\' + $HiveTempName)) { Write-Verbose "Unloading registry hive $($HiveTempName) trying $counter" $counter++ if ($counter -gt 10) { Write-Wrror "Could not unload the registry hive $($HiveTempName). Please remove manual" break } Start-Sleep -Seconds 3 reg.exe unload $('HKLM\' + $HiveTempName) Start-Sleep -Seconds 2 } } try { if (-not $isAdmin) { # If the script is not running with admin rights if ($PSCmdlet.MyInvocation.BoundParameters["Force"].IsPresent) { $scriptContent = $SetACLScriptBlock.ToString() $fullCommand = "& { $scriptContent } '$MSIXFolder'" # Convert the command to bytes and then to a Base64 string $bytes = [System.Text.Encoding]::Unicode.GetBytes($fullCommand) $encodedCommand = [Convert]::ToBase64String($bytes) # Start the new PowerShell instance with the encoded command Start-Process powershell.exe -ArgumentList " -encodedCommand $encodedCommand" -Verb RunAs -Wait -WindowStyle Hidden Start-Sleep -seconds 3 # Custom Script $HiveTempName = 'TempHive'# + [GUID]::NewGuid().ToString() if ($null -ne $CustomScript) { $CustomScript.Invoke($HiveTempName) } else { Write-Warning "No CustomScript defined." } Start-Sleep -seconds 3 $bytes2 = [System.Text.Encoding]::Unicode.GetBytes($UnloadRegHive) $encodedCommand2 = [Convert]::ToBase64String( $bytes2 ) Start-Process powershell.exe -ArgumentList " -encodedCommand $encodedCommand2" -Verb RunAs -Wait -WindowStyle Hidden } else { # Otherwise, output an error message Write-Error "This script must be run as an administrator. Please re-run as Administrator or with -Force to elevate privileges." exit 1 } } else { $scriptContent = $SetACLScriptBlock.ToString() $fullCommand = "& { $scriptContent } '$MSIXFolder'" # Convert the command to bytes and then to a Base64 string $bytes = [System.Text.Encoding]::Unicode.GetBytes($fullCommand) $encodedCommand = [Convert]::ToBase64String($bytes) Start-Process powershell.exe -ArgumentList " -encodedCommand $encodedCommand" -Wait -WindowStyle Hidden # Custom Script $HiveTempName = 'TempHive'# + [GUID]::NewGuid().ToString() if ($null -ne $CustomScript) { $CustomScript.Invoke($HiveTempName) } else { Write-Warning "No CustomScript defined." } Start-Sleep -seconds 2 $bytes2 = [System.Text.Encoding]::Unicode.GetBytes($UnloadRegHive) $encodedCommand2 = [Convert]::ToBase64String( $bytes2 ) Start-Process powershell.exe -ArgumentList " -encodedCommand $encodedCommand2" -Wait -WindowStyle Hidden } } catch { Write-Verbose "Error change virtual registry key permission." Write-Error $_.Exception.Message } finally { # Der Hive kann irgendwie nur über einen andren Prozess entladen werden! } } |