From a37beefdcc7d55ce26ca00d64c893203113cf21f Mon Sep 17 00:00:00 2001 From: Kaleb Luedtke Date: Wed, 17 Nov 2021 18:38:07 -0600 Subject: [PATCH 01/13] Begin update in place --- Tools/YamlCreate.ps1 | 340 ++++++++++++++++++++++--------------------- 1 file changed, 173 insertions(+), 167 deletions(-) diff --git a/Tools/YamlCreate.ps1 b/Tools/YamlCreate.ps1 index 5d66c4622c897..6d004b556b5fa 100644 --- a/Tools/YamlCreate.ps1 +++ b/Tools/YamlCreate.ps1 @@ -1,5 +1,5 @@ #Requires -Version 5 -[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification='This script is not intended to have any outputs piped')] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'This script is not intended to have any outputs piped')] Param ( @@ -205,13 +205,13 @@ Function Test-String { if ($PSBoundParameters.ContainsKey('MatchPattern')) { $_isValid = $_isValid -and ($InputString -match $MatchPattern) } - if ($AllowNull -and [string]::IsNullOrEmpty($InputString)) { + if ($AllowNull -and [string]::IsNullOrWhiteSpace($InputString)) { $_isValid = $true - } elseif ($NotNull -and [string]::IsNullOrEmpty($InputString)) { + } elseif ($NotNull -and [string]::IsNullOrWhiteSpace($InputString)) { $_isValid = $false } if ($IsNull) { - $_isValid = [string]::IsNullOrEmpty($InputString) + $_isValid = [string]::IsNullOrWhiteSpace($InputString) } if ($Not) { @@ -361,52 +361,27 @@ Function Get-InstallerFile { ) # Create a filename based on the Package Identifier and Version; Try to get the extension from the URL # If the extension isn't found, use a custom one - $Filename = "$PackageIdentifier v$PackageVersion" + $(if([System.IO.Path]::HasExtension($URI)) { [System.IO.Path]::GetExtension($URI) } else { '.winget-tmp' }) - $script:dest = Join-Path -Path $env:TEMP -ChildPath $Filename + $_Filename = "$PackageIdentifier v$PackageVersion" + $(if ([System.IO.Path]::HasExtension($URI)) { [System.IO.Path]::GetExtension($URI) } else { '.winget-tmp' }) + $_OutFile = Join-Path -Path $env:TEMP -ChildPath $_Filename # Create a new web client for downloading the file - $WebClient = [System.Net.WebClient]::new() + $_WebClient = [System.Net.WebClient]::new() # If the system has a default proxy set, use it # Powershell Core will automatically use this, so it's only necessary for PS5 - if ($PSVersionTable.PSVersion.Major -lt 6){ $WebClient.Proxy = [System.Net.WebProxy]::GetDefaultProxy() } + if ($PSVersionTable.PSVersion.Major -lt 6) { $_WebClient.Proxy = [System.Net.WebProxy]::GetDefaultProxy() } # Download the file - $WebClient.DownloadFile($URI, $dest) + $_WebClient.DownloadFile($URI, $_OutFile) # Dispose of the web client to release the resources it uses - $WebClient.Dispose() -} + $_WebClient.Dispose() -# Prompts the user to enter installer values -# Sets the $script:Installers value as an output -# Returns void -Function Read-InstallerEntry { - # Clear prompted variables to ensure data from previous installer entries is not used for new entries - $InstallerValues = @( - 'Architecture' - 'InstallerType' - 'InstallerUrl' - 'InstallerSha256' - 'SignatureSha256' - 'PackageFamilyName' - 'Custom' - 'Silent' - 'SilentWithProgress' - 'ProductCode' - 'Scope' - 'InstallerLocale' - 'UpgradeBehavior' - 'AnotherInstaller' - ) - Foreach ($InstallerValue in $InstallerValues) { Clear-Variable -Name $InstallerValue -Force -ErrorAction SilentlyContinue } - - # Request user enter Installer URL - $InstallerUrl = Request-InstallerUrl + return $_OutFile +} - # Get or request Installer Sha256 - # Check the settings to see if we need to display this menu +Function Get-UserSavePreference { switch ($ScriptSettings.SaveToTemporaryFolder) { - 'always' { $script:SaveOption = '0' } - 'never' { $script:SaveOption = '1' } - 'manual' { $script:SaveOption = '2' } + 'always' { $_Preference = '0' } + 'never' { $_Preference = '1' } + 'manual' { $_Preference = '2' } default { $_menu = @{ entries = @('[Y] Yes'; '*[N] No'; '[M] Manually Enter SHA256') @@ -414,69 +389,116 @@ Function Read-InstallerEntry { DefaultString = 'N' } switch ( Invoke-KeypressMenu -Prompt $_menu['Prompt'] -Entries $_menu['Entries'] -DefaultString $_menu['DefaultString']) { - 'Y' { $script:SaveOption = '0' } - 'N' { $script:SaveOption = '1' } - 'M' { $script:SaveOption = '2' } - default { $script:SaveOption = '1' } + 'Y' { $_Preference = '0' } + 'N' { $_Preference = '1' } + 'M' { $_Preference = '2' } + default { $_Preference = '1' } } } } + return $_Preference +} - # If user did not select manual entry for Sha256, download file and calculate hash - # Also attempt to detect installer type and architecture - if ($script:SaveOption -ne '2') { - Write-Host - $start_time = Get-Date - Write-Host $NewLine - Write-Host 'Downloading URL. This will take a while...' -ForegroundColor Blue - try { - Get-InstallerFile -URI $InstallerUrl -PackageIdentifier $PackageIdentifier -PackageVersion $PackageVersion - } catch { - # Here we also want to pass any exceptions through for potential debugging - throw [System.Net.WebException]::new('The file could not be downloaded. Try running the script again', $_.Exception) - } finally { - Write-Host "Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)" -ForegroundColor Green +Function Get-PathInstallerType { + Param + ( + [Parameter(Mandatory = $true, Position = 0)] + [string] $Path + ) - $InstallerSha256 = (Get-FileHash -Path $script:dest -Algorithm SHA256).Hash + if ($Path -match '\.msix(bundle){0,1}$') { return 'msix' } + if ($Path -match '\.msi$') { return 'msi' } + if ($Path -match '\.appx(bundle){0,1}$') { return 'appx' } + if ($Path -match '\.zip$') { return 'zip' } + return $null +} - if ($script:dest -match '\.msix(bundle){0,1}$') { $InstallerType = 'msix' } - elseif ($script:dest -match '\.msi$') { $InstallerType = 'msi' } - elseif ($script:dest -match '\.appx(bundle){0,1}$') { $InstallerType = 'appx' } - elseif ($script:dest -match '\.zip$') { $InstallerType = 'zip' } +Function Get-UriArchitecture { + Param + ( + [Parameter(Mandatory = $true, Position = 0)] + [string] $URI + ) - if ($InstallerUrl -match '\b(x|win){0,1}64\b') { $architecture = 'x64' } - elseif ($InstallerUrl -match '\b((win|ia)32)|(x{0,1}86)\b') { $architecture = 'x86' } - elseif ($InstallerUrl -match '\b(arm|aarch)64\b') { $architecture = 'arm64' } - elseif ($InstallerUrl -match '\barm\b') { $architecture = 'arm' } + if ($URI -match '\b(x|win){0,1}64\b') { return 'x64' } + if ($URI -match '\b((win|ia)32)|(x{0,1}86)\b') { return 'x86' } + if ($URI -match '\b(arm|aarch)64\b') { return 'arm64' } + if ($URI -match '\barm\b') { return 'arm' } + return $null +} - $MSIProductCode = $(Get-AppLockerFileInformation -Path $script:dest | Select-Object Publisher | Select-String -Pattern '{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}').Matches +# Prompts the user to enter installer values +# Sets the $script:Installers value as an output +# Returns void +Function Read-InstallerEntry { - if ($script:SaveOption -eq '1' -and -not($script:dest -match '\.(msix|appx)(bundle){0,1}$')) { Remove-Item -Path $script:dest } - } + $_Installer = [ordered] @{} + # Request user enter Installer URL + $_Installer['InstallerUrl'] = Request-InstallerUrl + + if ($_Installer.InstallerUrl -in ($script:Installers).InstallerUrl) { + $_MatchingInstaller = $script:Installers | Where-Object { $_.InstallerUrl -eq $InstallerUrl } | Select-Object -First 1 + if ($_MatchingInstaller.InstallerSha256) { $_Installer['InstallerSha256'] = $_MatchingInstaller.InstallerSha256 } + if ($_MatchingInstaller.InstallerType) { $_Installer['InstallerType'] = $_MatchingInstaller.InstallerType } + if ($_MatchingInstaller.Architecture) { $_Installer['Architecture'] = $_MatchingInstaller.Architecture } + if ($_MatchingInstaller.ProductCode) { $_Installer['ProductCode'] = $_MatchingInstaller.ProductCode } + if ($_MatchingInstaller.PackageFamilyName) { $_Installer['PackageFamilyName'] = $_MatchingInstaller.PackageFamilyName } + if ($_MatchingInstaller.SignatureSha256) { $_Installer['SignatureSha256'] = $_MatchingInstaller.SignatureSha256 } } - # Manual Entry of Sha256 with validation - else { - Write-Host - do { - Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() - Write-Host -ForegroundColor 'Green' -Object '[Required] Enter the installer SHA256 Hash' - $InstallerSha256 = Read-Host -Prompt 'InstallerSha256' | TrimString - $InstallerSHA256 = $InstallerSha256.toUpper() - if ($InstallerSha256 -match $Patterns.InstallerSha256) { - $script:_returnValue = [ReturnValue]::Success() - } else { - $script:_returnValue = [ReturnValue]::PatternError() + + # Get or request Installer Sha256 + # Check the settings to see if we need to display this menu + if ($_Installer.Keys -notcontains 'InstallerSha256') { + + $script:SaveOption = Get-UserSavePreference + # If user did not select manual entry for Sha256, download file and calculate hash + # Also attempt to detect installer type and architecture + if ($script:SaveOption -ne '2') { + Write-Host + $start_time = Get-Date + Write-Host $NewLine + Write-Host 'Downloading URL. This will take a while...' -ForegroundColor Blue + try { + $script:dest = Get-InstallerFile -URI $InstallerUrl -PackageIdentifier $PackageIdentifier -PackageVersion $PackageVersion + } catch { + # Here we also want to pass any exceptions through for potential debugging + throw [System.Net.WebException]::new('The file could not be downloaded. Try running the script again', $_.Exception) + } finally { + Write-Host "Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)" -ForegroundColor Green + $_Installer['InstallerSha256'] = (Get-FileHash -Path $script:dest -Algorithm SHA256).Hash + Get-PathInstallerType -Path $script:dest -OutVariable _ | Out-Null + if ($_) { $_Installer['InstallerType'] = $_ | Select-Object -First 1 } + Get-UriArchitecture -URI $_Installer['InstallerUrl'] -OutVariable _ | Out-Null + if ($_) { $_Installer['Architecture'] = $_ | Select-Object -First 1 } + $_Installer['ProductCode'] = $(Get-AppLockerFileInformation -Path $script:dest | Select-Object Publisher | Select-String -Pattern '{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}').Matches + + if ($script:SaveOption -eq '1' -and -not($script:dest -match '\.(msix|appx)(bundle){0,1}$')) { Remove-Item -Path $script:dest } } - } until ($script:_returnValue.StatusCode -eq [ReturnValue]::Success().StatusCode) + } + # Manual Entry of Sha256 with validation + else { + Write-Host + do { + Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() + Write-Host -ForegroundColor 'Green' -Object '[Required] Enter the installer SHA256 Hash' + $_Installer['InstallerSha256'] = Read-Host -Prompt 'InstallerSha256' | TrimString + $_Installer['InstallerSha256'] = $_Installer['InstallerSha256'].toUpper() + if ($_Installer['InstallerSha256'] -match $Patterns.InstallerSha256) { + $script:_returnValue = [ReturnValue]::Success() + } else { + $script:_returnValue = [ReturnValue]::PatternError() + } + } until ($script:_returnValue.StatusCode -eq [ReturnValue]::Success().StatusCode) + } } # Manual Entry of Architecture with validation - if ($architecture -CNotIn @($Patterns.ValidArchitectures)) { + if ($_Installer['Architecture'] -CNotIn @($Patterns.ValidArchitectures)) { do { Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() Write-Host -ForegroundColor 'Green' -Object '[Required] Enter the architecture. Options:' , @($Patterns.ValidArchitectures -join ', ') - $architecture = Read-Host -Prompt 'Architecture' | TrimString - if ($architecture -Cin @($Patterns.ValidArchitectures)) { + $_Installer['Architecture'] = Read-Host -Prompt 'Architecture' | TrimString + if ($_Installer['Architecture'] -Cin @($Patterns.ValidArchitectures)) { $script:_returnValue = [ReturnValue]::Success() } else { $script:_returnValue = [ReturnValue]::new(400, 'Invalid Architecture', "Value must exist in the enum - $(@($Patterns.ValidArchitectures -join ', '))", 2) @@ -485,12 +507,12 @@ Function Read-InstallerEntry { } # Manual Entry of Installer Type with validation - if ($InstallerType -CNotIn @($Patterns.ValidInstallerTypes)) { + if ($_Installer['InstallerType'] -CNotIn @($Patterns.ValidInstallerTypes)) { do { Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() Write-Host -ForegroundColor 'Green' -Object '[Required] Enter the InstallerType. Options:' , @($Patterns.ValidInstallerTypes -join ', ' ) - $InstallerType = Read-Host -Prompt 'InstallerType' | TrimString - if ($InstallerType -Cin @($Patterns.ValidInstallerTypes)) { + $_Installer['InstallerType'] = Read-Host -Prompt 'InstallerType' | TrimString + if ($_Installer['InstallerType'] -Cin @($Patterns.ValidInstallerTypes)) { $script:_returnValue = [ReturnValue]::Success() } else { $script:_returnValue = [ReturnValue]::new(400, 'Invalid Installer Type', "Value must exist in the enum - $(@($Patterns.ValidInstallerTypes -join ', '))", 2) @@ -498,15 +520,16 @@ Function Read-InstallerEntry { } until ($script:_returnValue.StatusCode -eq [ReturnValue]::Success().StatusCode) } + $_Switches = [ordered] @{} # If Installer Type is `exe`, require the silent switches to be entered - if ($InstallerType -ieq 'exe') { + if ($_Installer['InstallerType'] -ieq 'exe') { # Required entry of `Silent` switches with validation do { Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() Write-Host -ForegroundColor 'Green' -Object '[Required] Enter the silent install switch. For example: /S, -verysilent, /qn, --silent, /exenoui' - $Silent = Read-Host -Prompt 'Silent switch' | TrimString + $_Switches['Silent'] = Read-Host -Prompt 'Silent switch' | TrimString - if (Test-String $Silent -MaxLength $Patterns.SilentSwitchMaxLength -NotNull) { + if (Test-String $_Switches['Silent'] -MaxLength $Patterns.SilentSwitchMaxLength -NotNull) { $script:_returnValue = [ReturnValue]::Success() } else { $script:_returnValue = [ReturnValue]::LengthError(1, $Patterns.SilentSwitchMaxLength) @@ -517,9 +540,9 @@ Function Read-InstallerEntry { do { Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() Write-Host -ForegroundColor 'Green' -Object '[Required] Enter the silent with progress install switch. For example: /S, -silent, /qb, /exebasicui' - $SilentWithProgress = Read-Host -Prompt 'Silent with progress switch' | TrimString + $_Switches['SilentWithProgress'] = Read-Host -Prompt 'Silent with progress switch' | TrimString - if (Test-String $SilentWithProgress -MaxLength $Patterns.ProgressSwitchMaxLength -NotNull) { + if (Test-String $_Switches['SilentWithProgress'] -MaxLength $Patterns.ProgressSwitchMaxLength -NotNull) { $script:_returnValue = [ReturnValue]::Success() } else { $script:_returnValue = [ReturnValue]::LengthError(1, $Patterns.ProgressSwitchMaxLength) @@ -532,23 +555,22 @@ Function Read-InstallerEntry { do { Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() Write-Host -ForegroundColor 'Yellow' -Object '[Optional] Enter the silent install switch. For example: /S, /s, /VERYSILENT, /qn, --silent' - $Silent = Read-Host -Prompt 'Silent' | TrimString - - if (Test-String $Silent -MaxLength $Patterns.SilentSwitchMaxLength -AllowNull) { + Read-Host -Prompt 'Silent' -OutVariable _ | Out-Null + if ($_) {$_Switches['Silent'] = $_ | TrimString} + if (Test-String $_Switches['Silent'] -MaxLength $Patterns.SilentSwitchMaxLength -AllowNull) { $script:_returnValue = [ReturnValue]::Success() } else { $script:_returnValue = [ReturnValue]::LengthError(1, $Patterns.SilentSwitchMaxLength) } - } until ($script:_returnValue.StatusCode -eq [ReturnValue]::Success().StatusCode) # Optional entry of `SilentWithProgress` switch with validation do { Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() Write-Host -ForegroundColor 'Yellow' -Object '[Optional] Enter the silent with progress install switch. For example: /S, /SILENT, /qb' - $SilentWithProgress = Read-Host -Prompt 'SilentWithProgress' | TrimString - - if (Test-String $SilentWithProgress -MaxLength $Patterns.ProgressSwitchMaxLength -AllowNull) { + Read-Host -Prompt 'SilentWithProgress' -OutVariable _ | Out-Null + if ($_) {$_Switches['SilentWithProgress'] = $_ | TrimString } + if (Test-String $_Switches['SilentWithProgress'] -MaxLength $Patterns.ProgressSwitchMaxLength -AllowNull) { $script:_returnValue = [ReturnValue]::Success() } else { $script:_returnValue = [ReturnValue]::LengthError(1, $Patterns.ProgressSwitchMaxLength) @@ -560,27 +582,30 @@ Function Read-InstallerEntry { do { Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() Write-Host -ForegroundColor 'Yellow' -Object '[Optional] Enter any custom switches for the installer. For example: /norestart, -norestart' - $Custom = Read-Host -Prompt 'Custom Switch' | TrimString - - if (Test-String $Custom -MaxLength $Patterns.CustomSwitchMaxLength -AllowNull) { + Read-Host -Prompt 'Custom Switch' -OutVariable _ | Out-Null + if ($_) { $_Switches['Custom'] = $_ | TrimString } + if (Test-String $_Switches['Custom'] -MaxLength $Patterns.CustomSwitchMaxLength -AllowNull) { $script:_returnValue = [ReturnValue]::Success() } else { $script:_returnValue = [ReturnValue]::LengthError(1, $Patterns.CustomSwitchMaxLength) } } until ($script:_returnValue.StatusCode -eq [ReturnValue]::Success().StatusCode) + if ($_Switches.Keys.Count -gt 0) { $_Installer['InstallerSwitches'] = $_Switches } + # If the installer is `msix` or `appx`, prompt for or detect additional fields - if ($InstallerType -ieq 'msix' -or $InstallerType -ieq 'appx') { + if ($_Installer['InstallerType'] -in @('msix'; 'appx')) { # Detect or prompt for Signature Sha256 if (Get-Command 'winget.exe' -ErrorAction SilentlyContinue) { $SignatureSha256 = winget hash -m $script:dest | Select-String -Pattern 'SignatureSha256:' | ConvertFrom-String; if ($SignatureSha256.P2) { $SignatureSha256 = $SignatureSha256.P2.ToUpper() } } - if (Test-String $SignatureSha256 -IsNull) { + $_Installer['SignatureSha256'] = $SignatureSha256 + if (Test-String $_Installer['SignatureSha256'] -IsNull) { # Manual entry of Signature Sha256 with validation do { Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() Write-Host -ForegroundColor 'Yellow' -Object '[Recommended] Enter the installer SignatureSha256' - $SignatureSha256 = Read-Host -Prompt 'SignatureSha256' | TrimString + $_Installer['SignatureSha256'] = Read-Host -Prompt 'SignatureSha256' | TrimString - if (Test-String $SignatureSha256 -MatchPattern $Patterns.SignatureSha256 -AllowNull) { + if (Test-String $_Installer['SignatureSha256'] -MatchPattern $Patterns.SignatureSha256 -AllowNull) { $script:_returnValue = [ReturnValue]::Success() } else { $script:_returnValue = [ReturnValue]::PatternError() @@ -598,7 +623,6 @@ Function Read-InstallerEntry { DefaultString = 'F' } switch ( Invoke-KeypressMenu -Prompt $_menu['Prompt'] -Entries $_menu['Entries'] -DefaultString $_menu['DefaultString']) { - 'F' { $ChoicePfn = '0' } 'M' { $ChoicePfn = '1' } default { $ChoicePfn = '0' } } @@ -610,13 +634,13 @@ Function Read-InstallerEntry { try { Add-AppxPackage -Path $script:dest $InstalledPkg = Get-AppxPackage | Select-Object -Last 1 | Select-Object PackageFamilyName, PackageFullName - $PackageFamilyName = $InstalledPkg.PackageFamilyName + $_Installer['PackageFamilyName'] = $InstalledPkg.PackageFamilyName Remove-AppxPackage $InstalledPkg.PackageFullName } catch { # Take no action here, we just want to catch the exceptions as a precaution Out-Null } finally { - if (Test-String $PackageFamilyName -IsNull) { + if (Test-String $_Installer['PackageFamilyName'] -IsNull) { $script:_returnValue = [ReturnValue]::new(500, 'Could not find PackageFamilyName', 'Value should be entered manually', 1) } } @@ -628,11 +652,11 @@ Function Read-InstallerEntry { if (($ChoicePfn -ne '0') -or ($script:_returnValue.StatusCode -ne [ReturnValue]::Success().StatusCode)) { Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() Write-Host -ForegroundColor 'Yellow' -Object '[Recommended] Enter the PackageFamilyName' - $PackageFamilyName = Read-Host -Prompt 'PackageFamilyName' | TrimString + $_Installer['PackageFamilyName'] = Read-Host -Prompt 'PackageFamilyName' | TrimString } - if (Test-String $PackageFamilyName -MaxLength $Patterns.FamilyNameMaxLength -MatchPattern $Patterns.FamilyName -AllowNull) { - if (Test-String $PackageFamilyName -IsNull) { $PackageFamilyName = "$([char]0x2370)" } + if (Test-String $_Installer['PackageFamilyName'] -MaxLength $Patterns.FamilyNameMaxLength -MatchPattern $Patterns.FamilyName -AllowNull) { + if (Test-String $_Installer['PackageFamilyName'] -IsNull) { $_Installer['PackageFamilyName'] = "$([char]0x2370)" } $script:_returnValue = [ReturnValue]::Success() } else { if (Test-String -not $PackageFamilyName -MaxLength $Patterns.FamilyNameMaxLength) { @@ -653,16 +677,17 @@ Function Read-InstallerEntry { Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() Write-Host -ForegroundColor 'Yellow' -Object '[Optional] Enter the installer locale. For example: en-US, en-CA' Write-Host -ForegroundColor 'Blue' -Object 'https://docs.microsoft.com/openspecs/office_standards/ms-oe376/6c085406-a698-4e12-9d4d-c3b0ee3dbc4a' - $InstallerLocale = Read-Host -Prompt 'InstallerLocale' | TrimString + Read-Host -Prompt 'InstallerLocale' -OutVariable _ + if ($_) { $_Installer['InstallerLocale'] = $_ | TrimString } # If user defined a default locale, add it - if ((Test-String $InstallerLocale -IsNull) -and (Test-String -not $ScriptSettings.DefaultInstallerLocale -IsNull)) { $InstallerLocale = $ScriptSettings.DefaultInstallerLocale } + if ((Test-String $_Installer['InstallerLocale'] -IsNull) -and (Test-String -not $ScriptSettings.DefaultInstallerLocale -IsNull)) { $_Installer['InstallerLocale'] = $ScriptSettings.DefaultInstallerLocale } - if (Test-String $InstallerLocale -MaxLength $Patterns.InstallerLocaleMaxLength -MatchPattern $Patterns.PackageLocale -AllowNull) { + if (Test-String $_Installer['InstallerLocale'] -MaxLength $Patterns.InstallerLocaleMaxLength -MatchPattern $Patterns.PackageLocale -AllowNull) { $script:_returnValue = [ReturnValue]::Success() } else { - if (Test-String -not $InstallerLocale -MaxLength $Patterns.InstallerLocaleMaxLength -AllowNull) { + if (Test-String -not $_Installer['InstallerLocale'] -MaxLength $Patterns.InstallerLocaleMaxLength -AllowNull) { $script:_returnValue = [ReturnValue]::LengthError(0, $Patterns.InstallerLocaleMaxLength) - } elseif (Test-String -not $InstallerLocale -MatchPattern $Patterns.PackageLocale) { + } elseif (Test-String -not $_Installer['InstallerLocale'] -MatchPattern $Patterns.PackageLocale) { $script:_returnValue = [ReturnValue]::PatternError() } else { $script:_returnValue = [ReturnValue]::GenericError() @@ -674,11 +699,13 @@ Function Read-InstallerEntry { do { Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() Write-Host -ForegroundColor 'Yellow' -Object '[Optional] Enter the application product code. Looks like {CF8E6E00-9C03-4440-81C0-21FACB921A6B}' - Write-Host -ForegroundColor 'White' -Object "ProductCode found from installer: $MSIProductCode" + Write-Host -ForegroundColor 'White' -Object "ProductCode found from installer: $($_Installer['ProductCode'])" Write-Host -ForegroundColor 'White' -Object 'Can be found with ' -NoNewline; Write-Host -ForegroundColor 'DarkYellow' 'get-wmiobject Win32_Product | Sort-Object Name | Format-Table IdentifyingNumber, Name -AutoSize' - $ProductCode = Read-Host -Prompt 'ProductCode' | TrimString + $NewProductCode = Read-Host -Prompt 'ProductCode' | TrimString + if (Test-String $NewProductCode -Not -IsNull) { $_Installer['ProductCode'] = $NewProductCode } + else { $_Installer['ProductCode'] = "$($_Installer['ProductCode'])" } - if (Test-String $ProductCode -MinLength $Patterns.ProductCodeMinLength -MaxLength $Patterns.ProductCodeMaxLength -AllowNull) { + if (Test-String $_Installer['ProductCode'] -MinLength $Patterns.ProductCodeMinLength -MaxLength $Patterns.ProductCodeMaxLength -AllowNull) { $script:_returnValue = [ReturnValue]::Success() } else { $script:_returnValue = [ReturnValue]::LengthError($Patterns.ProductCodeMinLength, $Patterns.ProductCodeMaxLength) @@ -692,10 +719,9 @@ Function Read-InstallerEntry { DefaultString = 'N' } switch ( Invoke-KeypressMenu -Prompt $_menu['Prompt'] -Entries $_menu['Entries'] -DefaultString $_menu['DefaultString']) { - 'M' { $Scope = 'machine' } - 'U' { $Scope = 'user' } - 'N' { $Scope = '' } - default { $Scope = '' } + 'M' { $_Installer['Scope'] = 'machine' } + 'U' { $_Installer['Scope'] = 'user' } + default { } } # Request upgrade behavior @@ -705,9 +731,8 @@ Function Read-InstallerEntry { DefaultString = 'I' } switch ( Invoke-KeypressMenu -Prompt $_menu['Prompt'] -Entries $_menu['Entries'] -DefaultString $_menu['DefaultString']) { - 'I' { $UpgradeBehavior = 'install' } - 'U' { $UpgradeBehavior = 'uninstallPrevious' } - default { $UpgradeBehavior = 'install' } + 'U' { $_Installer['UpgradeBehavior'] = 'uninstallPrevious' } + default { $_Installer['UpgradeBehavior'] = 'install' } } # If the installers array is empty, create it @@ -715,42 +740,23 @@ Function Read-InstallerEntry { $script:Installers = @() } - # Set up a new empty installer - $_Installer = [ordered] @{} - - # Add the single-line parameters to the installer entry - $_InstallerSingletons = [ordered] @{ - 'InstallerLocale' = $InstallerLocale - 'Architecture' = $Architecture - 'InstallerType' = $InstallerType - 'Scope' = $Scope - 'InstallerUrl' = $InstallerUrl - 'InstallerSha256' = $InstallerSha256 - 'SignatureSha256' = $SignatureSha256 - 'PackageFamilyName' = $PackageFamilyName - } - foreach ($_Item in $_InstallerSingletons.GetEnumerator()) { - If ($_Item.Value) { Add-YamlParameter -Object $_Installer -Parameter $_Item.Name -Value $_Item.Value } - } - - # Add the installer switches to the installer entry, if they exist - If ($Silent -or $SilentWithProgress -or $Custom) { - $_InstallerSwitches = [ordered]@{} - $_Switches = [ordered] @{ - 'Custom' = $Custom - 'Silent' = $Silent - 'SilentWithProgress' = $SilentWithProgress - } - foreach ($_Item in $_Switches.GetEnumerator()) { - If ($_Item.Value) { Add-YamlParameter -Object $_InstallerSwitches -Parameter $_Item.Name -Value $_Item.Value } - } - $_InstallerSwitches = Restore-YamlKeyOrder $_InstallerSwitches $InstallerSwitchProperties -NoComments - $_Installer['InstallerSwitches'] = $_InstallerSwitches - } + # # Add the installer switches to the installer entry, if they exist + # If ($Silent -or $SilentWithProgress -or $Custom) { + # $_InstallerSwitches = [ordered]@{} + # $_Switches = [ordered] @{ + # 'Custom' = $Custom + # 'Silent' = $Silent + # 'SilentWithProgress' = $SilentWithProgress + # } + # foreach ($_Item in $_Switches.GetEnumerator()) { + # If ($_Item.Value) { Add-YamlParameter -Object $_InstallerSwitches -Parameter $_Item.Name -Value $_Item.Value } + # } + # $_InstallerSwitches = Restore-YamlKeyOrder $_InstallerSwitches $InstallerSwitchProperties -NoComments + # $_Installer['InstallerSwitches'] = $_InstallerSwitches + # } # Add the product code to the installer entry, if it exists - If ($ProductCode) { Add-YamlParameter -Object $_Installer -Parameter 'ProductCode' -Value $ProductCode } - Add-YamlParameter -Object $_Installer -Parameter 'UpgradeBehavior' -Value $UpgradeBehavior + # If ($ProductCode) { Add-YamlParameter -Object $_Installer -Parameter 'ProductCode' -Value $ProductCode } # Add the completed installer to the installers array $_Installer = Restore-YamlKeyOrder $_Installer $InstallerEntryProperties -NoComments @@ -980,10 +986,10 @@ Function Read-InstallerMetadata { $script:_returnValue = [ReturnValue]::Success() try { #Ensure all values are integers - $script:InstallerSuccessCodes.Split(',').Trim()| ForEach-Object {[long]$_} + $script:InstallerSuccessCodes.Split(',').Trim() | ForEach-Object { [long]$_ } $script:_returnValue = [ReturnValue]::Success() } catch { - $script:_returnValue = [ReturnValue]::new(400,"Invalid Data Type","The value entered does not match the type requirements defined in the manifest schema",2) + $script:_returnValue = [ReturnValue]::new(400, 'Invalid Data Type', 'The value entered does not match the type requirements defined in the manifest schema', 2) } } else { $script:_returnValue = [ReturnValue]::MaxItemsError($Patterns.MaxItemsSuccessCodes) @@ -1600,7 +1606,7 @@ Function Write-InstallerManifest { $InstallerManifest['Dependencies'] = Restore-YamlKeyOrder $InstallerManifest['Dependencies'] $InstallerDependencyProperties -NoComments } # Move Installer Level Keys to Manifest Level - $_KeysToMove = $InstallerEntryProperties | Where-Object { $_ -in $InstallerProperties -and $_ -ne 'ProductCode'} + $_KeysToMove = $InstallerEntryProperties | Where-Object { $_ -in $InstallerProperties -and $_ -ne 'ProductCode' } foreach ($_Key in $_KeysToMove) { if ($_Key -in $InstallerManifest.Installers[0].Keys) { # Handle the switches specially From 2f2a55220462ccc2ec291001761fd2b215ec927e Mon Sep 17 00:00:00 2001 From: Kaleb Luedtke Date: Wed, 17 Nov 2021 18:48:32 -0600 Subject: [PATCH 02/13] Condense installer switch logic --- Tools/YamlCreate.ps1 | 78 +++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 52 deletions(-) diff --git a/Tools/YamlCreate.ps1 b/Tools/YamlCreate.ps1 index 6d004b556b5fa..c66d9813c9929 100644 --- a/Tools/YamlCreate.ps1 +++ b/Tools/YamlCreate.ps1 @@ -522,61 +522,35 @@ Function Read-InstallerEntry { $_Switches = [ordered] @{} # If Installer Type is `exe`, require the silent switches to be entered - if ($_Installer['InstallerType'] -ieq 'exe') { - # Required entry of `Silent` switches with validation - do { - Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() - Write-Host -ForegroundColor 'Green' -Object '[Required] Enter the silent install switch. For example: /S, -verysilent, /qn, --silent, /exenoui' - $_Switches['Silent'] = Read-Host -Prompt 'Silent switch' | TrimString - - if (Test-String $_Switches['Silent'] -MaxLength $Patterns.SilentSwitchMaxLength -NotNull) { - $script:_returnValue = [ReturnValue]::Success() - } else { - $script:_returnValue = [ReturnValue]::LengthError(1, $Patterns.SilentSwitchMaxLength) - } - } until ($script:_returnValue.StatusCode -eq [ReturnValue]::Success().StatusCode) + do { + Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() + if ($_Installer['InstallerType'] -ieq 'exe') { Write-Host -ForegroundColor 'Green' -Object '[Required] Enter the silent install switch. For example: /S, -verysilent, /qn, --silent, /exenoui' } + else { Write-Host -ForegroundColor 'Yellow' -Object '[Optional] Enter the silent install switch. For example: /S, -verysilent, /qn, --silent, /exenoui' } + $_Switches['Silent'] = Read-Host -Prompt 'Silent switch' | TrimString - # Required entry of `SilentWithProgress` swtich with validation - do { - Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() - Write-Host -ForegroundColor 'Green' -Object '[Required] Enter the silent with progress install switch. For example: /S, -silent, /qb, /exebasicui' - $_Switches['SilentWithProgress'] = Read-Host -Prompt 'Silent with progress switch' | TrimString + if (Test-String $_Switches['Silent'] -MaxLength $Patterns.SilentSwitchMaxLength -NotNull) { + $script:_returnValue = [ReturnValue]::Success() + } elseif ($_Installer['InstallerType'] -ne 'exe' -and (Test-String $_Switches['Silent'] -MaxLength $Patterns.SilentSwitchMaxLength -AllowNull)) { + $script:_returnValue = [ReturnValue]::Success() + } else { + $script:_returnValue = [ReturnValue]::LengthError(1, $Patterns.SilentSwitchMaxLength) + } + } until ($script:_returnValue.StatusCode -eq [ReturnValue]::Success().StatusCode) - if (Test-String $_Switches['SilentWithProgress'] -MaxLength $Patterns.ProgressSwitchMaxLength -NotNull) { - $script:_returnValue = [ReturnValue]::Success() - } else { - $script:_returnValue = [ReturnValue]::LengthError(1, $Patterns.ProgressSwitchMaxLength) - } - } until ($script:_returnValue.StatusCode -eq [ReturnValue]::Success().StatusCode) - } - # If Installer Type is not `exe`, the silent switches are optional - else { - # Optional entry of `Silent` switch with validation - do { - Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() - Write-Host -ForegroundColor 'Yellow' -Object '[Optional] Enter the silent install switch. For example: /S, /s, /VERYSILENT, /qn, --silent' - Read-Host -Prompt 'Silent' -OutVariable _ | Out-Null - if ($_) {$_Switches['Silent'] = $_ | TrimString} - if (Test-String $_Switches['Silent'] -MaxLength $Patterns.SilentSwitchMaxLength -AllowNull) { - $script:_returnValue = [ReturnValue]::Success() - } else { - $script:_returnValue = [ReturnValue]::LengthError(1, $Patterns.SilentSwitchMaxLength) - } - } until ($script:_returnValue.StatusCode -eq [ReturnValue]::Success().StatusCode) + do { + Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() + if ($_Installer['InstallerType'] -ieq 'exe') { Write-Host -ForegroundColor 'Green' -Object '[Required] Enter the silent with progress install switch. For example: /S, -silent, /qb, /exebasicui' } + else { Write-Host -ForegroundColor 'Yellow' -Object '[Optional] Enter the silent with progress install switch. For example: /S, -silent, /qb, /exebasicui' } + $_Switches['SilentWithProgress'] = Read-Host -Prompt 'Silent with progress switch' | TrimString - # Optional entry of `SilentWithProgress` switch with validation - do { - Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() - Write-Host -ForegroundColor 'Yellow' -Object '[Optional] Enter the silent with progress install switch. For example: /S, /SILENT, /qb' - Read-Host -Prompt 'SilentWithProgress' -OutVariable _ | Out-Null - if ($_) {$_Switches['SilentWithProgress'] = $_ | TrimString } - if (Test-String $_Switches['SilentWithProgress'] -MaxLength $Patterns.ProgressSwitchMaxLength -AllowNull) { - $script:_returnValue = [ReturnValue]::Success() - } else { - $script:_returnValue = [ReturnValue]::LengthError(1, $Patterns.ProgressSwitchMaxLength) - } - } until ($script:_returnValue.StatusCode -eq [ReturnValue]::Success().StatusCode) - } + if (Test-String $_Switches['SilentWithProgress'] -MaxLength $Patterns.ProgressSwitchMaxLength -NotNull) { + $script:_returnValue = [ReturnValue]::Success() + } elseif ($_Installer['InstallerType'] -ne 'exe' -and (Test-String $_Switches['SilentWithProgress'] -MaxLength $Patterns.ProgressSwitchMaxLength -AllowNull)) { + $script:_returnValue = [ReturnValue]::Success() + } else { + $script:_returnValue = [ReturnValue]::LengthError(1, $Patterns.ProgressSwitchMaxLength) + } + } until ($script:_returnValue.StatusCode -eq [ReturnValue]::Success().StatusCode) # Optional entry of `Custom` switches with validation for all installer types do { From 7b629606abd885996ce0106fc076ee32187b6dc7 Mon Sep 17 00:00:00 2001 From: Kaleb Luedtke Date: Wed, 17 Nov 2021 19:37:40 -0600 Subject: [PATCH 03/13] Fix Null values --- Tools/YamlCreate.ps1 | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/Tools/YamlCreate.ps1 b/Tools/YamlCreate.ps1 index c66d9813c9929..6d4dcadbb4f2a 100644 --- a/Tools/YamlCreate.ps1 +++ b/Tools/YamlCreate.ps1 @@ -526,7 +526,8 @@ Function Read-InstallerEntry { Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() if ($_Installer['InstallerType'] -ieq 'exe') { Write-Host -ForegroundColor 'Green' -Object '[Required] Enter the silent install switch. For example: /S, -verysilent, /qn, --silent, /exenoui' } else { Write-Host -ForegroundColor 'Yellow' -Object '[Optional] Enter the silent install switch. For example: /S, -verysilent, /qn, --silent, /exenoui' } - $_Switches['Silent'] = Read-Host -Prompt 'Silent switch' | TrimString + Read-Host -Prompt 'Silent switch' -OutVariable _ | Out-Null + if ($_) { $_Switches['Silent'] = $_ | TrimString } if (Test-String $_Switches['Silent'] -MaxLength $Patterns.SilentSwitchMaxLength -NotNull) { $script:_returnValue = [ReturnValue]::Success() @@ -540,8 +541,9 @@ Function Read-InstallerEntry { do { Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() if ($_Installer['InstallerType'] -ieq 'exe') { Write-Host -ForegroundColor 'Green' -Object '[Required] Enter the silent with progress install switch. For example: /S, -silent, /qb, /exebasicui' } - else { Write-Host -ForegroundColor 'Yellow' -Object '[Optional] Enter the silent with progress install switch. For example: /S, -silent, /qb, /exebasicui' } - $_Switches['SilentWithProgress'] = Read-Host -Prompt 'Silent with progress switch' | TrimString + else { Write-Host -ForegroundColor 'Yellow' -Object '[Optional] Enter the silent with progress install switch. For example: /S, -silent, /qb, /exebasicui' } + Read-Host -Prompt 'Silent with progress switch' -OutVariable _ | Out-Null + if ($_) { $_Switches['SilentWithProgress'] = $_ | TrimString } if (Test-String $_Switches['SilentWithProgress'] -MaxLength $Patterns.ProgressSwitchMaxLength -NotNull) { $script:_returnValue = [ReturnValue]::Success() @@ -714,24 +716,6 @@ Function Read-InstallerEntry { $script:Installers = @() } - # # Add the installer switches to the installer entry, if they exist - # If ($Silent -or $SilentWithProgress -or $Custom) { - # $_InstallerSwitches = [ordered]@{} - # $_Switches = [ordered] @{ - # 'Custom' = $Custom - # 'Silent' = $Silent - # 'SilentWithProgress' = $SilentWithProgress - # } - # foreach ($_Item in $_Switches.GetEnumerator()) { - # If ($_Item.Value) { Add-YamlParameter -Object $_InstallerSwitches -Parameter $_Item.Name -Value $_Item.Value } - # } - # $_InstallerSwitches = Restore-YamlKeyOrder $_InstallerSwitches $InstallerSwitchProperties -NoComments - # $_Installer['InstallerSwitches'] = $_InstallerSwitches - # } - - # Add the product code to the installer entry, if it exists - # If ($ProductCode) { Add-YamlParameter -Object $_Installer -Parameter 'ProductCode' -Value $ProductCode } - # Add the completed installer to the installers array $_Installer = Restore-YamlKeyOrder $_Installer $InstallerEntryProperties -NoComments $script:Installers += $_Installer From 86dbf042ba510e0e043e9bd7e2f2941ae8bf25ed Mon Sep 17 00:00:00 2001 From: Kaleb Luedtke Date: Wed, 17 Nov 2021 19:48:24 -0600 Subject: [PATCH 04/13] Prevent null checking --- Tools/YamlCreate.ps1 | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/Tools/YamlCreate.ps1 b/Tools/YamlCreate.ps1 index 6d4dcadbb4f2a..07b783c578810 100644 --- a/Tools/YamlCreate.ps1 +++ b/Tools/YamlCreate.ps1 @@ -471,8 +471,6 @@ Function Read-InstallerEntry { Get-UriArchitecture -URI $_Installer['InstallerUrl'] -OutVariable _ | Out-Null if ($_) { $_Installer['Architecture'] = $_ | Select-Object -First 1 } $_Installer['ProductCode'] = $(Get-AppLockerFileInformation -Path $script:dest | Select-Object Publisher | Select-String -Pattern '{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}').Matches - - if ($script:SaveOption -eq '1' -and -not($script:dest -match '\.(msix|appx)(bundle){0,1}$')) { Remove-Item -Path $script:dest } } } # Manual Entry of Sha256 with validation @@ -573,14 +571,14 @@ Function Read-InstallerEntry { if ($_Installer['InstallerType'] -in @('msix'; 'appx')) { # Detect or prompt for Signature Sha256 if (Get-Command 'winget.exe' -ErrorAction SilentlyContinue) { $SignatureSha256 = winget hash -m $script:dest | Select-String -Pattern 'SignatureSha256:' | ConvertFrom-String; if ($SignatureSha256.P2) { $SignatureSha256 = $SignatureSha256.P2.ToUpper() } } - $_Installer['SignatureSha256'] = $SignatureSha256 + if ($SignatureSha256) { $_Installer['SignatureSha256'] = $SignatureSha256 } if (Test-String $_Installer['SignatureSha256'] -IsNull) { # Manual entry of Signature Sha256 with validation do { Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() Write-Host -ForegroundColor 'Yellow' -Object '[Recommended] Enter the installer SignatureSha256' - $_Installer['SignatureSha256'] = Read-Host -Prompt 'SignatureSha256' | TrimString - + Read-Host -Prompt 'SignatureSha256' -OutVariable _ | Out-Null + if ($_) { $_Installer['SignatureSha256'] = $_ | TrimString } if (Test-String $_Installer['SignatureSha256'] -MatchPattern $Patterns.SignatureSha256 -AllowNull) { $script:_returnValue = [ReturnValue]::Success() } else { @@ -610,7 +608,7 @@ Function Read-InstallerEntry { try { Add-AppxPackage -Path $script:dest $InstalledPkg = Get-AppxPackage | Select-Object -Last 1 | Select-Object PackageFamilyName, PackageFullName - $_Installer['PackageFamilyName'] = $InstalledPkg.PackageFamilyName + if ($InstalledPkg.PackageFamilyName) { $_Installer['PackageFamilyName'] = $InstalledPkg.PackageFamilyName } Remove-AppxPackage $InstalledPkg.PackageFullName } catch { # Take no action here, we just want to catch the exceptions as a precaution @@ -628,24 +626,22 @@ Function Read-InstallerEntry { if (($ChoicePfn -ne '0') -or ($script:_returnValue.StatusCode -ne [ReturnValue]::Success().StatusCode)) { Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() Write-Host -ForegroundColor 'Yellow' -Object '[Recommended] Enter the PackageFamilyName' - $_Installer['PackageFamilyName'] = Read-Host -Prompt 'PackageFamilyName' | TrimString + Read-Host -Prompt 'PackageFamilyName' -OutVariable _ | Out-Null + if ($_) { $_Installer['PackageFamilyName'] = $_ | TrimString } } - if (Test-String $_Installer['PackageFamilyName'] -MaxLength $Patterns.FamilyNameMaxLength -MatchPattern $Patterns.FamilyName -AllowNull) { if (Test-String $_Installer['PackageFamilyName'] -IsNull) { $_Installer['PackageFamilyName'] = "$([char]0x2370)" } $script:_returnValue = [ReturnValue]::Success() } else { - if (Test-String -not $PackageFamilyName -MaxLength $Patterns.FamilyNameMaxLength) { + if (Test-String -not $_Installer['PackageFamilyName'] -MaxLength $Patterns.FamilyNameMaxLength) { $script:_returnValue = [ReturnValue]::LengthError(1, $Patterns.FamilyNameMaxLength) - } elseif (Test-String -not $PackageFamilyName -MatchPattern $Patterns.FamilyName) { + } elseif (Test-String -not $_Installer['PackageFamilyName'] -MatchPattern $Patterns.FamilyName) { $script:_returnValue = [ReturnValue]::PatternError() } else { $script:_returnValue = [ReturnValue]::GenericError() } } - } until ($script:_returnValue.StatusCode -eq [ReturnValue]::Success().StatusCode) - if ($script:SaveOption -eq '1') { Remove-Item -Path $script:dest } } # Request installer locale with validation as optional @@ -711,6 +707,8 @@ Function Read-InstallerEntry { default { $_Installer['UpgradeBehavior'] = 'install' } } + if ($script:SaveOption -eq '1') { Remove-Item -Path $script:dest } + # If the installers array is empty, create it if (!$script:Installers) { $script:Installers = @() From fe4ca527c823feff823a8178b81c816e14d7f114 Mon Sep 17 00:00:00 2001 From: Kaleb Luedtke Date: Wed, 17 Nov 2021 20:13:18 -0600 Subject: [PATCH 05/13] Cleanup --- Tools/YamlCreate.ps1 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Tools/YamlCreate.ps1 b/Tools/YamlCreate.ps1 index 07b783c578810..bc742033ba165 100644 --- a/Tools/YamlCreate.ps1 +++ b/Tools/YamlCreate.ps1 @@ -431,7 +431,6 @@ Function Get-UriArchitecture { # Sets the $script:Installers value as an output # Returns void Function Read-InstallerEntry { - $_Installer = [ordered] @{} # Request user enter Installer URL $_Installer['InstallerUrl'] = Request-InstallerUrl @@ -707,7 +706,7 @@ Function Read-InstallerEntry { default { $_Installer['UpgradeBehavior'] = 'install' } } - if ($script:SaveOption -eq '1') { Remove-Item -Path $script:dest } + if ($script:SaveOption -eq '1' -and (Test-Path -Path $script:dest)) { Remove-Item -Path $script:dest } # If the installers array is empty, create it if (!$script:Installers) { @@ -1692,6 +1691,7 @@ Function Write-LocaleManifest { $script:OldLocaleManifest = ConvertFrom-Yaml -Yaml ($(Get-Content -Path $DifLocale.FullName -Encoding UTF8) -join "`n") -Ordered $script:OldLocaleManifest['PackageVersion'] = $PackageVersion if ($script:OldLocaleManifest.Keys -contains 'Moniker') { $script:OldLocaleManifest.Remove('Moniker') } + $script:OldLocaleManifest['ManifestVersion'] = $ManifestVersion $script:OldLocaleManifest = Restore-YamlKeyOrder $script:OldLocaleManifest $LocaleProperties $yamlServer = "# yaml-language-server: $schema=https://aka.ms/winget-manifest.locale.$ManifestVersion.schema.json" @@ -1724,6 +1724,8 @@ function Remove-ManifestVersion { } while (@(Get-ChildItem $PathToVersion).Count -eq 0) } +## START OF MAIN SCRIPT ## + # Initialize the return value to be a success $script:_returnValue = [ReturnValue]::new(200) From 0796e31f497b03297211784b30a6c1b17a861413 Mon Sep 17 00:00:00 2001 From: Kaleb Luedtke Date: Wed, 17 Nov 2021 20:24:42 -0600 Subject: [PATCH 06/13] Fix missed variable --- Tools/YamlCreate.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tools/YamlCreate.ps1 b/Tools/YamlCreate.ps1 index bc742033ba165..2b1939e71ce1f 100644 --- a/Tools/YamlCreate.ps1 +++ b/Tools/YamlCreate.ps1 @@ -361,7 +361,7 @@ Function Get-InstallerFile { ) # Create a filename based on the Package Identifier and Version; Try to get the extension from the URL # If the extension isn't found, use a custom one - $_Filename = "$PackageIdentifier v$PackageVersion" + $(if ([System.IO.Path]::HasExtension($URI)) { [System.IO.Path]::GetExtension($URI) } else { '.winget-tmp' }) + $_Filename = "$PackageIdentifier v$PackageVersion - $(Get-Date -f 'yyyy.MM.dd-hh.mm.ss')" + $(if ([System.IO.Path]::HasExtension($URI)) { [System.IO.Path]::GetExtension($URI) } else { '.winget-tmp' }) $_OutFile = Join-Path -Path $env:TEMP -ChildPath $_Filename # Create a new web client for downloading the file @@ -458,7 +458,7 @@ Function Read-InstallerEntry { Write-Host $NewLine Write-Host 'Downloading URL. This will take a while...' -ForegroundColor Blue try { - $script:dest = Get-InstallerFile -URI $InstallerUrl -PackageIdentifier $PackageIdentifier -PackageVersion $PackageVersion + $script:dest = Get-InstallerFile -URI $_Installer['InstallerUrl'] -PackageIdentifier $PackageIdentifier -PackageVersion $PackageVersion } catch { # Here we also want to pass any exceptions through for potential debugging throw [System.Net.WebException]::new('The file could not be downloaded. Try running the script again', $_.Exception) From 7362d4a33e09366b88757f92782c120df4ca89df Mon Sep 17 00:00:00 2001 From: Kaleb Luedtke Date: Wed, 17 Nov 2021 20:25:20 -0600 Subject: [PATCH 07/13] Bump version --- Tools/YamlCreate.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/YamlCreate.ps1 b/Tools/YamlCreate.ps1 index 2b1939e71ce1f..443cd3acd9ac3 100644 --- a/Tools/YamlCreate.ps1 +++ b/Tools/YamlCreate.ps1 @@ -38,7 +38,7 @@ if ($Settings) { exit } -$ScriptHeader = '# Created with YamlCreate.ps1 v2.0.1' +$ScriptHeader = '# Created with YamlCreate.ps1 v2.0.2' $ManifestVersion = '1.1.0' $PSDefaultParameterValues = @{ '*:Encoding' = 'UTF8' } $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False From b0c70926de7f650fd4220a101aab5ded669d5dfb Mon Sep 17 00:00:00 2001 From: Kaleb Luedtke Date: Wed, 17 Nov 2021 20:30:23 -0600 Subject: [PATCH 08/13] Update function calls --- Tools/YamlCreate.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tools/YamlCreate.ps1 b/Tools/YamlCreate.ps1 index 443cd3acd9ac3..ab8d51770050c 100644 --- a/Tools/YamlCreate.ps1 +++ b/Tools/YamlCreate.ps1 @@ -768,7 +768,7 @@ Function Read-QuickInstallerEntry { $_NewInstaller['InstallerUrl'] = Request-InstallerUrl try { - Get-InstallerFile -URI $_NewInstaller['InstallerUrl'] -PackageIdentifier $PackageIdentifier -PackageVersion $PackageVersion + $script:dest = Get-InstallerFile -URI $_NewInstaller['InstallerUrl'] -PackageIdentifier $PackageIdentifier -PackageVersion $PackageVersion } catch { # Here we also want to pass any exceptions through for potential debugging throw [System.Net.WebException]::new('The file could not be downloaded. Try running the script again', $_.Exception) @@ -2111,7 +2111,7 @@ Switch ($script:Option) { Write-Host 'Updating Manifest Information. This may take a while...' -ForegroundColor Blue foreach ($_Installer in $script:OldInstallerManifest.Installers) { try { - Get-InstallerFile -URI $_Installer.InstallerUrl -PackageIdentifier $PackageIdentifier -PackageVersion $PackageVersion + $script:dest = Get-InstallerFile -URI $_Installer.InstallerUrl -PackageIdentifier $PackageIdentifier -PackageVersion $PackageVersion } catch { # Here we also want to pass any exceptions through for potential debugging throw [System.Net.WebException]::new('The file could not be downloaded. Try running the script again', $_.Exception) From 9be09aae18ab9116cd6a81f7c16830c3514deb47 Mon Sep 17 00:00:00 2001 From: Kaleb Luedtke Date: Thu, 18 Nov 2021 03:31:21 -0600 Subject: [PATCH 09/13] Fix empty ProductCode --- Tools/YamlCreate.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Tools/YamlCreate.ps1 b/Tools/YamlCreate.ps1 index ab8d51770050c..ec3bffa5ad157 100644 --- a/Tools/YamlCreate.ps1 +++ b/Tools/YamlCreate.ps1 @@ -469,7 +469,8 @@ Function Read-InstallerEntry { if ($_) { $_Installer['InstallerType'] = $_ | Select-Object -First 1 } Get-UriArchitecture -URI $_Installer['InstallerUrl'] -OutVariable _ | Out-Null if ($_) { $_Installer['Architecture'] = $_ | Select-Object -First 1 } - $_Installer['ProductCode'] = $(Get-AppLockerFileInformation -Path $script:dest | Select-Object Publisher | Select-String -Pattern '{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}').Matches + $ProductCode = $(Get-AppLockerFileInformation -Path $script:dest | Select-Object Publisher | Select-String -Pattern '{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}').Matches + if (Test-String -Not $ProductCode -IsNull) {$_Installer['ProductCode'] = $ProductCode} } } # Manual Entry of Sha256 with validation @@ -674,7 +675,7 @@ Function Read-InstallerEntry { Write-Host -ForegroundColor 'White' -Object 'Can be found with ' -NoNewline; Write-Host -ForegroundColor 'DarkYellow' 'get-wmiobject Win32_Product | Sort-Object Name | Format-Table IdentifyingNumber, Name -AutoSize' $NewProductCode = Read-Host -Prompt 'ProductCode' | TrimString if (Test-String $NewProductCode -Not -IsNull) { $_Installer['ProductCode'] = $NewProductCode } - else { $_Installer['ProductCode'] = "$($_Installer['ProductCode'])" } + elseif (Test-String $_Installer['ProductCode'] -Not -IsNull) { $_Installer['ProductCode'] = "$($_Installer['ProductCode'])" } if (Test-String $_Installer['ProductCode'] -MinLength $Patterns.ProductCodeMinLength -MaxLength $Patterns.ProductCodeMaxLength -AllowNull) { $script:_returnValue = [ReturnValue]::Success() From 5074e136ec1b41e2ae4c84a54d32fb0a07fc6066 Mon Sep 17 00:00:00 2001 From: Kaleb Luedtke Date: Thu, 18 Nov 2021 10:32:17 -0600 Subject: [PATCH 10/13] Confirm Architecture when Automatically Detected --- Tools/YamlCreate.ps1 | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/Tools/YamlCreate.ps1 b/Tools/YamlCreate.ps1 index ec3bffa5ad157..ec789bc7e55d7 100644 --- a/Tools/YamlCreate.ps1 +++ b/Tools/YamlCreate.ps1 @@ -436,7 +436,8 @@ Function Read-InstallerEntry { $_Installer['InstallerUrl'] = Request-InstallerUrl if ($_Installer.InstallerUrl -in ($script:Installers).InstallerUrl) { - $_MatchingInstaller = $script:Installers | Where-Object { $_.InstallerUrl -eq $InstallerUrl } | Select-Object -First 1 + Write-Host "Found Installer Matching" + $_MatchingInstaller = $script:Installers | Where-Object { $_.InstallerUrl -eq $_Installer.InstallerUrl } | Select-Object -First 1 if ($_MatchingInstaller.InstallerSha256) { $_Installer['InstallerSha256'] = $_MatchingInstaller.InstallerSha256 } if ($_MatchingInstaller.InstallerType) { $_Installer['InstallerType'] = $_MatchingInstaller.InstallerType } if ($_MatchingInstaller.Architecture) { $_Installer['Architecture'] = $_MatchingInstaller.Architecture } @@ -458,7 +459,7 @@ Function Read-InstallerEntry { Write-Host $NewLine Write-Host 'Downloading URL. This will take a while...' -ForegroundColor Blue try { - $script:dest = Get-InstallerFile -URI $_Installer['InstallerUrl'] -PackageIdentifier $PackageIdentifier -PackageVersion $PackageVersion + $script:dest = Get-InstallerFile -URI $_Installer['InstallerUrl'] -PackageIdentifier $PackageIdentifier -PackageVersion $PackageVersion } catch { # Here we also want to pass any exceptions through for potential debugging throw [System.Net.WebException]::new('The file could not be downloaded. Try running the script again', $_.Exception) @@ -470,7 +471,7 @@ Function Read-InstallerEntry { Get-UriArchitecture -URI $_Installer['InstallerUrl'] -OutVariable _ | Out-Null if ($_) { $_Installer['Architecture'] = $_ | Select-Object -First 1 } $ProductCode = $(Get-AppLockerFileInformation -Path $script:dest | Select-Object Publisher | Select-String -Pattern '{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}').Matches - if (Test-String -Not $ProductCode -IsNull) {$_Installer['ProductCode'] = $ProductCode} + if (Test-String -Not "$ProductCode" -IsNull) { $_Installer['ProductCode'] = "$ProductCode" } } } # Manual Entry of Sha256 with validation @@ -491,18 +492,22 @@ Function Read-InstallerEntry { } # Manual Entry of Architecture with validation - if ($_Installer['Architecture'] -CNotIn @($Patterns.ValidArchitectures)) { - do { - Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() - Write-Host -ForegroundColor 'Green' -Object '[Required] Enter the architecture. Options:' , @($Patterns.ValidArchitectures -join ', ') - $_Installer['Architecture'] = Read-Host -Prompt 'Architecture' | TrimString - if ($_Installer['Architecture'] -Cin @($Patterns.ValidArchitectures)) { - $script:_returnValue = [ReturnValue]::Success() - } else { - $script:_returnValue = [ReturnValue]::new(400, 'Invalid Architecture', "Value must exist in the enum - $(@($Patterns.ValidArchitectures -join ', '))", 2) - } - } until ($script:_returnValue.StatusCode -eq [ReturnValue]::Success().StatusCode) - } + do { + Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() + if (Test-String $_Installer['Architecture'] -IsNull) { Write-Host -ForegroundColor 'Green' -Object '[Required] Enter the architecture. Options:' , @($Patterns.ValidArchitectures -join ', ') } + else { + Write-Host -ForegroundColor 'Yellow' -Object '[Optional] Enter the architecture. Options:' , @($Patterns.ValidArchitectures -join ', ') + Write-Host -ForegroundColor 'DarkGray' -Object "Old Variable: $($_Installer['Architecture'])" + } + Read-Host -Prompt 'Architecture' -OutVariable _ | Out-Null + if (Test-String $_ -Not -IsNull) { $_Installer['Architecture'] = $_ | TrimString } + + if ($_Installer['Architecture'] -Cin @($Patterns.ValidArchitectures)) { + $script:_returnValue = [ReturnValue]::Success() + } else { + $script:_returnValue = [ReturnValue]::new(400, 'Invalid Architecture', "Value must exist in the enum - $(@($Patterns.ValidArchitectures -join ', '))", 2) + } + } until ($script:_returnValue.StatusCode -eq [ReturnValue]::Success().StatusCode) # Manual Entry of Installer Type with validation if ($_Installer['InstallerType'] -CNotIn @($Patterns.ValidInstallerTypes)) { @@ -839,7 +844,7 @@ Function Read-InstallerMetadataValue { ) Write-Host -ForegroundColor 'Red' $script:_returnValue.ErrorString() Write-Host -ForegroundColor 'Yellow' -Object $Prompt - if (Test-String -not $Variable -IsNull) { Write-Host -ForegroundColor 'DarkGray' "Old Value: $Variable" } + if (Test-String -not $Variable -IsNull) { Write-Host -ForegroundColor 'DarkGray' "Old Variable: $Variable" } $NewValue = Read-Host -Prompt $Key | TrimString if (Test-String -not $NewValue -IsNull) { From e284382900ec93babe8794cb10d7027b2d39a4a9 Mon Sep 17 00:00:00 2001 From: Kaleb Luedtke Date: Thu, 18 Nov 2021 10:35:25 -0600 Subject: [PATCH 11/13] Remove Debug Line --- Tools/YamlCreate.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/Tools/YamlCreate.ps1 b/Tools/YamlCreate.ps1 index ec789bc7e55d7..ba8af66172e9f 100644 --- a/Tools/YamlCreate.ps1 +++ b/Tools/YamlCreate.ps1 @@ -436,7 +436,6 @@ Function Read-InstallerEntry { $_Installer['InstallerUrl'] = Request-InstallerUrl if ($_Installer.InstallerUrl -in ($script:Installers).InstallerUrl) { - Write-Host "Found Installer Matching" $_MatchingInstaller = $script:Installers | Where-Object { $_.InstallerUrl -eq $_Installer.InstallerUrl } | Select-Object -First 1 if ($_MatchingInstaller.InstallerSha256) { $_Installer['InstallerSha256'] = $_MatchingInstaller.InstallerSha256 } if ($_MatchingInstaller.InstallerType) { $_Installer['InstallerType'] = $_MatchingInstaller.InstallerType } From 9e74f09fe59cc4e91a2d5aaeb6ffb1c16a87515a Mon Sep 17 00:00:00 2001 From: Kaleb Luedtke Date: Thu, 18 Nov 2021 15:28:00 -0600 Subject: [PATCH 12/13] Add duplicate url check for Quick update --- Tools/YamlCreate.ps1 | 105 +++++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 44 deletions(-) diff --git a/Tools/YamlCreate.ps1 b/Tools/YamlCreate.ps1 index ba8af66172e9f..fa52c758b06a7 100644 --- a/Tools/YamlCreate.ps1 +++ b/Tools/YamlCreate.ps1 @@ -760,6 +760,7 @@ Function Read-QuickInstallerEntry { # This is to ensure all previously entered and un-modified parameters are retained $_iteration += 1 $_NewInstaller = $_OldInstaller + $_NewInstaller.Remove('InstallerSha256'); # Show the user which installer entry they should be entering information for Write-Host -ForegroundColor 'Green' "Installer Entry #$_iteration`:`n" @@ -772,53 +773,69 @@ Function Read-QuickInstallerEntry { # Request user enter the new Installer URL $_NewInstaller['InstallerUrl'] = Request-InstallerUrl - try { - $script:dest = Get-InstallerFile -URI $_NewInstaller['InstallerUrl'] -PackageIdentifier $PackageIdentifier -PackageVersion $PackageVersion - } catch { - # Here we also want to pass any exceptions through for potential debugging - throw [System.Net.WebException]::new('The file could not be downloaded. Try running the script again', $_.Exception) - } finally { - # Get the Sha256 - $_NewInstaller['InstallerSha256'] = (Get-FileHash -Path $script:dest -Algorithm SHA256).Hash - # Update the product code, if a new one exists - # If a new product code doesn't exist, and the installer isn't an `.exe` file, remove the product code if it exists - $MSIProductCode = [string]$(Get-AppLockerFileInformation -Path $script:dest | Select-Object Publisher | Select-String -Pattern '{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}').Matches - if (Test-String -not $MSIProductCode -IsNull) { - $_NewInstaller['ProductCode'] = $MSIProductCode - } elseif ( ($_NewInstaller.Keys -contains 'ProductCode') -and ($script:dest -notmatch '.exe$')) { - $_NewInstaller.Remove('ProductCode') - } - # If the installer is msix or appx, try getting the new SignatureSha256 - # If the new SignatureSha256 can't be found, remove it if it exists - if ($_NewInstaller.InstallerType -in @('msix', 'appx')) { - if (Get-Command 'winget.exe' -ErrorAction SilentlyContinue) { $NewSignatureSha256 = winget hash -m $script:dest | Select-String -Pattern 'SignatureSha256:' | ConvertFrom-String; if ($NewSignatureSha256.P2) { $NewSignatureSha256 = $NewSignatureSha256.P2.ToUpper() } } - } - if (Test-String -not $NewSignatureSha256 -IsNull) { - $_NewInstaller['SignatureSha256'] = $NewSignatureSha256 - } elseif ($_NewInstaller.Keys -contains 'SignatureSha256') { - $_NewInstaller.Remove('SignatureSha256') - } - # If the installer is msix or appx, try getting the new package family name - # If the new package family name can't be found, remove it if it exists - if ($script:dest -match '\.(msix|appx)(bundle){0,1}$') { - try { - Add-AppxPackage -Path $script:dest - $InstalledPkg = Get-AppxPackage | Select-Object -Last 1 | Select-Object PackageFamilyName, PackageFullName - $PackageFamilyName = $InstalledPkg.PackageFamilyName - Remove-AppxPackage $InstalledPkg.PackageFullName - } catch { - # Take no action here, we just want to catch the exceptions as a precaution - Out-Null - } finally { - if (Test-String -not $PackageFamilyName -IsNull) { - $_NewInstaller['PackageFamilyName'] = $PackageFamilyName - } elseif ($_NewInstaller.Keys -contains 'PackageFamilyName') { - $_NewInstaller.Remove('PackageFamilyName') + if ($_NewInstaller.InstallerUrl -in ($_NewInstallers).InstallerUrl) { + Write-Host "Matching Installer Foud" + $_MatchingInstaller = $_NewInstallers | Where-Object { $_.InstallerUrl -eq $_NewInstaller.InstallerUrl } | Select-Object -First 1 + if ($_MatchingInstaller.InstallerSha256) { $_NewInstaller['InstallerSha256'] = $_MatchingInstaller.InstallerSha256 } + if ($_MatchingInstaller.InstallerType) { $_NewInstaller['InstallerType'] = $_MatchingInstaller.InstallerType } + if ($_MatchingInstaller.Architecture) { $_NewInstaller['Architecture'] = $_MatchingInstaller.Architecture } + if ($_MatchingInstaller.ProductCode) { $_NewInstaller['ProductCode'] = $_MatchingInstaller.ProductCode } + elseif ( ($_NewInstaller.Keys -contains 'ProductCode') -and ($script:dest -notmatch '.exe$')) { $_NewInstaller.Remove('ProductCode') } + if ($_MatchingInstaller.PackageFamilyName) { $_NewInstaller['PackageFamilyName'] = $_MatchingInstaller.PackageFamilyName } + elseif ($_NewInstaller.Keys -contains 'PackageFamilyName') { $_NewInstaller.Remove('PackageFamilyName') } + if ($_MatchingInstaller.SignatureSha256) { $_NewInstaller['SignatureSha256'] = $_MatchingInstaller.SignatureSha256 } + elseif ($_NewInstaller.Keys -contains 'SignatureSha256') { $_NewInstaller.Remove('SignatureSha256') } + } + + if ($_NewInstaller.Keys -notcontains 'InstallerSha256') { + try { + $script:dest = Get-InstallerFile -URI $_NewInstaller['InstallerUrl'] -PackageIdentifier $PackageIdentifier -PackageVersion $PackageVersion + } catch { + # Here we also want to pass any exceptions through for potential debugging + throw [System.Net.WebException]::new('The file could not be downloaded. Try running the script again', $_.Exception) + } finally { + # Get the Sha256 + $_NewInstaller['InstallerSha256'] = (Get-FileHash -Path $script:dest -Algorithm SHA256).Hash + # Update the product code, if a new one exists + # If a new product code doesn't exist, and the installer isn't an `.exe` file, remove the product code if it exists + $MSIProductCode = [string]$(Get-AppLockerFileInformation -Path $script:dest | Select-Object Publisher | Select-String -Pattern '{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}').Matches + if (Test-String -not $MSIProductCode -IsNull) { + $_NewInstaller['ProductCode'] = $MSIProductCode + } elseif ( ($_NewInstaller.Keys -contains 'ProductCode') -and ($script:dest -notmatch '.exe$')) { + $_NewInstaller.Remove('ProductCode') + } + # If the installer is msix or appx, try getting the new SignatureSha256 + # If the new SignatureSha256 can't be found, remove it if it exists + if ($_NewInstaller.InstallerType -in @('msix', 'appx')) { + if (Get-Command 'winget.exe' -ErrorAction SilentlyContinue) { $NewSignatureSha256 = winget hash -m $script:dest | Select-String -Pattern 'SignatureSha256:' | ConvertFrom-String; if ($NewSignatureSha256.P2) { $NewSignatureSha256 = $NewSignatureSha256.P2.ToUpper() } } + } + if (Test-String -not $NewSignatureSha256 -IsNull) { + $_NewInstaller['SignatureSha256'] = $NewSignatureSha256 + } elseif ($_NewInstaller.Keys -contains 'SignatureSha256') { + $_NewInstaller.Remove('SignatureSha256') + } + # If the installer is msix or appx, try getting the new package family name + # If the new package family name can't be found, remove it if it exists + if ($script:dest -match '\.(msix|appx)(bundle){0,1}$') { + try { + Add-AppxPackage -Path $script:dest + $InstalledPkg = Get-AppxPackage | Select-Object -Last 1 | Select-Object PackageFamilyName, PackageFullName + $PackageFamilyName = $InstalledPkg.PackageFamilyName + Remove-AppxPackage $InstalledPkg.PackageFullName + } catch { + # Take no action here, we just want to catch the exceptions as a precaution + Out-Null + } finally { + if (Test-String -not $PackageFamilyName -IsNull) { + $_NewInstaller['PackageFamilyName'] = $PackageFamilyName + } elseif ($_NewInstaller.Keys -contains 'PackageFamilyName') { + $_NewInstaller.Remove('PackageFamilyName') + } } } + # Remove the downloaded files + Remove-Item -Path $script:dest } - # Remove the downloaded files - Remove-Item -Path $script:dest } #Add the updated installer to the new installers array $_NewInstaller = Restore-YamlKeyOrder $_NewInstaller $InstallerEntryProperties -NoComments From b51d5e673fbdc468ac14f923be664cf884df6682 Mon Sep 17 00:00:00 2001 From: Kaleb Luedtke Date: Fri, 19 Nov 2021 10:26:38 -0600 Subject: [PATCH 13/13] Remove line used in debugging --- Tools/YamlCreate.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/Tools/YamlCreate.ps1 b/Tools/YamlCreate.ps1 index fa52c758b06a7..020b4d1abf9ae 100644 --- a/Tools/YamlCreate.ps1 +++ b/Tools/YamlCreate.ps1 @@ -774,7 +774,6 @@ Function Read-QuickInstallerEntry { $_NewInstaller['InstallerUrl'] = Request-InstallerUrl if ($_NewInstaller.InstallerUrl -in ($_NewInstallers).InstallerUrl) { - Write-Host "Matching Installer Foud" $_MatchingInstaller = $_NewInstallers | Where-Object { $_.InstallerUrl -eq $_NewInstaller.InstallerUrl } | Select-Object -First 1 if ($_MatchingInstaller.InstallerSha256) { $_NewInstaller['InstallerSha256'] = $_MatchingInstaller.InstallerSha256 } if ($_MatchingInstaller.InstallerType) { $_NewInstaller['InstallerType'] = $_MatchingInstaller.InstallerType }