├── .github └── workflows │ └── publish.yml ├── .gitignore ├── Help ├── Confirm-RSWinGet.md ├── Get-RSInstallInfo.md ├── Install-RSVCLib.md ├── Start-RSWinGet.md └── Update-RSWinSoftware.md ├── LICENSE ├── README.md ├── WinSoftwareUpdate ├── WinSoftwareUpdate.psd1 └── WinSoftwareUpdate.psm1 └── publish.ps1 /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | build: 9 | name: Publish 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v1 13 | - name: Publish 14 | env: 15 | PSGALLERY: ${{ secrets.PSGALLERY }} 16 | run: .\publish.ps1 17 | shell: pwsh -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Packages # 2 | ############ 3 | # it's better to unpack these files and commit the raw source 4 | # git has its own built in compression methods 5 | *.7z 6 | *.dmg 7 | *.gz 8 | *.iso 9 | *.jar 10 | *.rar 11 | *.tar 12 | *.zip 13 | 14 | # Logs and databases # 15 | ###################### 16 | *.log 17 | *.sql 18 | *.sqlite 19 | 20 | # OS generated files # 21 | ###################### 22 | .DS_Store 23 | .DS_Store? 24 | ._* 25 | .Spotlight-V100 26 | .Trashes 27 | ehthumbs.db 28 | Thumbs.db 29 | *.csproj.user 30 | bin/ 31 | obj/ 32 | .vs/ 33 | .vscode/ 34 | .idea/ 35 | license/ 36 | 37 | WinSoftwareUpdate.psd1.source 38 | RSModuleBuilder.ps1 -------------------------------------------------------------------------------- /Help/Confirm-RSWinGet.md: -------------------------------------------------------------------------------- 1 |  2 | NAME 3 | Confirm-RSWinGet 4 | 5 | SYNOPSIS 6 | This function is connected and used of the main function for this module, Update-RSWinSoftware. 7 | So when you run the Update-RSWinSoftware function this function will be called during the process. 8 | 9 | 10 | SYNTAX 11 | Confirm-RSWinGet [-GitHubUrl] [-GithubHeaders] [[-WinGet] ] [] 12 | 13 | 14 | DESCRIPTION 15 | This function will connect to the GitHub API and check if there is a newer version of WinGet to download and install. 16 | 17 | 18 | PARAMETERS 19 | -GitHubUrl 20 | Url to the GitHub API for the latest release of WinGet 21 | 22 | Required? true 23 | Position? 1 24 | Default value 25 | Accept pipeline input? false 26 | Accept wildcard characters? false 27 | 28 | -GithubHeaders 29 | The headers and API version for the GitHub API, this is pasted from the main function for this module, Update-RSWinSoftware. 30 | This is pasted in from the main function for this module, Update-RSWinSoftware. 31 | 32 | Required? true 33 | Position? 2 34 | Default value 35 | Accept pipeline input? false 36 | Accept wildcard characters? false 37 | 38 | -WinGet 39 | 40 | Required? false 41 | Position? 3 42 | Default value 43 | Accept pipeline input? false 44 | Accept wildcard characters? false 45 | 46 | 47 | This cmdlet supports the common parameters: Verbose, Debug, 48 | ErrorAction, ErrorVariable, WarningAction, WarningVariable, 49 | OutBuffer, PipelineVariable, and OutVariable. For more information, see 50 | about_CommonParameters (https://go.microsoft.com/fwlink/?LinkID=113216). 51 | 52 | INPUTS 53 | 54 | OUTPUTS 55 | 56 | NOTES 57 | 58 | 59 | Author: Robin Widmark 60 | Mail: robin@widmark.dev 61 | Website/Blog: https://widmark.dev 62 | X: https://x.com/widmark_robin 63 | Mastodon: https://mastodon.social/@rwidmark 64 | YouTube: https://www.youtube.com/@rwidmark 65 | Linkedin: https://www.linkedin.com/in/rwidmark/ 66 | GitHub: https://github.com/rwidmark 67 | 68 | 69 | RELATED LINKS 70 | https://github.com/rwidmark/WinSoftwareUpdate/blob/main/README.md 71 | 72 | 73 | -------------------------------------------------------------------------------- /Help/Get-RSInstallInfo.md: -------------------------------------------------------------------------------- 1 |  2 | NAME 3 | Get-RSInstallInfo 4 | 5 | SYNOPSIS 6 | This function is connected and used of the main function for this module, Update-RSWinSoftware. 7 | So when you run the Update-RSWinSoftware function this function will be called during the process. 8 | 9 | 10 | SYNTAX 11 | Get-RSInstallInfo [] 12 | 13 | 14 | DESCRIPTION 15 | This function will collect the following data from the computer and store it in a PSCustomObject to make it easier for the main function for this module, Update-RSWinSoftware, to use the data. 16 | 17 | 18 | PARAMETERS 19 | 20 | This cmdlet supports the common parameters: Verbose, Debug, 21 | ErrorAction, ErrorVariable, WarningAction, WarningVariable, 22 | OutBuffer, PipelineVariable, and OutVariable. For more information, see 23 | about_CommonParameters (https://go.microsoft.com/fwlink/?LinkID=113216). 24 | 25 | INPUTS 26 | 27 | OUTPUTS 28 | 29 | NOTES 30 | 31 | 32 | Author: Robin Widmark 33 | Mail: robin@widmark.dev 34 | Website/Blog: https://widmark.dev 35 | X: https://x.com/widmark_robin 36 | Mastodon: https://mastodon.social/@rwidmark 37 | YouTube: https://www.youtube.com/@rwidmark 38 | Linkedin: https://www.linkedin.com/in/rwidmark/ 39 | GitHub: https://github.com/rwidmark 40 | 41 | 42 | RELATED LINKS 43 | https://github.com/rwidmark/WinSoftwareUpdate/blob/main/README.md 44 | 45 | 46 | -------------------------------------------------------------------------------- /Help/Install-RSVCLib.md: -------------------------------------------------------------------------------- 1 |  2 | NAME 3 | Install-RSVCLib 4 | 5 | SYNOPSIS 6 | This function is connected and used of the main function for this module, Update-RSWinSoftware. 7 | So when you run the Update-RSWinSoftware function this function will be called during the process. 8 | 9 | 10 | SYNTAX 11 | Install-RSVCLib [-VCLibsOutFile] [-VCLibsUrl] [] 12 | 13 | 14 | DESCRIPTION 15 | This function will install VCLibs if it's not installed on the computer. 16 | 17 | 18 | PARAMETERS 19 | -VCLibsOutFile 20 | The path to the output file for the VCLibs when downloaded, this is pasted from the main function for this module, Update-RSWinSoftware. 21 | 22 | Required? true 23 | Position? 1 24 | Default value 25 | Accept pipeline input? false 26 | Accept wildcard characters? false 27 | 28 | -VCLibsUrl 29 | The url path to where the VCLibs can be downloaded from, this is pasted from the main function for this module, Update-RSWinSoftware. 30 | 31 | Required? true 32 | Position? 2 33 | Default value 34 | Accept pipeline input? false 35 | Accept wildcard characters? false 36 | 37 | 38 | This cmdlet supports the common parameters: Verbose, Debug, 39 | ErrorAction, ErrorVariable, WarningAction, WarningVariable, 40 | OutBuffer, PipelineVariable, and OutVariable. For more information, see 41 | about_CommonParameters (https://go.microsoft.com/fwlink/?LinkID=113216). 42 | 43 | INPUTS 44 | 45 | OUTPUTS 46 | 47 | NOTES 48 | 49 | 50 | Author: Robin Widmark 51 | Mail: robin@widmark.dev 52 | Website/Blog: https://widmark.dev 53 | X: https://x.com/widmark_robin 54 | Mastodon: https://mastodon.social/@rwidmark 55 | YouTube: https://www.youtube.com/@rwidmark 56 | Linkedin: https://www.linkedin.com/in/rwidmark/ 57 | GitHub: https://github.com/rwidmark 58 | 59 | 60 | RELATED LINKS 61 | https://github.com/rwidmark/WinSoftwareUpdate/blob/main/README.md 62 | 63 | 64 | -------------------------------------------------------------------------------- /Help/Start-RSWinGet.md: -------------------------------------------------------------------------------- 1 |  2 | NAME 3 | Start-RSWinGet 4 | 5 | SYNOPSIS 6 | This function is connected and used of the main function for this module, Update-RSWinSoftware. 7 | So when you run the Update-RSWinSoftware function this function will be called during the process. 8 | 9 | 10 | SYNTAX 11 | Start-RSWinGet [] 12 | 13 | 14 | DESCRIPTION 15 | This will function will update all sources for WinGet and then check if any softwares needs to be updated. 16 | 17 | 18 | PARAMETERS 19 | 20 | This cmdlet supports the common parameters: Verbose, Debug, 21 | ErrorAction, ErrorVariable, WarningAction, WarningVariable, 22 | OutBuffer, PipelineVariable, and OutVariable. For more information, see 23 | about_CommonParameters (https://go.microsoft.com/fwlink/?LinkID=113216). 24 | 25 | INPUTS 26 | 27 | OUTPUTS 28 | 29 | NOTES 30 | 31 | 32 | Author: Robin Widmark 33 | Mail: robin@widmark.dev 34 | Website/Blog: https://widmark.dev 35 | X: https://x.com/widmark_robin 36 | Mastodon: https://mastodon.social/@rwidmark 37 | YouTube: https://www.youtube.com/@rwidmark 38 | Linkedin: https://www.linkedin.com/in/rwidmark/ 39 | GitHub: https://github.com/rwidmark 40 | 41 | 42 | RELATED LINKS 43 | https://github.com/rwidmark/WinSoftwareUpdate/blob/main/README.md 44 | 45 | 46 | -------------------------------------------------------------------------------- /Help/Update-RSWinSoftware.md: -------------------------------------------------------------------------------- 1 |  2 | NAME 3 | Update-RSWinSoftware 4 | 5 | SYNOPSIS 6 | This module let users auto update their installed software on Windows 10, 11 with WinGet. 7 | 8 | 9 | SYNTAX 10 | Update-RSWinSoftware [-SkipVersionCheck] [] 11 | 12 | 13 | DESCRIPTION 14 | The module will check if WinGet is installed and up to date, if not it will install WinGet or update it. 15 | It will also if Microsoft.VCLibs is installed and if not it will install it. 16 | Besides that the module will check what aritecture the computer is running and download the correct version of Microsoft.VCLibs etc. 17 | Then it will check if there is any software that needs to be updated and if so it will update them. 18 | 19 | 20 | PARAMETERS 21 | -SkipVersionCheck [] 22 | You can decide if you want to skip the WinGet version check, default it set to false. If you use the switch -SkipVersionCheck it will skip to check the version of WinGet. 23 | 24 | Required? false 25 | Position? named 26 | Default value False 27 | Accept pipeline input? false 28 | Accept wildcard characters? false 29 | 30 | 31 | This cmdlet supports the common parameters: Verbose, Debug, 32 | ErrorAction, ErrorVariable, WarningAction, WarningVariable, 33 | OutBuffer, PipelineVariable, and OutVariable. For more information, see 34 | about_CommonParameters (https://go.microsoft.com/fwlink/?LinkID=113216). 35 | 36 | INPUTS 37 | 38 | OUTPUTS 39 | 40 | NOTES 41 | 42 | 43 | Author: Robin Widmark 44 | Mail: robin@widmark.dev 45 | Website/Blog: https://widmark.dev 46 | X: https://x.com/widmark_robin 47 | Mastodon: https://mastodon.social/@rwidmark 48 | YouTube: https://www.youtube.com/@rwidmark 49 | Linkedin: https://www.linkedin.com/in/rwidmark/ 50 | GitHub: https://github.com/rwidmark 51 | 52 | -------------------------- EXAMPLE 1 -------------------------- 53 | 54 | PS > Update-RSWinSoftware 55 | # This command will run the module and check if WinGet and VCLibs are up to date. 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------- EXAMPLE 2 -------------------------- 63 | 64 | PS > Update-RSWinSoftware -SkipVersionCheck 65 | # This command will run the module without checking if WinGet and VCLibs are up to date. 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | RELATED LINKS 74 | https://github.com/rwidmark/WinSoftwareUpdate/blob/main/README.md 75 | 76 | 77 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (C) 2023 Robin Stolpe. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![GitHub](https://img.shields.io/github/license/rwidmark/WinSoftwareUpdate?style=plastic) 2 | ![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/rwidmark/WinSoftwareUpdate?sort=semver&style=plastic) ![Last release](https://img.shields.io/github/release-date/rwidmark/WinSoftwareUpdate?style=plastic) 3 | ![GitHub last commit](https://img.shields.io/github/last-commit/rwidmark/WinSoftwareUpdate?style=plastic) 4 | ![PSGallery downloads](https://img.shields.io/powershellgallery/dt/WinSoftwareUpdate?style=plastic) 5 | 6 | # WinSoftwareUpdate 7 | This module will let you update your installed software with WinGet, many of them but not all. The complete list is published here: [WinGet Repo](https://github.com/microsoft/winget-cli) 8 | This module is perfect for people like me that are to lazy to update every singel software all the time, it's much easier to just run a PowerShell Script. 9 | I have added the result from PSScriptAnalyzer in [test folder](https://github.com/rwidmark/WinSoftwareUpdate/tree/main/test) I have some ShouldProcess warnings in this module but that's nothing to worry about really. 10 | 11 | ## This module can do the following 12 | - Check what platform your currently running and adapt the downloads for that, if your running x86, amd64, arm64. 13 | - Make sure that you have WinGet installed and up to date, if it's not the module will install / update it for you to the latest version. 14 | - Make sure that you have Microsoft.VCLibs installed, if not the module will install it for you. 15 | - If your running this module with PowerShell 7 this module will check if PowerShell 7 have any newer versions, and if it's any newer version it will download and update PowerShell 7 16 | - Update all your softwares with WinGet 17 | 18 | # Links 19 | * [My PowerShell Collection](https://github.com/rwidmark/PSCollection) 20 | * [Webpage/Blog](https://widmark.dev) 21 | * [X](https://twitter.com/widmark_robin) 22 | * [Mastodon](https://mastodon.social/@rwidmark) 23 | * [YouTube](https://www.youtube.com/@rwidmark) 24 | * [LinkedIn](https://www.linkedin.com/in/rwidmark/) 25 | * [GitHub](https://github.com/rwidmark) 26 | 27 | # Help 28 | Below I have specified things that I think will help people with this module. 29 | You can also see the API for each function in the [help folder](https://github.com/rwidmark/WinSoftwareUpdate/tree/main/help) 30 | 31 | ## Install 32 | Install for current user 33 | ``` 34 | Install-Module -Name WinSoftwareUpdate -Scope CurrentUser -Force 35 | ``` 36 | 37 | Install for all users 38 | ``` 39 | Install-Module -Name WinSoftwareUpdate -Scope AllUsers -Force 40 | ``` 41 | 42 | # Update-RSWinSoftware 43 | Run the complete update 44 | ```` 45 | Update-RSWinSoftware 46 | ```` 47 | 48 | Only checks if your softwares are up to date with WinGet. This will not verify if WinGet or Microsoft.VCLibs is up to date. 49 | ```` 50 | Update-RSWinSoftware -SkipVersionCheck 51 | ```` 52 | 53 | 54 | -------------------------------------------------------------------------------- /WinSoftwareUpdate/WinSoftwareUpdate.psd1: -------------------------------------------------------------------------------- 1 | <# 2 | MIT License 3 | 4 | Copyright (C) 2025 Robin Widmark. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | #> 24 | 25 | # 26 | # Module manifest for module 'WinSoftwareUpdate' 27 | # 28 | # Generated by: Robin Widmark 29 | # 30 | # Generated on: 2023-01-20 31 | # 32 | 33 | @{ 34 | 35 | # Script module or binary module file associated with this manifest. 36 | RootModule = '.\WinSoftwareUpdate.psm1' 37 | 38 | # Version number of this module. 39 | ModuleVersion = '1.0.0' 40 | 41 | # Supported PSEditions 42 | # CompatiblePSEditions = @() 43 | 44 | # ID used to uniquely identify this module 45 | GUID = '4699dd6a-cc61-4929-97ed-11de5eb6bc01' 46 | 47 | # Author of this module 48 | Author = 'Robin Widmark' 49 | 50 | # Company or vendor of this module 51 | CompanyName = 'widmark.dev' 52 | 53 | # Copyright statement for this module 54 | Copyright = '(c) 2025 Robin Widmark. All rights reserved.' 55 | 56 | # Description of the functionality provided by this module 57 | Description = 'This module will help you to update your software on your Windows 10 and Windows 11 machines.' 58 | 59 | # Minimum version of the PowerShell engine required by this module 60 | PowerShellVersion = '5.1' 61 | 62 | # Name of the PowerShell host required by this module 63 | # PowerShellHostName = '' 64 | 65 | # Minimum version of the PowerShell host required by this module 66 | # PowerShellHostVersion = '' 67 | 68 | # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 69 | # DotNetFrameworkVersion = '' 70 | 71 | # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 72 | # ClrVersion = '' 73 | 74 | # Processor architecture (None, X86, Amd64) required by this module 75 | #ProcessorArchitecture = '' 76 | 77 | # Modules that must be imported into the global environment prior to importing this module 78 | # RequiredModules = @() 79 | 80 | # Assemblies that must be loaded prior to importing this module 81 | # RequiredAssemblies = @() 82 | 83 | # Script files (.ps1) that are run in the caller's environment prior to importing this module. 84 | # ScriptsToProcess = @() 85 | 86 | # Type files (.ps1xml) to be loaded when importing this module 87 | # TypesToProcess = @() 88 | 89 | # Format files (.ps1xml) to be loaded when importing this module 90 | # FormatsToProcess = @() 91 | 92 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 93 | # NestedModules = @() 94 | 95 | # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. 96 | FunctionsToExport = "Get-rsPowerShell7", "Update-RSWinSoftware", "Confirm-RSDependency", "Confirm-RSWinGet", "Get-RSSystemInfo" 97 | 98 | # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. 99 | CmdletsToExport = @() 100 | 101 | # Variables to export from this module 102 | VariablesToExport = '*' 103 | 104 | # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. 105 | AliasesToExport = @() 106 | 107 | # DSC resources to export from this module 108 | # DscResourcesToExport = @() 109 | 110 | # List of all modules packaged with this module 111 | # ModuleList = @() 112 | 113 | # List of all files packaged with this module 114 | # FileList = @() 115 | 116 | # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. 117 | PrivateData = @{ 118 | 119 | PSData = @{ 120 | 121 | # Tags applied to this module. These help with module discovery in online galleries. 122 | Tags = @("windows", "maintenance", "autoupdate", "autoupdate-script", "psmodule", "update", "winget", "windows10", "windows11") 123 | 124 | # A URL to the license for this module. 125 | LicenseUri = 'https://github.com/rwidmark/WinSoftwareUpdate/blob/main/LICENSE' 126 | 127 | # A URL to the main website for this project. 128 | ProjectUri = 'https://github.com/rwidmark/WinSoftwareUpdate' 129 | 130 | # A URL to an icon representing this module. 131 | # IconUri = '' 132 | 133 | # ReleaseNotes of this module 134 | ReleaseNotes = 'https://github.com/rwidmark/WinSoftwareUpdate/releases' 135 | 136 | # Prerelease string of this module 137 | Prerelease = 'beta4' 138 | 139 | # Flag to indicate whether the module requires explicit user acceptance for install/update/save 140 | RequireLicenseAcceptance = $false 141 | 142 | # External dependent modules of this module 143 | # ExternalModuleDependencies = @() 144 | 145 | } # End of PSData hashtable 146 | 147 | } # End of PrivateData hashtable 148 | 149 | # HelpInfo URI of this module 150 | # HelpInfoURI = '' 151 | 152 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. 153 | # DefaultCommandPrefix = '' 154 | } 155 | -------------------------------------------------------------------------------- /WinSoftwareUpdate/WinSoftwareUpdate.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | MIT License 3 | 4 | Copyright (C) 2025 Robin Widmark. 5 | 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | #> 25 | 26 | Function Confirm-rsWinGet { 27 | <# 28 | .SYNOPSIS 29 | This function is connected and used of the main function for this module, Update-RSWinSoftware. 30 | So when you run the Update-RSWinSoftware function this function will be called during the process. 31 | 32 | .DESCRIPTION 33 | This function will connect to the GitHub API and check if there is a newer version of WinGet to download and install. 34 | 35 | .PARAMETER GitHubUrl 36 | Url to the GitHub API for the latest release of WinGet 37 | 38 | .PARAMETER GithubHeaders 39 | The headers and API version for the GitHub API, this is pasted from the main function for this module, Update-RSWinSoftware. 40 | This is pasted in from the main function for this module, Update-RSWinSoftware. 41 | 42 | .PARAMETER WinGet 43 | 44 | 45 | .LINK 46 | https://github.com/rwidmark/WinSoftwareUpdate/blob/main/README.md 47 | 48 | .NOTES 49 | Author: Robin Widmark 50 | Mail: robin@widmark.dev 51 | Website/Blog: https://widmark.dev 52 | X: https://x.com/widmark_robin 53 | Mastodon: https://mastodon.social/@rwidmark 54 | YouTube: https://www.youtube.com/@rwidmark 55 | Linkedin: https://www.linkedin.com/in/rwidmark/ 56 | GitHub: https://github.com/rwidmark 57 | #> 58 | 59 | [CmdletBinding()] 60 | Param( 61 | [Parameter(Mandatory = $false, HelpMessage = "Information about the installed version of WinGet")] 62 | $SysInfo 63 | ) 64 | 65 | # ================================= 66 | # Static Variables 67 | # ================================= 68 | # 69 | # GitHub url for the latest release of WinGet 70 | [string]$WinGetUrl = "https://api.github.com/repos/microsoft/winget-cli/releases/latest" 71 | # 72 | # The headers and API version for the GitHub API 73 | [hashtable]$GithubHeaders = @{ 74 | "Accept" = "application/vnd.github.v3+json" 75 | "X-GitHub-Api-Version" = "2022-11-28" 76 | } 77 | 78 | # Collecting information from GitHub regarding latest version of WinGet. 79 | try { 80 | # If the computer is running PowerShell 7 or higher, use HTTP/3.0 for the GitHub API in other cases use HTTP/2.0 81 | [System.Object]$GithubInfoRestData = Invoke-RestMethod -Uri $WinGetUrl -Method Get -Headers $GithubHeaders -TimeoutSec 10 -HttpVersion $SysInfo.HTTPVersion | Select-Object -Property assets, tag_name 82 | 83 | [System.Object]$GitHubInfo = [PSCustomObject]@{ 84 | Tag = $($GithubInfoRestData.tag_name.Substring(1)) 85 | DownloadUrl = $GithubInfoRestData.assets | where-object { $_.name -like "*.msixbundle" } | Select-Object -ExpandProperty browser_download_url 86 | OutFile = "$($env:TEMP)\WinGet_$($GithubInfoRestData.tag_name.Substring(1)).msixbundle" 87 | } 88 | } 89 | catch { 90 | Throw "Message: $($_.Exception.Message)`nError Line: $($_.InvocationInfo.Line)`n" 91 | break 92 | } 93 | 94 | # Checking if the installed version of WinGet are the same as the latest version of WinGet 95 | [version]$vWinGet = $SysInfo.Software.WinGet 96 | [version]$vGitHub = $GitHubInfo.Tag 97 | if ([Version]$vWinGet -lt [Version]$vGitHub) { 98 | Write-Output "WinGet has a newer version $($vGitHub | Out-String), downloading and installing it..." 99 | Write-Verbose "Downloading WinGet..." 100 | Invoke-WebRequest -UseBasicParsing -Uri $GitHubInfo.DownloadUrl -OutFile $GitHubInfo.OutFile 101 | 102 | Write-Verbose "Installing version $($vGitHub | Out-String) of WinGet..." 103 | [void](Add-AppxPackage $($GitHubInfo.OutFile) -ForceApplicationShutdown) 104 | 105 | Write-Verbose "Deleting WinGet downloaded installation file..." 106 | [void](Remove-Item -Path $($GitHubInfo.OutFile) -Force) 107 | } 108 | else { 109 | Write-Verbose "Your already on the latest version of WinGet $($vWinGet | Out-String), no need to update." 110 | Continue 111 | } 112 | } 113 | Function Get-rsSystemInfo { 114 | <# 115 | .SYNOPSIS 116 | This function is connected and used of the main function for this module, Update-RSWinSoftware. 117 | So when you run the Update-RSWinSoftware function this function will be called during the process. 118 | 119 | .DESCRIPTION 120 | This function will collect the following data from the computer and store it in a PSCustomObject to make it easier for the main function for this module, Update-RSWinSoftware, to use the data. 121 | 122 | .LINK 123 | https://github.com/rwidmark/WinSoftwareUpdate/blob/main/README.md 124 | 125 | .NOTES 126 | Author: Robin Widmark 127 | Mail: robin@widmark.dev 128 | Website/Blog: https://widmark.dev 129 | X: https://x.com/widmark_robin 130 | Mastodon: https://mastodon.social/@rwidmark 131 | YouTube: https://www.youtube.com/@rwidmark 132 | Linkedin: https://www.linkedin.com/in/rwidmark/ 133 | GitHub: https://github.com/rwidmark 134 | #> 135 | 136 | # Getting architecture of the computer and adapting it after the right download links 137 | [string]$Architecture = $(Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object -ExpandProperty SystemType) 138 | 139 | [string]$Arch = Switch ($Architecture) { 140 | "x64-based PC" { "x64" } 141 | "ARM64-based PC" { "arm64" } 142 | "x86-based PC" { "x86" } 143 | default { "Unsupported" } 144 | } 145 | 146 | if ($Arch -eq "Unsupported") { 147 | Throw "Your running a unsupported architecture, exiting now..." 148 | Break 149 | } 150 | else { 151 | # Verify verifying what ps version that's running and checks if pwsh7 is installed 152 | [version]$CurrentPSVersion = if ($PSVersionTable.PSVersion.Major -lt 7) { 153 | $pwshPath = Join-Path -Path "C:\Program Files" -ChildPath "PowerShell\7" -AdditionalChildPath "pwsh.exe" 154 | 155 | if ($pwshPath -eq $true) { 156 | (Get-Command "$($pwshPath)").Version 157 | } 158 | else { 159 | $PSVersionTable.PSVersion 160 | } 161 | } 162 | else { 163 | $PSVersionTable.PSVersion 164 | } 165 | 166 | # Collects everything in pscustomobject to get easier access to the information 167 | # Need to redothis to hashtable 168 | $SysInfo = [ordered]@{ 169 | Software = [ordered]@{ 170 | "Microsoft.VCLibs" = [ordered]@{ 171 | Version = $(try { (Get-AppxPackage -AllUsers | Where-Object { $_.Architecture -eq $Arch -and $_.PackageFamilyName -like "Microsoft.VCLibs.140.00_8wekyb3d8bbwe" } | Sort-Object { $_.Version -as [version] } -Descending | Select-Object Version -First 1).version } catch { "0.0.0.0" }) -as [version] 172 | Url = "https://aka.ms/Microsoft.VCLibs.$($Arch).14.00.Desktop.appx" 173 | FileName = "Microsoft.VCLibs.$($Arch).14.00.Desktop.appx" 174 | } 175 | "Microsoft.UI.Xaml" = [ordered]@{ 176 | Version = $(try { (Get-AppxPackage -AllUsers | Where-Object { $_.Architecture -eq $Arch -and $_.PackageFamilyName -like "Microsoft.UI.Xaml.2.8_8wekyb3d8bbwe" } | Sort-Object { $_.Version -as [version] } -Descending | Select-Object Version -First 1).version } catch { "0.0.0.0" }) -as [version] 177 | Url = "https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.6/Microsoft.UI.Xaml.2.8.$($Arch).appx" 178 | FileName = "Microsoft.UI.Xaml.2.8.$($Arch).appx" 179 | } 180 | "WinGet" = [ordered]@{ 181 | Version = $(try { (Get-AppxPackage -AllUsers | Where-Object { $_.Architecture -eq $Arch -and $_.PackageFamilyName -like "Microsoft.DesktopAppInstaller_8wekyb3d8bbwe" } | Sort-Object { $_.Version -as [version] } -Descending | Select-Object Version -First 1).version } catch { "0.0.0.0" }) -as [version] 182 | Url = "" 183 | FileName = "Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" 184 | } 185 | "vsRedist" = [ordered]@{ 186 | Version = "" 187 | Url = "https://aka.ms/vs/17/release/vc_redist.$($Architecture).exe" 188 | FileName = "vc_redist.$($Architecture).exe" 189 | } 190 | } 191 | Arch = $Arch 192 | VersionPS = [version]$CurrentPSVersion 193 | Temp = $env:TEMP 194 | HTTPVersion = Switch ($PSVersionTable.PSVersion.Major) { 195 | 7 { "3.0" } 196 | default { "2.0" } 197 | } 198 | } 199 | 200 | return $SysInfo 201 | } 202 | } 203 | Function Confirm-rsDependency { 204 | # Collecting systeminformation 205 | $SysInfo = Get-rsSystemInfo 206 | 207 | # If any dependencies are missing it will install them 208 | foreach ($_info in $SysInfo.Software.keys) { 209 | if ($_info -notlike "WinGet") { 210 | $Software = $SysInfo.Software.$_info 211 | if ($null -eq $Software.version -or $Software.version -eq "0.0.0.0") { 212 | try { 213 | Write-Output "$($_info) is not installed, downloading and installing it now..." 214 | [string]$DepOutFile = Join-Path -Path $SysInfo.Temp -ChildPath $Software.FileName 215 | Write-Verbose "Downloading $($_info)..." 216 | Invoke-RestMethod -Uri $Software.url -OutFile $DepOutFile -HttpVersion $SysInfo.HTTPVersion 217 | 218 | Write-Verbose "Installing $($_info)..." 219 | [void](Add-AppxPackage -Path $DepOutFile) 220 | 221 | Write-Verbose "Deleting $($_info) downloaded installation file..." 222 | [void](Remove-Item -Path $DepOutFile -Force) 223 | } 224 | catch { 225 | Throw "Message: $($_.Exception.Message)`nError Line: $($_.InvocationInfo.Line)`n" 226 | break 227 | } 228 | } 229 | } 230 | } 231 | 232 | # Install VisualCRedist 233 | # To Install visualcredist use vc_redist.x64.exe /install /quiet /norestart 234 | 235 | # If PowerShell 7 is installed on the system then it will check if it's the latest version and if not it will update it 236 | [version]$pwsh7 = "7.0.0.0" 237 | if ($SysInfo.VersionPS -ge $pwsh7) { 238 | Confirm-rsPowerShell7 -SysInfo $SysInfo 239 | } 240 | 241 | # If WinGet is not installed it will be installed and if it's any updates it will be updated 242 | Confirm-RSWinGet -SysInfo $SysInfo 243 | } 244 | Function Confirm-rsPowerShell7 { 245 | <# 246 | .SYNOPSIS 247 | .DESCRIPTION 248 | .PARAMETER SID 249 | .PARAMETER Trim 250 | .EXAMPLE 251 | #> 252 | 253 | $MissingPWSH7 = $false 254 | 255 | [version]$CurrentVersion = if ($PSVersionTable.PSVersion.Major -lt 7) { 256 | $CheckpwshVersion = Test-Path -Path "C:\Program Files\PowerShell\7\pwsh.exe" 257 | 258 | if ($CheckpwshVersion -eq $true) { 259 | (Get-Command "C:\Program Files\PowerShell\7\pwsh.exe").Version 260 | } 261 | else { 262 | [version]$CurrentVersion = $PSVersionTable.PSVersion 263 | $true 264 | } 265 | } 266 | else { 267 | $PSVersionTable.PSVersion 268 | } 269 | 270 | [version]$pwshV7 = "7.0.0.0" 271 | if ($CurrentVersion -lt $pwshV7) { 272 | $GetMetaData = Invoke-RestMethod -Uri "https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/metadata.json" 273 | } 274 | else { 275 | $GetMetaData = Invoke-RestMethod -Uri "https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/metadata.json" -HttpVersion 3.0 276 | } 277 | 278 | [version]$Release = $GetMetaData.StableReleaseTag -replace '^v' 279 | $PackageName = "PowerShell-${Release}-win-x64.msi" 280 | $PackagePath = Join-Path -Path $env:TEMP -ChildPath $PackageName 281 | $downloadURL = "https://github.com/PowerShell/PowerShell/releases/download/v${Release}/${PackageName}" 282 | 283 | if ($CurrentVersion -lt $pwshV7) { 284 | $MSIArguments = @() 285 | $MSIArguments = @("/i", $packagePath, "/quiet") 286 | $MSIArguments += "ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL=1" 287 | $MSIArguments += "ENABLE_PSREMOTING=1" 288 | $MSIArguments += "ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL=1" 289 | $MSIArguments += "REGISTER_MANIFEST=1" 290 | $MSIArguments += "ADD_PATH=1" 291 | } 292 | 293 | # Check if powershell needs to update or not 294 | if ($CurrentVersion -lt $Release) { 295 | # Download latest MSI installer for PowerShell 296 | Invoke-RestMethod -Uri $downloadURL -OutFile $PackagePath 297 | 298 | # Setting arguments 299 | if ($null -ne $MSIArguments) { 300 | $ArgumentList = $MSIArguments 301 | } 302 | else { 303 | $ArgumentList = @("/i", $packagePath, "/quiet") 304 | } 305 | 306 | $InstallProcess = Start-Process msiexec -ArgumentList $ArgumentList -Wait -PassThru 307 | if ($InstallProcess.exitcode -ne 0) { 308 | throw "Quiet install failed, please ensure you have administrator rights" 309 | } 310 | else { 311 | if ($MissingPWSH7 -eq $true) { 312 | Write-Output "PowerShell 7 was not installed on your system, PowerShell 7 have been installed and you need to restart PowerShell to use the new version" 313 | } 314 | else { 315 | Write-Output "PowerShell 7 have been updated from $($CurrentVersion) to $($Release), you need to restart PowerShell to use the new version" 316 | } 317 | } 318 | # Removes the installation file 319 | Remove-Item -Path $PackagePath -Force -ErrorAction SilentlyContinue 320 | } 321 | } 322 | Function Update-rsWinSoftware { 323 | <# 324 | .SYNOPSIS 325 | This module let users auto update their installed software on Windows 10, 11 with WinGet. 326 | 327 | .DESCRIPTION 328 | The module will check if WinGet is installed and up to date, if not it will install WinGet or update it. 329 | It will also if Microsoft.VCLibs is installed and if not it will install it. 330 | Besides that the module will check what aritecture the computer is running and download the correct version of Microsoft.VCLibs etc. 331 | Then it will check if there is any software that needs to be updated and if so it will update them. 332 | 333 | .EXAMPLE 334 | Update-RSWinSoftware 335 | # This command will run the module and check if WinGet and VCLibs are up to date. 336 | 337 | .LINK 338 | https://github.com/rwidmark/WinSoftwareUpdate/blob/main/README.md 339 | 340 | .NOTES 341 | Author: Robin Widmark 342 | Mail: robin@widmark.dev 343 | Website/Blog: https://widmark.dev 344 | X: https://x.com/widmark_robin 345 | Mastodon: https://mastodon.social/@rwidmark 346 | YouTube: https://www.youtube.com/@rwidmark 347 | Linkedin: https://www.linkedin.com/in/rwidmark/ 348 | GitHub: https://github.com/rwidmark 349 | #> 350 | 351 | #Check if script was started as Administrator 352 | if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator")) { 353 | Write-Error ("{0} needs admin privileges, exiting now...." -f $MyInvocation.MyCommand) 354 | break 355 | } 356 | 357 | # Importing appx with -usewindowspowershell if your using PowerShell 7 or higher 358 | if ($PSVersionTable.PSVersion.Major -ge 7) { 359 | Import-Module appx -UseWindowsPowershell 360 | Write-Output "This messages is expected if you are using PowerShell 7 or higher and can be ignored`n" 361 | } 362 | 363 | # Register WinGet 364 | # Add-AppxPackage -RegisterByFamilyName -MainPackage "Microsoft.DesktopAppInstaller_8wekyb3d8bbwe" 365 | 366 | # Check if something needs to be installed or updated 367 | Confirm-RSDependency 368 | 369 | # Checking if it's any softwares to update and if so it will update them 370 | Write-Output "Updating Wingets source list..." 371 | Start-Process -FilePath "WinGet.exe" -ArgumentList "source update" -NoNewWindow -Wait 372 | 373 | Write-OutPut "Checks if any softwares needs to be updated..." 374 | try { 375 | $Arguments = @() 376 | $Arguments += "upgrade" 377 | $Arguments += "--all" 378 | $Arguments += "--include-unknown" 379 | $Arguments += "--accept-package-agreements" 380 | $Arguments += "--accept-source-agreements" 381 | $Arguments += "--uninstall-previous" 382 | $Arguments += "--silent" 383 | 384 | Start-Process -FilePath "WinGet.exe" -ArgumentList $Arguments -NoNewWindow -Wait 385 | } 386 | catch { 387 | Throw "Message: $($_.Exception.Message)`nError Line: $($_.InvocationInfo.Line)`n" 388 | } 389 | 390 | Write-OutPut "FINISH - All of your programs have been updated!" 391 | } -------------------------------------------------------------------------------- /publish.ps1: -------------------------------------------------------------------------------- 1 | $ModulePath = "$PSScriptRoot\WinSoftwareUpdate" 2 | Publish-Module -Path $ModulePath -NuGetApiKey $Env:PSGALLERY --------------------------------------------------------------------------------