1. Windows 10 User

    Windows 10 User MDL Guru

    Feb 2, 2017
    2,005
    122
    90
    Ok.
     
  2. GodHand

    GodHand MDL Addicted

    Jul 15, 2016
    534
    926
    30
    ISO/WIM to UUP working.

    Anyone who wants to know the working parameters, knock yourself out.

    Code:
    [DllImport("Wimgapi.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "CreateUUP")]
    internal static extern IntPtr GetCurrentProcess();
    if (MarshalAs(UnmanagedType.Bool)); throw ex;
    CreateUUP(
        [In, MarshalAs(UnmanagedType.WIMStr)] string WimFile,
        [In]    UUPCreateDesiredAccess DesiredAccess,
        [In]    UUPCompressionType CompressionType,
        [Out, Optional] out UUPCreationResult CreationResult
    );
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  3. Enthousiast

    Enthousiast MDL Tester

    Oct 30, 2009
    49,712
    103,719
    450
    Why would we want to create UUP files from iso/wim, and why is this in the MSMG thread?
     
  4. Tito

    Tito Super Mod / Adviser
    Staff Member

    Nov 30, 2009
    18,826
    19,045
    340
    @GodHand

    It would be better if you create a new thread in Coding Life sub-forum, cause the discussions are going to deviate too much from the original topic.
     
  5. Windows 10 User

    Windows 10 User MDL Guru

    Feb 2, 2017
    2,005
    122
    90
    Is it possible to remove the Snipping Tool with MSMG ToolKit?
     
  6. Super Spartan

    Super Spartan MDL Expert

    May 30, 2014
    1,740
    1,010
    60
    No
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  7. Windows 10 User

    Windows 10 User MDL Guru

    Feb 2, 2017
    2,005
    122
    90
    Ok.
     
  8. GodHand

    GodHand MDL Addicted

    Jul 15, 2016
    534
    926
    30
    I'm well aware, but at the time I was entertained at the presumption a handful of people had in that things require an array of 3rd party tools when, in fact, significantly more can be done with no 3rd party tools and a little patience.

    But in any case, it won't too long before I post the primary PShell project for offline optimizing on GitHub and PowerShellGet, and likewise, release it on here. And yeah I will make its own thread for it. I appreciate the cordial response, in any case.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  9. GodHand

    GodHand MDL Addicted

    Jul 15, 2016
    534
    926
    30
    #5749 GodHand, Jan 30, 2018
    Last edited: Jan 30, 2018
    There is no need to remove Snipping Tool from the image when you can completely disable it system-wide via Group Policy:

    Click Start,
    type gpedit.msc,
    open Local Group Policy
    Navigate to Computer Configuration->Administrative Templates->Windows Components->Tablet PC->Accessories
    double click "Do not allow Snipping Tool to run."
    Select "Enabled"
    Click "OK."

    You can also do it by editing its specific offline registry hive subkey, removing the link from its default directory and removing the Desktop.ini string associated with said .lnk in ProgramData > > > Accessories

    Code:
    If (Test-Path -Path "$Mount\ProgramData\Microsoft\Windows\Start Menu\Programs\Accessories\Snipping Tool.lnk") { Remove-Item -Path "$Mount\ProgramData\Microsoft\Windows\Start Menu\Programs\Accessories\Snipping Tool.lnk" -Force } #Test if the Link exists, and remove it if so.
    Else { Break } # If it does not exist, the code-block breaks and does not proceed.
    $LnkINI = "$Mount\ProgramData\Microsoft\Windows\Start Menu\Programs\Accessories\desktop.ini" # Assign the Desktop.ini to a variable.
    $SnippingLnk = "Snipping Tool.lnk=@%SystemRoot%\system32\SnippingTool.exe,-15051" # Assign the string you want to remove to a variable.
    $LnkContent = (Get-Content -Path $LnkINI) # Get the content of the INI file, and save the content to a variable so it can be searched for the string you want to remove.
    If ((Select-String -InputObject $LnkContent -Pattern $SnippingLnk -SimpleMatch -Quiet) -eq $true) # Search the string using the variables that have been assigned above it.  The -Quiet flag returns a bool result ($true, $false) as opposed to ouputting the entire content of the file, hence why it requires the search to -eq (equal) $true.
    {
       If ((([IO.FileInfo]$LnkINI).Attributes -match "Hidden" -and "System")) { ATTRIB -S -H $LnkINI } # Removes the System and Hidden security attributes on the ini so it can be edited.
       (Get-Content -Path $LnkINI) | Where { $_ -ne $SnippingLnk } | Set-Content -Path $LnkINI -Force # The content of the ini is retrieved, piped to the Where cmdlet where it looks for every line ($_) that does NOT equal the variable containing the Snipping Tool string, and then sets the content with the Snipping Tool string omitted.
       ATTRIB +S +H $LnkINI # Resets the security attrubutes
    }
    

    I made this long so you could see verbatim everything that's done in sequence. You can shrink this down into 2 lines if you wanted.

    Or...do it using Group Policy. Mind you removing certain links (Snipping, Steps Recorder, etc.) will not stick, as they are automatically replaced if you run SFC /SCANNOW. So yeah, just use GPEdit.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  10. Windows 10 User

    Windows 10 User MDL Guru

    Feb 2, 2017
    2,005
    122
    90
    Thanks, it's easy for me if I follow the Group Policy guide, although what I really wanted was to remove it and not disable it (if I wanted that I'd disable more things instead of removing them). So, there's no way to remove some apps from the start menu like the Windos Defender Security Center, Photos app and Mixed Reality Portal even if they can't be removed without a clean install? I've already deleted the content of the TileDataLayer folder and it didn't work.
     
  11. AeonX

    AeonX MDL Addicted

    May 24, 2013
    796
    725
    30
    #5751 AeonX, Jan 30, 2018
    Last edited: Jan 30, 2018
    Do you want to remove the shortcut or the entire component? Windows Defender is complicated to remove on RS2/RS3 because it does not reside in a single package.

    Edit:
    Anyway MSMG Toolkit can only remove packages of images offline so if you want help in that do not ask in that topic because anything that does not have the word MSMG written irritates some people with problems of text interpretation and common sense.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  12. GodHand

    GodHand MDL Addicted

    Jul 15, 2016
    534
    926
    30
    Defender can be removed from a live system using process privileges and fairly simple functions. This is not something I would ever personally do but I have done it up to the latest Insider Update on VMs for testing purposes.

    Install_WIM_Tweak will remove the component packages, but will leave visibility settings, registry values and even non-working links across the system. I would not recommend removing Defender using that; you need to use something that does the most thorough job possible for an online system.

    I have never tried NTLite but know the APIs and wrappers it uses, and it, too, has the ability (as stated) to remove it fairly well; however, NTLite does not commit all the final registry values post-removal nor does it recursively remove all hard-links and symbolic-links to Defender, its services, SecHealthUI, etc.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  13. GodHand

    GodHand MDL Addicted

    Jul 15, 2016
    534
    926
    30
    Snipping Tool is just a very small program in your System32 folder. If you remove it from there, and use the guide I posted to remove its link and string data, it's "deleted." You can also set its registry key to '0' as well, but like I said, the removal of programs in the Accessories directory will be flagged as repairable corruption, and running SFC /SCANNOW will replace them.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  14. AeonX

    AeonX MDL Addicted

    May 24, 2013
    796
    725
    30
    Could you give us an example code? Is it just using Powershell or is it something more complex using APIs or C#?
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  15. AeonX

    AeonX MDL Addicted

    May 24, 2013
    796
    725
    30
    #5756 AeonX, Jan 30, 2018
    Last edited: Jan 30, 2018
    Can not right-click and remove the shortcut?

    Edit:
    To remove content online look for another thread or create one but you can easily find how to remove apps online if you search on google.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  16. Windows 10 User

    Windows 10 User MDL Guru

    Feb 2, 2017
    2,005
    122
    90
    But I was talking about the live install and RS3 (and the paid version). No, I can't. If I click them I'm redirected to the settings app.
     
  17. GodHand

    GodHand MDL Addicted

    Jul 15, 2016
    534
    926
    30
    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.

    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.

    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.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  18. endbase

    endbase MDL Guru

    Aug 12, 2012
    4,694
    1,717
    150
    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 ;)
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  19. GodHand

    GodHand MDL Addicted

    Jul 15, 2016
    534
    926
    30
    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).
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...