If the access token privilege granting or the actual functions for removal? The Access Token privileges use a C# .NET framework method that the function creates into a usable object via a wrapper to Grant/Revoke privileges during the process block of the function. The full function to do it is quite lengthy but I'll give you an idea. Spoiler Code: Function Remove-Components { [CmdletBinding()] Param () Begin { $SecHealthArray = @( "SenseClient-Package" "Defender" ) $ErrorActionPreference = 'SilentlyContinue' $PackageList = [System.Collections.ArrayList]@() $MountPath = (Get-WindowsImage -Mounted).Path $ParentKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages" $PackageKey = $ParentKey.Substring(6) $Desktop = [Environment]::GetFolderPath("Desktop") $QueryRegistry = REG QUERY HKLM | FindStr 'AppData' If ($QueryRegistry -like "*AppData*") { [gc]::Collect() [void]($QueryRegistry.ForEach({ REG UNLOAD $_ })) } } Process { $GetPackages = { (Get-ChildItem -Path $ParentKey).Name.Split('\') | Select-String -Pattern '~' -SimpleMatch | Out-File $Desktop\OriginalPackageList.txt -Force ForEach ($Object in $SecHealthArray) { $Packages = (Get-ChildItem $ParentKey | ? Name -Like "*$Object*") If ($Packages -ne $null) { Write-Verbose "Processing all component packages containing $Object" -Verbose ForEach ($Package in $Packages) { $PackageName = $Package.Name.Split('\')[-1] $ComponentKey = "$PackageKey\$PackageName" Grant-RegistryAccess -Hive HKLM -SubKey $ComponentKey <--Where I access token privileges for system-level elevation is granted, then it's immediately revoked once the key's ownership has been successfully granted. Moreover, it backs up the original ACL and restores it upon removal to ensure no broken SIDs or the like are left on parent-keys or any hives. If (Test-Path "$($ParentKey)\$($PackageName)") { [void]($PackageList.Add($PackageName)) } [void](Set-ItemProperty -Path "$($ParentKey)\$($PackageName)" -Name "Visibility" -Value 1 -Force) [void](New-ItemProperty -Path "$($ParentKey)\$($PackageName)" -Name "DefVis" -PropertyType DWord -Value 2 -Force) [void](Remove-Item -Path "$($ParentKey)\$($PackageName)\Owners" -Force) } } } } That's just a tweaked snippit of proper component removal, though I did not include the changing of the XML permanency values from "Permanent" to "Removale," though that is not required. With this I use my Grant-RegistryAccess cmdlet I posted earlier in here as well as my Grant-Ownership/Grant-Permissions cmdlets that also use Access Token privileges to grant the current process system-level access in order to ensure all directories and key can be recursively removed and/or modified. An example of the simple granting of an access token privilege, here's a very lite portion of how it's done: Code: Add-Type @" using System; namespace PRIVILEGES_LSA { using System.Runtime.InteropServices; using System.Security; using System.Management; using System.Runtime.CompilerServices; using System.ComponentModel; using LSA_HANDLE = IntPtr; public enum AccessTokens { SeAssignPrimaryTokenPrivilege, // Replace a process-level token. SeAuditPrivilege, // Generate security audits. SeBackupPrivilege, // Back up files and directories. SeChangeNotifyPrivilege, // Bypass traverse checking. SeCreateGlobalPrivilege, // Create global objects. SeCreatePagefilePrivilege, // Create a pagefile. SeCreatePermanentPrivilege, // Create permanent shared objects. SeCreateSymbolicLinkPrivilege, // Create symbolic links. SeCreateTokenPrivilege, // Create a token object. SeDebugPrivilege, // Debug programs. SeEnableDelegationPrivilege, // Enable computer and user accounts to be trusted for delegation. SeImpersonatePrivilege, // Impersonate a client after authentication. SeIncreaseBasePriorityPrivilege, // Increase scheduling priority. SeIncreaseQuotaPrivilege, // Adjust memory quotas for a process. SeIncreaseWorkingSetPrivilege, // Increase a process working set. SeLoadDriverPrivilege, // Load and unload device drivers. SeLockMemoryPrivilege, // Lock pages in memory. SeMachineAccountPrivilege, // Add workstations to domain. SeManageVolumePrivilege, // Perform volume maintenance tasks. SeProfileSingleProcessPrivilege, // Profile single process. SeRelabelPrivilege, // Modify an object label. SeRemoteShutdownPrivilege, // Force shutdown from a remote system. SeRestorePrivilege, // Restore files and directories. SeSecurityPrivilege, // Manage auditing and security log. SeShutdownPrivilege, // Shut down the system. SeSyncAgentPrivilege, // Synchronize directory service data. SeSystemEnvironmentPrivilege, // Modify firmware environment values. SeSystemProfilePrivilege, // Profile system performance. SeSystemtimePrivilege, // Change the system time. SeTakeOwnershipPrivilege, // Take ownership of files or other objects. SeTcbPrivilege, // Act as part of the operating system. SeTimeZonePrivilege, // Change the time zone. SeTrustedCredManAccessPrivilege, // Access Credential Manager as a trusted caller. SeUndockPrivilege, // Remove computer from docking station. SeUnsolicitedInputPrivilege // Read unsolicited input from a terminal device. } internal sealed class Win32Token { [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen); [DllImport("kernel32.dll", ExactSpelling = true)] internal static extern IntPtr GetCurrentProcess(); [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok); [DllImport("advapi32.dll", SetLastError = true)] internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid); [DllImport("kernel32.dll", ExactSpelling = true)] internal static extern bool CloseHandle(IntPtr phtok); } **Continuing to the how you want the method to work to your liking** In this little bit of C# code I use a Win32 wrapper within the main wrapper, as the Win32 wrapper allows me to add the actual classes as PowerShell input objects that then I can issue such commands as .NET Framework strings instead of having to actually use the function's command, hence why you can see me using :[PRIVILEGES_LSA.TokenAdjustor]::GrantPrivilege/RevokePrivilege(Privilege(s)) as opposed to Grant-Privilege -Privilege "Privilege(s)" It's much faster that way and bypasses PowerShell having to repeatedly recreate the object since it's already been set as part of the system itself until the full process has completed (hence why I use Begin/Process/End code-blocks in functions). Moreover, it allows you to use said Framework strings across any script/function (if you create the actual privilege granting as a module) so you do not have to include it in every script. And how I grant access at the beginning, before the process begins, and then it's automatically revoked at the end, to ensure no privileges stay enabled. This is a fairly basic function that uses said privileges, and automatically climbs the path's directory chain to make sure all items' access control and ownership are granted consistently and recursively. Lastly the BackupPrivilege allows me to save the access control permissions before they're modified to a file, so they can be restored at the end, too, to ensure no broken SIDs are left and OEM access permissions are set to their default settings. Spoiler Code: Function Grant-AccessPermissions { <# .SYNOPSIS Grants file and folder access control permissions. .DESCRIPTION Grants system-level file and folder access by enabling access token process privileges. .PARAMETER Path The path to the file or folder access is to be granted to. .PARAMETER Account The account name that will be granted access. .PARAMETER Recurse Allows for access control permissions to be recursively granted on directories and subdirectories. .EXAMPLE PS C:\> Grant-AccessPermissions -Path 'File' .EXAMPLE PS C:\> Grant-AccessPermissions -Path 'Folder' -Recurse .EXAMPLE PS C:\> Grant-AccessPermissions -Path 'File' -Account 'DomainName\DomainAccount' .EXAMPLE PS C:\> $Path = "C:\Mount\Users\Default\ProgramData" PS C:\> Get-ChildItem -Path $Path -Recurse -Force | Grant-AccessPermissions #> [CmdletBinding()] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = 'The path to the file or folder to take ownership of.')][ValidateScript({ If (Test-Path -Path $_) { $_ } Else { Throw "$_ is not a valid path." } })][Alias('FullName')][string]$Path, [Parameter(HelpMessage = 'The name of the account that will be granted ownership.')][Alias('User')][string]$Account = "Administrators", [Parameter(HelpMessage = 'Enables recursive ownership granting of directories and folders.')][switch]$Recurse ) Begin { [PRIVILEGES_LSA.TokenAdjustor]::GrantPrivilege("SeRestorePrivilege") [PRIVILEGES_LSA.TokenAdjustor]::GrantPrivilege("SeBackupPrivilege") [PRIVILEGES_LSA.TokenAdjustor]::GrantPrivilege("SeTakeOwnershipPrivilege") } Process { ForEach ($File in $Path) { Write-Verbose "Processing: $File" $DirOwner = New-Object System.Security.AccessControl.DirectorySecurity $DirOwner.SetOwner([System.Security.Principal.NTAccount]$Account) $FileOwner = New-Object System.Security.AccessControl.FileSecurity $FileOwner.SetOwner([System.Security.Principal.NTAccount]$Account) $DirACL = New-Object System.Security.AccessControl.DirectorySecurity $FileACL = New-Object System.Security.AccessControl.DirectorySecurity $Rule = New-Object System.Security.AccessControl.FileSystemAccessRule("Administrators", "FullControl", "ContainerInherit,ObjectInherit", "InheritOnly", "Allow") $FileACL.AddAccessRule($Rule) $DirACL.AddAccessRule($Rule) Try { $File = Get-Item -LiteralPath $File -Force -ErrorAction Stop If (!($File.PSIsContainer)) { Try { $File.SetAccessControl($FileOwner) } Catch { Write-Warning "Failed to grant full permissions on $($File.FullName). Attempting to grant full permissions on $($File.Directory.FullName)." $File.Directory.SetAccessControl($FileACL) $File.SetAccessControl($FileOwner) } } Else { Try { $File.SetAccessControl($DirOwner) } Catch { Write-Warning "Failed to grant full directory permissions on $($File.FullName). Attempting to grant full directory permissions on $($File.Parent.FullName)." $File.Parent.SetAccessControl($DirACL) $File.SetAccessControl($DirOwner) } If ($Recurse) { Get-ChildItem $File -Force | Grant-AccessPermissions } } } Catch { Write-Warning "$($File): $($_.Exception.Message)" } } } End { [PRIVILEGES_LSA.TokenAdjustor]::RevokePrivilege("SeRestorePrivilege") [PRIVILEGES_LSA.TokenAdjustor]::RevokePrivilege("SeBackupPrivilege") [PRIVILEGES_LSA.TokenAdjustor]::RevokePrivilege("SeTakeOwnershipPrivilege") } } Next to Privileges you have actual User Rights you can change the same way, but those you need to be very careful with because those are primarily used to interact with hardware on a system, as it's how you can customize your BIOS from within Windows and without even booting into it (so long as the manufacturer/board brand has a namespace it assigns to the system, and most do). With User Rights you can log in as a process, remove the built-in administrator, etc.
Could you guys please go to another topic with the NTLite talk it's been said before this is MSMG Toolkit topic keep it clean pls
Also that component removal function does all of its directory and registry/Symbolic Link and Hard-Link removals after all the components have been removed (I did not include that, for the sake of keeping it fairly short but to the point in how you'd go about doing it).
But on that note, truly if you want any further info or detail, just PM me like others do. That's the last of the stuff I'll post regarding that in here because this is not my thread and no one likes hijackers.
@GodHand Thank you very much. I thought it was something simpler and maybe it could be incorporated into the MSMG project. Anyway thank you and any further questions I will send MP.
Nothing wrong with the word @AeonX but It's as @GodHand stated it's has no purpose to hijack this tread with a "commercial" program if MSMG Toolkit is putting all his effort in a nice tool for free ! I find that rude TBH
Get off your pedestal. First off I was answering questions regarding how I go about doing something. If you have a problem, report me to a real moderator instead of pretending you're one while also quite ironically hijacking the thread further with your drivel.
Stripped out 1709 16299.125 Pro version removed all apps and windows components and only leave store and defender works like a charm after inplace upgrade.
Hi, Could anyone please remind me the full path of the activation tokens on my installed OS ? Need to copy them to the new Iso. Thanks.
^^ open services.msc and close Windows Update service after re-open service again restart PC to see if now WU works;still I don't know what you remove when working with Toolkit so is very hard to tell something ok, well when I start working with MSMG Toolkit first I only remove applications desired and not integrate nothing for example .netFX35, DirectX 9.0C, Windows Updates etc... to avoid mistakes then try works first for stages until you get more knowledge and reliance and principaly read all pages of MSMG Toolkit and take note of all important actions before make some modified ISO without know what you are doing because as result is only waste of time IMO
Do you use antivirus? Have you set up telemetry as Security? https://forums.mydigitallife.net/threads/windows-10-hotfix-repository.57050/page-258#post-1403394