Capa.PowerShell.Module.PowerPack.Winget.psm1
<# .SYNOPSIS Set the winget scope to machine .DESCRIPTION Set the winget scope to machine .EXAMPLE Add-PpWingetScopeMachine .NOTES Custom function not from CapaSystems. Idea from: https://github.com/Romanitho/Winget-Install/blob/main/winget-install.ps1 #> function Add-PpWingetScopeMachine { $Function = 'Add-PpWingetScopeMachine' #Get Settings path for system or current user if ([System.Security.Principal.WindowsIdentity]::GetCurrent().IsSystem) { $SettingsPath = "$global:gsWindowsDir\System32\config\systemprofile\AppData\Local\Microsoft\WinGet\Settings\defaultState\settings.json" } else { $SettingsPath = "$env:LOCALAPPDATA\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\settings.json" } Job_WriteLog -Text "SettingsPath: $SettingsPath" -FunctionName $Function $ConfigFile = @{} #Check if setting file exist, if not create it if (Test-Path $SettingsPath) { $ConfigFile = Get-Content -Path $SettingsPath | Where-Object { $_ -notmatch '//' } | ConvertFrom-Json Job_WriteLog -Text 'The config file exists' -FunctionName $Function } else { New-Item -Path $SettingsPath -Force | Out-Null Job_WriteLog -Text 'The config file does not exist, creating it' -FunctionName $Function } if ($ConfigFile.installBehavior.preferences) { Add-Member -InputObject $ConfigFile.installBehavior.preferences -MemberType NoteProperty -Name 'scope' -Value 'Machine' -Force } else { $Scope = New-Object PSObject -Property $(@{scope = 'Machine' }) $Preference = New-Object PSObject -Property $(@{preferences = $Scope }) Add-Member -InputObject $ConfigFile -MemberType NoteProperty -Name 'installBehavior' -Value $Preference -Force } $ConfigFile | ConvertTo-Json | Out-File $SettingsPath -Encoding utf8 -Force Job_WriteLog -Text 'Scope set to Machine' -FunctionName $Function } <# .SYNOPSIS Confirm if an app is installed. .DESCRIPTION Confirm if an app is installed. Returns $true if the app is installed, otherwise $false. .PARAMETER AppId The AppId of the app to confirm. .PARAMETER WingetPath The path to the winget executable. If not provided, the function will try to find the winget executable. .EXAMPLE Confirm-PpWingetAppInstall -AppId 'Microsoft.VisualStudioCode' .NOTES Custom function not from CapaSystems. Idea from: https://github.com/Romanitho/Winget-Install/blob/main/winget-install.ps1 #> function Confirm-PpWingetAppInstall { param ( [Parameter(Mandatory = $true)] [string]$AppId, [Parameter(Mandatory = $false)] [string]$WingetPath ) $Function = 'Confirm-PpWingetAppInstall' if ([string]::IsNullOrEmpty($WingetPath)) { $Winget = Find-PpWinGetCmd } else { $Winget = $WingetPath } #Get "Winget List AppID" $InstalledApp = & $winget list --Id $AppID -e --accept-source-agreements -s winget | Out-String #Return if AppID exists in the list if ($InstalledApp -match [regex]::Escape($AppID)) { return $true } else { return $false } } <# .SYNOPSIS Find the path to the WinGet executable. .DESCRIPTION Find the path to the WinGet executable. If the WinGet executable is not found, the function will return $false. .PARAMETER AllowInstallOfWinGet If set to $true, the function will try to install or update WinGet if it is not found or if the version is outdated. .EXAMPLE $WingetPath = Find-PpWinGetCmd .EXAMPLE $WingetPath = Find-PpWinGetCmd -AllowInstallOfWinGet $true .NOTES Custom function not from CapaSystems. Idea from: https://github.com/Romanitho/Winget-Install/blob/main/winget-install.ps1 #> function Find-PpWinGetCmd { [CmdletBinding()] param ( ) $FunctionName = 'Find-WinGet' $WingetCmd = $false if ($global:gsOsSystem -like '*server*') { Job_WriteLog -Text 'WinGet is not supported on server OS' -FunctionName $FunctionName return $false } #Get WinGet Path try { #Get Admin Context Winget Location $WingetInfo = (Get-Item "$env:ProgramFiles\WindowsApps\Microsoft.DesktopAppInstaller_*_8wekyb3d8bbwe\winget.exe").VersionInfo | Sort-Object -Property FileVersionRaw #If multiple versions, pick most recent one $WingetCmd = $WingetInfo[-1].FileName } catch { #Get User context Winget Location if (Test-Path "$env:LocalAppData\Microsoft\WindowsApps\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\winget.exe") { $WingetCmd = "$env:LocalAppData\Microsoft\WindowsApps\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\winget.exe" } } Job_WriteLog -Text "WingetCmd: $WingetCmd" -FunctionName $FunctionName return $WingetCmd } <# .SYNOPSIS Get the error message for a WinGet error code. .DESCRIPTION Get the error message for a WinGet error code. .PARAMETER Decimal The error code in decimal. .EXAMPLE Get-PpWingetReturnCodeDescription -Decimal -1978335231 .NOTES Custom function not from CapaSystems. Source: https://github.com/microsoft/winget-cli/blob/master/doc/windows/package-manager/winget/returnCodes.md #> function Get-PpWingetReturnCodeDescription { param ( [Parameter(Mandatory = $true)] [int]$Decimal ) switch ($Decimal) { 0 { Job_WriteLog -Text 'Command completed successfully' return 'Command completed successfully' } -1978335231 { Job_WriteLog -Text 'Internal Error' return 'Internal Error' } -1978335230 { Job_WriteLog -Text 'Invalid command line arguments' return 'Invalid command line arguments' } -1978335229 { Job_WriteLog -Text 'Executing command failed' return 'Executing command failed' } -1978335228 { Job_WriteLog -Text 'Opening manifest failed' return 'Opening manifest failed' } -1978335227 { Job_WriteLog -Text 'Cancellation signal received' return 'Cancellation signal received' } -1978335226 { Job_WriteLog -Text 'Running ShellExecute failed' return 'Running ShellExecute failed' } -1978335225 { Job_WriteLog -Text 'Cannot process manifest. The manifest version is higher than supported. Please update the client.' return 'Cannot process manifest. The manifest version is higher than supported. Please update the client.' } -1978335224 { Job_WriteLog -Text 'Downloading installer failed' return 'Downloading installer failed' } -1978335223 { Job_WriteLog -Text 'Cannot write to index; it is a higher schema version' return 'Cannot write to index; it is a higher schema version' } -1978335222 { Job_WriteLog -Text 'The index is corrupt' return 'The index is corrupt' } -1978335221 { Job_WriteLog -Text 'The configured source information is corrupt' return 'The configured source information is corrupt' } -1978335220 { Job_WriteLog -Text 'The source name is already configured' return 'The source name is already configured' } -1978335219 { Job_WriteLog -Text 'The source type is invalid' return 'The source type is invalid' } -1978335218 { Job_WriteLog -Text 'The MSIX file is a bundle, not a package' return 'The MSIX file is a bundle, not a package' } -1978335217 { Job_WriteLog -Text 'Data required by the source is missing' return 'Data required by the source is missing' } -1978335216 { Job_WriteLog -Text 'None of the installers are applicable for the current system' return 'None of the installers are applicable for the current system' } -1978335215 { Job_WriteLog -Text 'The installer file''s hash does not match the manifest' return 'The installer file''s hash does not match the manifest' } -1978335214 { Job_WriteLog -Text 'The source name does not exist' return 'The source name does not exist' } -1978335213 { Job_WriteLog -Text 'The source location is already configured under another name' return 'The source location is already configured under another name' } -1978335212 { Job_WriteLog -Text 'No packages found' return 'No packages found' } -1978335211 { Job_WriteLog -Text 'No sources are configured' return 'No sources are configured' } -1978335210 { Job_WriteLog -Text 'Multiple packages found matching the criteria' return 'Multiple packages found matching the criteria' } -1978335209 { Job_WriteLog -Text 'No manifest found matching the criteria' return 'No manifest found matching the criteria' } -1978335208 { Job_WriteLog -Text 'Failed to get Public folder from source package' return 'Failed to get Public folder from source package' } -1978335207 { Job_WriteLog -Text 'Command requires administrator privileges to run' return 'Command requires administrator privileges to run' } -1978335206 { Job_WriteLog -Text 'The source location is not secure' return 'The source location is not secure' } -1978335205 { Job_WriteLog -Text 'The Microsoft Store client is blocked by policy' return 'The Microsoft Store client is blocked by policy' } -1978335204 { Job_WriteLog -Text 'The Microsoft Store app is blocked by policy' return 'The Microsoft Store app is blocked by policy' } -1978335203 { Job_WriteLog -Text 'The feature is currently under development. It can be enabled using winget settings.' return 'The feature is currently under development. It can be enabled using winget settings.' } -1978335202 { Job_WriteLog -Text 'Failed to install the Microsoft Store app' return 'Failed to install the Microsoft Store app' } -1978335201 { Job_WriteLog -Text 'Failed to perform auto complete' return 'Failed to perform auto complete' } -1978335200 { Job_WriteLog -Text 'Failed to initialize YAML parser' return 'Failed to initialize YAML parser' } -1978335199 { Job_WriteLog -Text 'Encountered an invalid YAML key' return 'Encountered an invalid YAML key' } -1978335198 { Job_WriteLog -Text 'Encountered a duplicate YAML key' return 'Encountered a duplicate YAML key' } -1978335197 { Job_WriteLog -Text 'Invalid YAML operation' return 'Invalid YAML operation' } -1978335196 { Job_WriteLog -Text 'Failed to build YAML doc' return 'Failed to build YAML doc' } -1978335195 { Job_WriteLog -Text 'Invalid YAML emitter state' return 'Invalid YAML emitter state' } -1978335194 { Job_WriteLog -Text 'Invalid YAML data' return 'Invalid YAML data' } -1978335193 { Job_WriteLog -Text 'LibYAML error' return 'LibYAML error' } -1978335192 { Job_WriteLog -Text 'Manifest validation succeeded with warning' return 'Manifest validation succeeded with warning' } -1978335191 { Job_WriteLog -Text 'Manifest validation failed' return 'Manifest validation failed' } -1978335190 { Job_WriteLog -Text 'Manifest is invalid' return 'Manifest is invalid' } -1978335189 { Job_WriteLog -Text 'No applicable update found' return 'No applicable update found' } -1978335188 { Job_WriteLog -Text 'winget upgrade --all completed with failures' return 'winget upgrade --all completed with failures' } -1978335187 { Job_WriteLog -Text 'Installer failed security check' return 'Installer failed security check' } -1978335186 { Job_WriteLog -Text 'Download size does not match expected content length' return 'Download size does not match expected content length' } -1978335185 { Job_WriteLog -Text 'Uninstall command not found' return 'Uninstall command not found' } -1978335184 { Job_WriteLog -Text 'Running uninstall command failed' return 'Running uninstall command failed' } -1978335183 { Job_WriteLog -Text 'ICU break iterator error' return 'ICU break iterator error' } -1978335182 { Job_WriteLog -Text 'ICU casemap error' return 'ICU casemap error' } -1978335181 { Job_WriteLog -Text 'ICU regex error' return 'ICU regex error' } -1978335180 { Job_WriteLog -Text 'Failed to install one or more imported packages' return 'Failed to install one or more imported packages' } -1978335179 { Job_WriteLog -Text 'Could not find one or more requested packages' return 'Could not find one or more requested packages' } -1978335178 { Job_WriteLog -Text 'Json file is invalid' return 'Json file is invalid' } -1978335177 { Job_WriteLog -Text 'The source location is not remote' return 'The source location is not remote' } -1978335176 { Job_WriteLog -Text 'The configured rest source is not supported' return 'The configured rest source is not supported' } -1978335175 { Job_WriteLog -Text 'Invalid data returned by rest source' return 'Invalid data returned by rest source' } -1978335174 { Job_WriteLog -Text 'Operation is blocked by Group Policy' return 'Operation is blocked by Group Policy' } -1978335173 { Job_WriteLog -Text 'Rest source internal error' return 'Rest source internal error' } -1978335172 { Job_WriteLog -Text 'Invalid rest source url' return 'Invalid rest source url' } -1978335171 { Job_WriteLog -Text 'Unsupported MIME type returned by rest source' return 'Unsupported MIME type returned by rest source' } -1978335170 { Job_WriteLog -Text 'Invalid rest source contract version' return 'Invalid rest source contract version' } -1978335169 { Job_WriteLog -Text 'The source data is corrupted or tampered' return 'The source data is corrupted or tampered' } -1978335168 { Job_WriteLog -Text 'Error reading from the stream' return 'Error reading from the stream' } -1978335167 { Job_WriteLog -Text 'Package agreements were not agreed to' return 'Package agreements were not agreed to' } -1978335166 { Job_WriteLog -Text 'Error reading input in prompt' return 'Error reading input in prompt' } -1978335165 { Job_WriteLog -Text 'The search request is not supported by one or more sources' return 'The search request is not supported by one or more sources' } -1978335164 { Job_WriteLog -Text 'The rest source endpoint is not found.' return 'The rest source endpoint is not found.' } -1978335163 { Job_WriteLog -Text 'Failed to open the source.' return 'Failed to open the source.' } -1978335162 { Job_WriteLog -Text 'Source agreements were not agreed to' return 'Source agreements were not agreed to' } -1978335161 { Job_WriteLog -Text 'Header size exceeds the allowable limit of 1024 characters. Please reduce the size and try again.' return 'Header size exceeds the allowable limit of 1024 characters. Please reduce the size and try again.' } -1978335160 { Job_WriteLog -Text 'Missing resource file' return 'Missing resource file' } -1978335159 { Job_WriteLog -Text 'Running MSI install failed' return 'Running MSI install failed' } -1978335158 { Job_WriteLog -Text 'Arguments for msiexec are invalid' return 'Arguments for msiexec are invalid' } -1978335157 { Job_WriteLog -Text 'Failed to open one or more sources' return 'Failed to open one or more sources' } -1978335156 { Job_WriteLog -Text 'Failed to validate dependencies' return 'Failed to validate dependencies' } -1978335155 { Job_WriteLog -Text 'One or more package is missing' return 'One or more package is missing' } -1978335154 { Job_WriteLog -Text 'Invalid table column' return 'Invalid table column' } -1978335153 { Job_WriteLog -Text 'The upgrade version is not newer than the installed version' return 'The upgrade version is not newer than the installed version' } -1978335152 { Job_WriteLog -Text 'Upgrade version is unknown and override is not specified' return 'Upgrade version is unknown and override is not specified' } -1978335151 { Job_WriteLog -Text 'ICU conversion error' return 'ICU conversion error' } -1978335150 { Job_WriteLog -Text 'Failed to install portable package' return 'Failed to install portable package' } -1978335149 { Job_WriteLog -Text 'Volume does not support reparse points.' return 'Volume does not support reparse points.' } -1978335148 { Job_WriteLog -Text 'Portable package from a different source already exists.' return 'Portable package from a different source already exists.' } -1978335147 { Job_WriteLog -Text 'Unable to create symlink, path points to a directory.' return 'Unable to create symlink, path points to a directory.' } -1978335146 { Job_WriteLog -Text 'The installer cannot be run from an administrator context.' return 'The installer cannot be run from an administrator context.' } -1978335145 { Job_WriteLog -Text 'Failed to uninstall portable package' return 'Failed to uninstall portable package' } -1978335144 { Job_WriteLog -Text 'Failed to validate DisplayVersion values against index.' return 'Failed to validate DisplayVersion values against index.' } -1978335143 { Job_WriteLog -Text 'One or more arguments are not supported.' return 'One or more arguments are not supported.' } -1978335142 { Job_WriteLog -Text 'Embedded null characters are disallowed for SQLite' return 'Embedded null characters are disallowed for SQLite' } -1978335141 { Job_WriteLog -Text 'Failed to find the nested installer in the archive.' return 'Failed to find the nested installer in the archive.' } -1978335140 { Job_WriteLog -Text 'Failed to extract archive.' return 'Failed to extract archive.' } -1978335139 { Job_WriteLog -Text 'Invalid relative file path to nested installer provided.' return 'Invalid relative file path to nested installer provided.' } -1978335138 { Job_WriteLog -Text 'The server certificate did not match any of the expected values.' return 'The server certificate did not match any of the expected values.' } -1978335137 { Job_WriteLog -Text 'Install location must be provided.' return 'Install location must be provided.' } -1978335136 { Job_WriteLog -Text 'Archive malware scan failed.' return 'Archive malware scan failed.' } -1978335135 { Job_WriteLog -Text 'Found at least one version of the package installed.' return 'Found at least one version of the package installed.' } -1978335134 { Job_WriteLog -Text 'A pin already exists for the package.' return 'A pin already exists for the package.' } -1978335133 { Job_WriteLog -Text 'There is no pin for the package.' return 'There is no pin for the package.' } -1978335132 { Job_WriteLog -Text 'Unable to open the pin database.' return 'Unable to open the pin database.' } -1978335131 { Job_WriteLog -Text 'One or more applications failed to install' return 'One or more applications failed to install' } -1978335130 { Job_WriteLog -Text 'One or more applications failed to uninstall' return 'One or more applications failed to uninstall' } -1978335129 { Job_WriteLog -Text 'One or more queries did not return exactly one match' return 'One or more queries did not return exactly one match' } -1978335128 { Job_WriteLog -Text 'The package has a pin that prevents upgrade.' return 'The package has a pin that prevents upgrade.' } -1978335127 { Job_WriteLog -Text 'The package currently installed is the stub package' return 'The package currently installed is the stub package' } -1978335126 { Job_WriteLog -Text 'Application shutdown signal received' return 'Application shutdown signal received' } -1978335125 { Job_WriteLog -Text 'Failed to download package dependencies.' return 'Failed to download package dependencies.' } -1978335124 { Job_WriteLog -Text 'Failed to download package. Download for offline installation is prohibited.' return 'Failed to download package. Download for offline installation is prohibited.' } -1978335123 { Job_WriteLog -Text 'A required service is busy or unavailable. Try again later.' return 'A required service is busy or unavailable. Try again later.' } -1978335122 { Job_WriteLog -Text 'The guid provided does not correspond to a valid resume state.' return 'The guid provided does not correspond to a valid resume state.' } -1978335121 { Job_WriteLog -Text 'The current client version did not match the client version of the saved state.' return 'The current client version did not match the client version of the saved state.' } -1978335120 { Job_WriteLog -Text 'The resume state data is invalid.' return 'The resume state data is invalid.' } -1978335119 { Job_WriteLog -Text 'Unable to open the checkpoint database.' return 'Unable to open the checkpoint database.' } -1978335118 { Job_WriteLog -Text 'Exceeded max resume limit.' return 'Exceeded max resume limit.' } -1978335117 { Job_WriteLog -Text 'Invalid authentication info.' return 'Invalid authentication info.' } -1978335116 { Job_WriteLog -Text 'Authentication method not supported.' return 'Authentication method not supported.' } -1978335115 { Job_WriteLog -Text 'Authentication failed.' return 'Authentication failed.' } -1978335114 { Job_WriteLog -Text 'Authentication failed. Interactive authentication required.' return 'Authentication failed. Interactive authentication required.' } -1978335113 { Job_WriteLog -Text 'Authentication failed. User cancelled.' return 'Authentication failed. User cancelled.' } -1978335112 { Job_WriteLog -Text 'Authentication failed. Authenticated account is not the desired account.' return 'Authentication failed. Authenticated account is not the desired account.' } -1978335111 { Job_WriteLog -Text 'Repair command not found.' return 'Repair command not found.' } -1978335110 { Job_WriteLog -Text 'Repair operation is not applicable.' return 'Repair operation is not applicable.' } -1978335109 { Job_WriteLog -Text 'Repair operation failed.' return 'Repair operation failed.' } -1978335108 { Job_WriteLog -Text 'The installer technology in use doesn''t support repair.' return 'The installer technology in use doesn''t support repair.' } -1978335107 { Job_WriteLog -Text 'Repair operations involving administrator privileges are not permitted on packages installed within the user scope.' return 'Repair operations involving administrator privileges are not permitted on packages installed within the user scope.' } -1978334975 { Job_WriteLog -Text 'Application is currently running. Exit the application then try again.' return 'Application is currently running. Exit the application then try again.' } -1978334974 { Job_WriteLog -Text 'Another installation is already in progress. Try again later.' return 'Another installation is already in progress. Try again later.' } -1978334973 { Job_WriteLog -Text 'One or more file is being used. Exit the application then try again.' return 'One or more file is being used. Exit the application then try again.' } -1978334972 { Job_WriteLog -Text 'This package has a dependency missing from your system.' return 'This package has a dependency missing from your system.' } -1978334971 { Job_WriteLog -Text 'There''s no more space on your PC. Make space, then try again.' return 'There''s no more space on your PC. Make space, then try again.' } -1978334970 { Job_WriteLog -Text 'There''s not enough memory available to install. Close other applications then try again.' return 'There''s not enough memory available to install. Close other applications then try again.' } -1978334969 { Job_WriteLog -Text 'This application requires internet connectivity. Connect to a network then try again.' return 'This application requires internet connectivity. Connect to a network then try again.' } -1978334968 { Job_WriteLog -Text 'This application encountered an error during installation. Contact support.' return 'This application encountered an error during installation. Contact support.' } -1978334967 { Job_WriteLog -Text 'Restart your PC to finish installation.' return 'Restart your PC to finish installation.' } -1978334966 { Job_WriteLog -Text 'Installation failed. Restart your PC then try again.' return 'Installation failed. Restart your PC then try again.' } -1978334965 { Job_WriteLog -Text 'Your PC will restart to finish installation.' return 'Your PC will restart to finish installation.' } -1978334964 { Job_WriteLog -Text 'You cancelled the installation.' return 'You cancelled the installation.' } -1978334963 { Job_WriteLog -Text 'Another version of this application is already installed.' return 'Another version of this application is already installed.' } -1978334962 { Job_WriteLog -Text 'A higher version of this application is already installed.' return 'A higher version of this application is already installed.' } -1978334961 { Job_WriteLog -Text 'Organization policies are preventing installation. Contact your admin.' return 'Organization policies are preventing installation. Contact your admin.' } -1978334960 { Job_WriteLog -Text 'Failed to install package dependencies.' return 'Failed to install package dependencies.' } -1978334959 { Job_WriteLog -Text 'Application is currently in use by another application.' return 'Application is currently in use by another application.' } -1978334958 { Job_WriteLog -Text 'Invalid parameter.' return 'Invalid parameter.' } -1978334957 { Job_WriteLog -Text 'Package not supported by the system.' return 'Package not supported by the system.' } -1978334956 { Job_WriteLog -Text 'The installer does not support upgrading an existing package.' return 'The installer does not support upgrading an existing package.' } -1978334719 { Job_WriteLog -Text 'The Apps and Features Entry for the package could not be found.' return 'The Apps and Features Entry for the package could not be found.' } -1978334718 { Job_WriteLog -Text 'The install location is not applicable.' return 'The install location is not applicable.' } -1978334717 { Job_WriteLog -Text 'The install location could not be found.' return 'The install location could not be found.' } -1978334716 { Job_WriteLog -Text 'The hash of the existing file did not match.' return 'The hash of the existing file did not match.' } -1978334715 { Job_WriteLog -Text 'File not found.' return 'File not found.' } -1978334714 { Job_WriteLog -Text 'The file was found but the hash was not checked.' return 'The file was found but the hash was not checked.' } -1978334713 { Job_WriteLog -Text 'The file could not be accessed.' return 'The file could not be accessed.' } -1978286079 { Job_WriteLog -Text 'The configuration file is invalid.' return 'The configuration file is invalid.' } -1978286078 { Job_WriteLog -Text 'The YAML syntax is invalid.' return 'The YAML syntax is invalid.' } -1978286077 { Job_WriteLog -Text 'A configuration field has an invalid type.' return 'A configuration field has an invalid type.' } -1978286076 { Job_WriteLog -Text 'The configuration has an unknown version.' return 'The configuration has an unknown version.' } -1978286075 { Job_WriteLog -Text 'An error occurred while applying the configuration.' return 'An error occurred while applying the configuration.' } -1978286074 { Job_WriteLog -Text 'The configuration contains a duplicate identifier.' return 'The configuration contains a duplicate identifier.' } -1978286073 { Job_WriteLog -Text 'The configuration is missing a dependency.' return 'The configuration is missing a dependency.' } -1978286072 { Job_WriteLog -Text 'The configuration has an unsatisfied dependency.' return 'The configuration has an unsatisfied dependency.' } -1978286071 { Job_WriteLog -Text 'An assertion for the configuration unit failed.' return 'An assertion for the configuration unit failed.' } -1978286070 { Job_WriteLog -Text 'The configuration was manually skipped.' return 'The configuration was manually skipped.' } -1978286069 { Job_WriteLog -Text 'A warning was thrown and the user declined to continue execution.' return 'A warning was thrown and the user declined to continue execution.' } -1978286068 { Job_WriteLog -Text 'The dependency graph contains a cycle which cannot be resolved.' return 'The dependency graph contains a cycle which cannot be resolved.' } -1978286067 { Job_WriteLog -Text 'The configuration has an invalid field value.' return 'The configuration has an invalid field value.' } -1978286066 { Job_WriteLog -Text 'The configuration is missing a field.' return 'The configuration is missing a field.' } -1978285823 { Job_WriteLog -Text 'The configuration unit was not installed.' return 'The configuration unit was not installed.' } -1978285822 { Job_WriteLog -Text 'The configuration unit could not be found.' return 'The configuration unit could not be found.' } -1978285821 { Job_WriteLog -Text 'Multiple matches were found for the configuration unit specify the module to select the correct one.' return 'Multiple matches were found for the configuration unit specify the module to select the correct one.' } -1978285820 { Job_WriteLog -Text 'The configuration unit failed while attempting to get the current system state.' return 'The configuration unit failed while attempting to get the current system state.' } -1978285819 { Job_WriteLog -Text 'The configuration unit failed while attempting to test the current system state.' return 'The configuration unit failed while attempting to test the current system state.' } -1978285818 { Job_WriteLog -Text 'The configuration unit failed while attempting to apply the desired state.' return 'The configuration unit failed while attempting to apply the desired state.' } -1978285817 { Job_WriteLog -Text 'The module for the configuration unit is available in multiple locations with the same version.' return 'The module for the configuration unit is available in multiple locations with the same version.' } -1978285816 { Job_WriteLog -Text 'Loading the module for the configuration unit failed.' return 'Loading the module for the configuration unit failed.' } -1978285815 { Job_WriteLog -Text 'The configuration unit returned an unexpected result during execution.' return 'The configuration unit returned an unexpected result during execution.' } -1978285814 { Job_WriteLog -Text 'A unit contains a setting that requires the config root.' return 'A unit contains a setting that requires the config root.' } -1978285813 { Job_WriteLog -Text 'Loading the module for the configuration unit failed because it requires administrator privileges to run.' return 'Loading the module for the configuration unit failed because it requires administrator privileges to run.' } default { Job_WriteLog -Text "Exiting with status: $Result" return "Unknown error code: $Result" } } } <# .SYNOPSIS Install an application using winget .DESCRIPTION Install an application using winget .PARAMETER Id The id of the application to install. You can find all the available applications on https://winget.run .PARAMETER Locale The locale to use for the installation, for example 'da-DK' .PARAMETER AllowInstallOfWinGet Allow the installation of winget if it is not installed. Or update winget if it is installed. .EXAMPLE Install-PpWingetApp -Id 'Mozilla.Firefox' .EXAMPLE Install-PpWingetApp -Id 'Mozilla.Firefox' -Locale 'da-DK' .EXAMPLE Install-PpWingetApp -Id 'Mozilla.Firefox' -AllowInstallOfWinGet $true .NOTES Custom function not from CapaSystems. Idea from: https://github.com/Romanitho/Winget-Install/blob/main/winget-install.ps1 #> function Install-PpWingetApp { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$AppId, [Parameter(Mandatory = $false)] [string]$Locale, [Parameter(Mandatory = $false)] [bool]$AllowInstallOfWinGet = $false ) $FunctionName = 'Install-PpWingetApp' $WingetPath = Find-PpWinGetCmd $InstallCommand = "install -e --id $AppId -h --accept-package-agreements --accept-source-agreements --force" if ($Locale) { $InstallCommand += " --locale $Locale" } if ($AllowInstallOfWinGet) { Install-PpWingetPrerequisites -WingetPath $WingetPath $WingetPath = Find-PpWinGetCmd } if ($WingetPath -eq $false) { Job_WriteLog -Text 'Winget not found' -FunctionName $FunctionName Exit-PpPackageFailedInstall -ExitMessage 'Winget not found' } Add-PpWingetScopeMachine $ExecuteSplatting = @{ Command = $WingetPath Arguments = $InstallCommand Wait = $true WindowStyle = 'Hidden' MustExist = $true } $Result = Shell_Execute @ExecuteSplatting $Text = Get-PpWingetReturnCodeDescription -Decimal $Result Job_WriteLog -Text "Command completed with status: $Result" -FunctionName $FunctionName $AppInstalled = Confirm-PpWingetAppInstall -AppId $AppId if ($AppInstalled) { Job_WriteLog -Text "$AppId was installed" -FunctionName $FunctionName } else { Job_WriteLog -Text "$AppId was not installed" -FunctionName $FunctionName Exit-PpCommandFailed -ExitMessage "$AppId was not installed" } return $Result } <# .SYNOPSIS Install prerequisites for winget .DESCRIPTION Install prerequisites for winget .NOTES Custom function not from CapaSystems. Idea from: https://github.com/Romanitho/Winget-Install/blob/main/winget-install.ps1 #> function Install-PpWingetPrerequisites { param ( [Parameter(Mandatory = $false)] [string]$WingetPath ) $Function = 'Install-PpWingetPrerequisites' <# Sometimes does the modules is not import the functions correctly, so we try to import it again. If it fails, then we try to import it with the Windows PowerShell. If that also fails, then keep going. #> try { Import-Module Appx } catch { Import-Module Appx -UseWindowsPowerShell } if ([string]::IsNullOrEmpty($WingetPath)) { $Winget = Find-PpWinGetCmd } else { $Winget = $WingetPath } Job_WriteLog -Text '###############################################' -FunctionName $Function Job_WriteLog -Text 'Checking prerequisites for winget' -FunctionName $Function #region Check if Visual C++ 2019 or 2022 installed $Visual2019 = 'Microsoft Visual C++ 2015-2019 Redistributable*' $Visual2022 = 'Microsoft Visual C++ 2015-2022 Redistributable*' $path = Get-Item HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object { $_.GetValue('DisplayName') -like $Visual2019 -or $_.GetValue('DisplayName') -like $Visual2022 } Job_WriteLog -Text "Visual C++ 2019 or 2022: $path" -FunctionName $Function #If not installed, download and install if (!($path)) { #region Download and install try { $SourceURL = "https://aka.ms/vs/17/release/VC_redist.$global:gsOsArchitechture.exe" $Installer = Join-Path $Global:TempFolder "\VC_redist.$global:gsOsArchitechture.exe" Job_WriteLog -Text "Downloading $SourceURL..." -FunctionName $Function Invoke-WebRequest $SourceURL -UseBasicParsing -OutFile $Installer Job_WriteLog -Text "Installing $Installer..." -FunctionName $Function Start-Process -FilePath $Installer -Args '/passive /norestart' -Wait Start-Sleep 3 Remove-Item $Installer -ErrorAction Ignore Job_WriteLog -Text 'MS Visual C++ 2015-2022 installed successfully.' -FunctionName $Function } catch { Job_WriteLog -Text 'MS Visual C++ 2015-2022 installation failed.' -FunctionName $Function Job_WriteLog -Text $_.Exception.Message -FunctionName $Function } } else { Job_WriteLog -Text 'MS Visual C++ 2015-2022 is installed.' -FunctionName $Function } #endregion #endregion #region Check if Microsoft.VCLibs.140.00.UWPDesktop is installed if (!(Get-AppxPackage -Name 'Microsoft.VCLibs.140.00.UWPDesktop' -AllUsers)) { Job_WriteLog -Text 'Microsoft.VCLibs.140.00.UWPDesktop is not installed' -FunctionName $Function $VCLibsUrl = 'https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx' $VCLibsFile = "$Global:TempFolder\Microsoft.VCLibs.x64.14.00.Desktop.appx" Job_WriteLog -Text "Downloading $VCLibsUrl..." -FunctionName $Function Invoke-RestMethod -Uri $VCLibsUrl -OutFile $VCLibsFile try { Job_WriteLog -Text 'Installing Microsoft.VCLibs.140.00.UWPDesktop...' -FunctionName $Function Add-AppxProvisionedPackage -Online -PackagePath $VCLibsFile -SkipLicense | Out-Null Job_WriteLog -Text 'Microsoft.VCLibs.140.00.UWPDesktop installed successfully.' -FunctionName $Function } catch { Job_WriteLog -Text 'Microsoft.VCLibs.140.00.UWPDesktop installation failed.' -FunctionName $Function Job_WriteLog -Text $_.Exception.Message -FunctionName $Function } Remove-Item -Path $VCLibsFile -Force -ErrorAction Ignore } else { Job_WriteLog -Text 'Microsoft.VCLibs.140.00.UWPDesktop is installed.' -FunctionName $Function } #endregion #region Check available WinGet version, if fail set version to the latest version as of 2024-03-01 $WingetURL = 'https://api.github.com/repos/microsoft/winget-cli/releases/latest' try { $WinGetAvailableVersion = ((Invoke-WebRequest $WingetURL -UseBasicParsing | ConvertFrom-Json)[0].tag_name).Replace('v', '') } catch { $WinGetAvailableVersion = '1.7.10582' } Job_WriteLog -Text "WinGet available version: $WinGetAvailableVersion" -FunctionName $Function #region Get installed Winget version try { $WingetInstalledVersionCmd = & $Winget -v $WinGetInstalledVersion = (($WingetInstalledVersionCmd).Replace('-preview', '')).Replace('v', '') Job_WriteLog -Text "Installed Winget version: $WinGetInstalledVersion" -FunctionName $Function } catch { Job_WriteLog -Text 'WinGet is not installed' -FunctionName $Function } #region Check if the available WinGet is newer than the installed if ($WinGetAvailableVersion -gt $WinGetInstalledVersion) { Job_WriteLog -Text "Downloading Winget v$WinGetAvailableVersion" -FunctionName $Function $WingetURL = "https://github.com/microsoft/winget-cli/releases/download/v$WinGetAvailableVersion/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" $WingetInstaller = "$Global:TempFolder\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" Invoke-RestMethod -Uri $WingetURL -OutFile $WingetInstaller try { Job_WriteLog -Text "Installing Winget v$WinGetAvailableVersion" -FunctionName $Function Add-AppxProvisionedPackage -Online -PackagePath $WingetInstaller -SkipLicense | Out-Null Job_WriteLog -Text 'Winget installed.' -FunctionName $Function } catch { Job_WriteLog -Text 'Failed to install Winget!' -FunctionName $Function Job_WriteLog -Text $_.Exception.Message -FunctionName $Function } Remove-Item -Path $WingetInstaller -Force -ErrorAction Ignore } #endregion #endregion #endregion Job_WriteLog -Text 'Checking prerequisites ended.' -FunctionName $Function Job_WriteLog -Text '###############################################' -FunctionName $Function } <# .SYNOPSIS Uninstalls an application using winget. .DESCRIPTION Uninstalls an application using winget. .PARAMETER AppId The id of the application to uninstall. You can find all the available applications on https://winget.run .PARAMETER AllowInstallOfWinGet Allow the installation of winget if it is not installed. Or update winget if it is installed. .EXAMPLE Uninstall-PpWingetApp -AppId 'Mozilla.Firefox' .EXAMPLE Uninstall-PpWingetApp -AppId 'Mozilla.Firefox' -AllowInstallOfWinGet $true .NOTES Custom function not from CapaSystems. #> function Uninstall-PpWingetApp { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$AppId, [Parameter(Mandatory = $false)] [bool]$AllowInstallOfWinGet = $false ) $FunctionName = 'Uninstall-PpWingetApp' $WingetPath = Find-PpWinGetCmd $UninstallCommand = "uninstall -e --id $AppId --force -h" if ($AllowInstallOfWinGet) { Install-PpWingetPrerequisites -WingetPath $WingetPath $WingetPath = Find-PpWinGetCmd } if ($WingetPath -eq $false) { Job_WriteLog -Text 'Winget not found' -FunctionName $FunctionName Exit-PpPackageFailedInstall -ExitMessage 'Winget not found' } $ExecuteSplatting = @{ Command = $WingetPath Arguments = $UninstallCommand Wait = $true WindowStyle = 'Hidden' MustExist = $true } $Result = Shell_Execute @ExecuteSplatting $Text = Get-PpWingetReturnCodeDescription -Decimal $Result Job_WriteLog -Text "Command completed with status: $Result" -FunctionName $FunctionName $AppInstalled = Confirm-PpWingetAppInstall -AppId $AppId if ($AppInstalled) { Job_WriteLog -Text "$AppId was not uninstalled" -FunctionName $FunctionName Exit-PpCommandFailed -ExitMessage "$AppId was not uninstalled" } else { Job_WriteLog -Text "$AppId was uninstalled" -FunctionName $FunctionName } return $Result } <# .SYNOPSIS Updates an application using winget. .DESCRIPTION Updates an application using winget. .PARAMETER AppId The id of the application to update. You can find all the available applications on https://winget.run .PARAMETER Locale The locale to use for the installation, for example 'da-DK' .PARAMETER UninstallPrevious Uninstall the previous version of the package during upgrade.Behavior will depend on the individual package. Some installers are designed to install new versions side-by-side. Some installers include a manifest that specifies “uninstallPrevious” so earlier versions are uninstalled without needing to use this command flag. In this case, using the winget upgrade --uninstall-previous command will tell WinGet to uninstall the previous version regardless of what is in the package manifest. If the package manifest does not include “uninstallPrevious” and the --uninstall-previous flag is not used, then the default behavior for the installer will apply. .PARAMETER AllowInstallOfWinGet Allow the installation of winget if it is not installed. Or update winget if it is installed. .EXAMPLE Update-PpWingetApp -AppId 'Mozilla.Firefox' .EXAMPLE Update-PpWingetApp -AppId 'Mozilla.Firefox' -Locale 'da-DK' .EXAMPLE Update-PpWingetApp -AppId 'Mozilla.Firefox' -UninstallPrevious $true .EXAMPLE Update-PpWingetApp -AppId 'Mozilla.Firefox' -AllowInstallOfWinGet $true #> function Update-PpWingetApp { param ( [Parameter(Mandatory = $true)] [string]$AppId, [Parameter(Mandatory = $false)] [string]$Locale, [Parameter(Mandatory = $false)] [bool]$UninstallPrevious = $false, [Parameter(Mandatory = $false)] [bool]$AllowInstallOfWinGet = $false ) $FunctionName = 'Update-PpWingetApp' $WingetPath = Find-PpWinGetCmd $UpdateCommand = "upgrade --id $AppId -e -h --accept-source-agreements --force" if ($UninstallPrevious) { $UpdateCommand += ' --uninstall-previous' } if ($Locale) { $UpdateCommand += " --locale $Locale" } if ($AllowInstallOfWinGet) { Install-PpWingetPrerequisites -WingetPath $WingetPath $WingetPath = Find-PpWinGetCmd } if ($WingetPath -eq $false) { Job_WriteLog -Text 'Winget not found' -FunctionName $FunctionName Exit-PpPackageFailedInstall -ExitMessage 'Winget not found' } $ExecuteSplatting = @{ Command = $WingetPath Arguments = $UpdateCommand Wait = $true WindowStyle = 'Hidden' MustExist = $true } $Result = Shell_Execute @ExecuteSplatting $Text = Get-PpWingetReturnCodeDescription -Decimal $Result Job_WriteLog -Text "Command completed with status: $Result" -FunctionName $FunctionName return $Result } |