From 81c0387c14b747990a1cdeae90ae922fd88c2675 Mon Sep 17 00:00:00 2001 From: ChrisTitusTech Date: Thu, 28 Mar 2024 15:51:18 +0000 Subject: [PATCH] Compile Winutil --- winutil.ps1 | 12599 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 12599 insertions(+) diff --git a/winutil.ps1 b/winutil.ps1 index e69de29b..541775ae 100644 --- a/winutil.ps1 +++ b/winutil.ps1 @@ -0,0 +1,12599 @@ + +################################################################################################################ +### ### +### WARNING: This file is automatically generated DO NOT modify this file directly as it will be overwritten ### +### ### +################################################################################################################ + +<# +.NOTES + Author : Chris Titus @christitustech + Runspace Author: @DeveloperDurp + GitHub : https://github.com/ChrisTitusTech + Version : 24.03.28 +#> +param ( + [switch]$Debug, + [string]$Config, + [switch]$Run +) + +# Set DebugPreference based on the -Debug switch +if ($Debug) { + $DebugPreference = "Continue" +} + +if ($Config) { + $PARAM_CONFIG = $Config +} + +$PARAM_RUN = $false +# Handle the -Run switch +if ($Run) { + Write-Host "Running config file tasks..." + $PARAM_RUN = $true +} + +if (!(Test-Path -Path $ENV:TEMP)) { + New-Item -ItemType Directory -Force -Path $ENV:TEMP +} + +Start-Transcript $ENV:TEMP\Winutil.log -Append + +# Load DLLs +Add-Type -AssemblyName PresentationFramework +Add-Type -AssemblyName System.Windows.Forms + +# Variable to sync between runspaces +$sync = [Hashtable]::Synchronized(@{}) +$sync.PSScriptRoot = $PSScriptRoot +$sync.version = "24.03.28" +$sync.configs = @{} +$sync.ProcessRunning = $false + +$currentPid = [System.Security.Principal.WindowsIdentity]::GetCurrent() +$principal = new-object System.Security.Principal.WindowsPrincipal($currentPid) +$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator + + +if ($principal.IsInRole($adminRole)) +{ + $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Admin)" + clear-host +} +else +{ + $newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell"; + $newProcess.Arguments = $myInvocation.MyCommand.Definition; + $newProcess.Verb = "runas"; + [System.Diagnostics.Process]::Start($newProcess); + break +} +function ConvertTo-Icon { + <# + + .DESCRIPTION + This function will convert PNG to ICO file + + .EXAMPLE + ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath $iconPath + #> + param( [Parameter(Mandatory=$true)] + $bitmapPath, + $iconPath = "$env:temp\newicon.ico" + ) + + Add-Type -AssemblyName System.Drawing + + if (Test-Path $bitmapPath) { + $b = [System.Drawing.Bitmap]::FromFile($bitmapPath) + $icon = [System.Drawing.Icon]::FromHandle($b.GetHicon()) + $file = New-Object System.IO.FileStream($iconPath, 'OpenOrCreate') + $icon.Save($file) + $file.Close() + $icon.Dispose() + #explorer "/SELECT,$iconpath" + } + else { Write-Warning "$BitmapPath does not exist" } +} +function Copy-Files { + <# + + .DESCRIPTION + This function will make all modifications to the registry + + .EXAMPLE + + Set-WinUtilRegistry -Name "PublishUserActivities" -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Type "DWord" -Value "0" + + #> + param ( + [string] $Path, + [string] $Destination, + [switch] $Recurse = $false, + [switch] $Force = $false + ) + + try { + + $files = Get-ChildItem -Path $path -Recurse:$recurse + Write-Host "Copy $($files.Count)(s) from $path to $destination" + + foreach($file in $files) + { + $status = "Copy files {0} on {1}: {2}" -f $counter, $files.Count, $file.Name + Write-Progress -Activity "Copy Windows files" -Status $status -PercentComplete ($counter++/$files.count*100) + $restpath = $file.FullName -Replace $path, '' + + if($file.PSIsContainer -eq $true) + { + Write-Debug "Creating $($destination + $restpath)" + New-Item ($destination+$restpath) -Force:$force -Type Directory -ErrorAction SilentlyContinue + } + else + { + Write-Debug "Copy from $($file.FullName) to $($destination+$restpath)" + Copy-Item $file.FullName ($destination+$restpath) -ErrorAction SilentlyContinue -Force:$force + Set-ItemProperty -Path ($destination+$restpath) -Name IsReadOnly -Value $false + } + } + Write-Progress -Activity "Copy Windows files" -Status "Ready" -Completed + } + Catch{ + Write-Warning "Unable to Copy all the files due to unhandled exception" + Write-Warning $psitem.Exception.StackTrace + } +} +function Get-LocalizedYesNo { + <# + .SYNOPSIS + This function runs choice.exe and captures its output to extract yes no in a localized Windows + + .DESCRIPTION + The function retrieves the output of the command 'cmd /c "choice nul"' and converts the default output for Yes and No + in the localized format, such as "Yes=, No=". + + .EXAMPLE + $yesNoArray = Get-LocalizedYesNo + Write-Host "Yes=$($yesNoArray[0]), No=$($yesNoArray[1])" + #> + + # Run choice and capture its options as output + # The output shows the options for Yes and No as "[Y,N]?" in the (partitially) localized format. + # eg. English: [Y,N]? + # Dutch: [Y,N]? + # German: [J,N]? + # French: [O,N]? + # Spanish: [S,N]? + # Italian: [S,N]? + # Russian: [Y,N]? + + $line = cmd /c "choice nul" + $charactersArray = @() + $regexPattern = '([a-zA-Z])' + $charactersArray = [regex]::Matches($line, $regexPattern) | ForEach-Object { $_.Groups[1].Value } + + Write-Debug "According to takeown.exe local Yes is $charactersArray[0]" + # Return the array of characters + return $charactersArray + } + + +function Get-LocalizedYesNoTakeown { + <# + .SYNOPSIS + This function runs takeown.exe and captures its output to extract yes no in a localized Windows + + .DESCRIPTION + The function retrieves lines from the output of takeown.exe until there are at least 2 characters + captured in a specific format, such as "Yes=, No=". + + .EXAMPLE + $yesNoArray = Get-LocalizedYesNo + Write-Host "Yes=$($yesNoArray[0]), No=$($yesNoArray[1])" + #> + + # Run takeown.exe and capture its output + $takeownOutput = & takeown.exe /? | Out-String + + # Parse the output and retrieve lines until there are at least 2 characters in the array + $found = $false + $charactersArray = @() + foreach ($line in $takeownOutput -split "`r`n") + { + # skip everything before /D flag help + if ($found) + { + # now that /D is found start looking for a single character in double quotes + # in help text there is another string in double quotes but it is not a single character + $regexPattern = '"([a-zA-Z])"' + + $charactersArray = [regex]::Matches($line, $regexPattern) | ForEach-Object { $_.Groups[1].Value } + + # if ($charactersArray.Count -gt 0) { + # Write-Output "Extracted symbols: $($matches -join ', ')" + # } else { + # Write-Output "No matches found." + # } + + if ($charactersArray.Count -ge 2) + { + break + } + } + elseif ($line -match "/D ") + { + $found = $true + } + } + + Write-Debug "According to takeown.exe local Yes is $charactersArray[0]" + # Return the array of characters + return $charactersArray + } +function Get-Oscdimg { + <# + + .DESCRIPTION + This function will download oscdimg file from github Release folders and put it into env:temp folder + + .EXAMPLE + Get-Oscdimg + #> + param( [Parameter(Mandatory=$true)] + [string]$oscdimgPath + ) + $oscdimgPath = "$env:TEMP\oscdimg.exe" + $downloadUrl = "https://github.com/ChrisTitusTech/winutil/raw/main/releases/oscdimg.exe" + Invoke-RestMethod -Uri $downloadUrl -OutFile $oscdimgPath + $hashResult = Get-FileHash -Path $oscdimgPath -Algorithm SHA256 + $sha256Hash = $hashResult.Hash + + Write-Host "[INFO] oscdimg.exe SHA-256 Hash: $sha256Hash" + + $expectedHash = "AB9E161049D293B544961BFDF2D61244ADE79376D6423DF4F60BF9B147D3C78D" # Replace with the actual expected hash + if ($sha256Hash -eq $expectedHash) { + Write-Host "Hashes match. File is verified." + } else { + Write-Host "Hashes do not match. File may be corrupted or tampered with." + } +} +function Get-TabXaml { + <# + .SYNOPSIS + Generates XAML for a tab in the WinUtil GUI + This function is used to generate the XAML for the applications tab in the WinUtil GUI + It takes the tabname and the number of columns to display the applications in as input and returns the XAML for the tab as output + .PARAMETER tabname + The name of the tab to generate XAML for + .PARAMETER columncount + The number of columns to display the applications in + .OUTPUTS + The XAML for the tab + .EXAMPLE + Get-TabXaml "applications" 3 + #> + + + param( [Parameter(Mandatory=$true)] + $tabname, + $columncount = 0 + ) + $organizedData = @{} + # Iterate through JSON data and organize by panel and category + foreach ($appName in $sync.configs.$tabname.PSObject.Properties.Name) { + $appInfo = $sync.configs.$tabname.$appName + + # Create an object for the application + $appObject = [PSCustomObject]@{ + Name = $appName + Category = $appInfo.Category + Content = $appInfo.Content + Choco = $appInfo.choco + Winget = $appInfo.winget + Panel = if ($columncount -gt 0 ) { "0" } else {$appInfo.panel} + Link = $appInfo.link + Description = $appInfo.description + # Type is (Checkbox,Toggle,Button,Combobox ) (Default is Checkbox) + Type = $appInfo.type + ComboItems = $appInfo.ComboItems + # Checked is the property to set startup checked status of checkbox (Default is false) + Checked = $appInfo.Checked + } + + if (-not $organizedData.ContainsKey($appObject.panel)) { + $organizedData[$appObject.panel] = @{} + } + + if (-not $organizedData[$appObject.panel].ContainsKey($appObject.Category)) { + $organizedData[$appObject.panel][$appObject.Category] = @{} + } + + # Store application data in a sub-array under the category + # Add Order property to keep the original order of tweaks and features + $organizedData[$appObject.panel][$appInfo.Category]["$($appInfo.order)$appName"] = $appObject + } + $panelcount=0 + $paneltotal = $organizedData.Keys.Count + if ($columncount -gt 0) { + $appcount = $sync.configs.$tabname.PSObject.Properties.Name.count + $organizedData["0"].Keys.count + $maxcount = [Math]::Round( $appcount / $columncount + 0.5) + $paneltotal = $columncount + } + # add ColumnDefinitions to evenly draw colums + $blockXml="`n"+("`n"*($paneltotal))+"`n" + # Iterate through organizedData by panel, category, and application + $count = 0 + foreach ($panel in ($organizedData.Keys | Sort-Object)) { + $blockXml += "`n`n" + $panelcount++ + foreach ($category in ($organizedData[$panel].Keys | Sort-Object)) { + $count++ + if ($columncount -gt 0) { + $panelcount2 = [Int](($count)/$maxcount-0.5) + if ($panelcount -eq $panelcount2 ) { + $blockXml +="`n`n`n" + $blockXml += "`n`n" + $panelcount++ + } + } + $blockXml += "`n`n" + $blockXml += "`n`n" + $panelcount++ + } + } + $appInfo = $organizedData[$panel][$category][$appName] + if ("Toggle" -eq $appInfo.Type) { + $blockXml += "`n`n" + } elseif ("Combobox" -eq $appInfo.Type) { + $blockXml += "`n" + # If it is a digit, type is button and button length is digits + } elseif ($appInfo.Type -match "^[\d\.]+$") { + $blockXml += " + + + + + + Choose Windows SKU + + Choose Windows features you want to remove from the ISO + + + + + + + + + + +