Skip to content

Instantly share code, notes, and snippets.

@JustinGrote
Last active July 20, 2024 10:26
Show Gist options
  • Save JustinGrote/19abb6d2cd0464dd76a86b2a47ecf0f6 to your computer and use it in GitHub Desktop.
Save JustinGrote/19abb6d2cd0464dd76a86b2a47ecf0f6 to your computer and use it in GitHub Desktop.
Update Help More Quickly using ThreadJob
#Requires -module ThreadJob
param(
#Filter modules to update by name, otherwise will update all modules
[string[]]$Name = @(),
[ValidateSet('AllUsers', 'CurrentUser')]
$Scope = 'CurrentUser',
$ThrottleLimit = 30
)
try {
Import-Module ThreadJob -ErrorAction Stop
} catch {
throw 'This script requires the ThreadJob module. Run Install-Module -Name ThreadJob -Scope CurrentUser -Force to install it.'
}
function Test-IsElevated {
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
return $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
if ($PSVersionTable.PSVersion -lt '6.0') {
#Enable TLS 1.2 for downloading help files
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
if (-not (Test-IsElevated)) {
Write-Warning 'Windows PowerShell Detected, only All User Update is supported and you are not running as Administrator. If you see Access Denied errors, either grant access to the module folders to the updating user, or re-run this command as an Administrator.'
}
if ($Scope -eq 'CurrentUser') {
Write-Warning 'Windows PowerShell Detected, only All User Update is supported. Switching to All User Update Mode'
}
$Scope = 'AllUsers'
}
try {
#TODO: Remove help redundancies from different repos and only fetch for the latest version
[Collections.Generic.List[Management.Automation.Job2]]$updateInfoJobs = Get-Module -ListAvailable |
Where-Object HelpInfoUri -Match '^https?://' |
ForEach-Object {
$module = $PSItem
Start-ThreadJob -InputObject $module -Name $module.Name -ThrottleLimit $ThrottleLimit {
$updateHelpParams = @{
Module = $input.Name
ErrorAction = 'Continue'
Verbose = $true
}
if ($PSVersionTable.PSVersion -ge '7.0') {
$updateHelpParams.Scope = $using:Scope
}
Update-Help @updateHelpParams
}
}
#Track Job Progress
$jobCount = $updateInfoJobs.Count
Write-Progress -Id 1 -Activity 'Updating Help' -Status "0/$jobCount" -PercentComplete 0
$completedCount = 0
while ($updateInfoJobs.State -contains 'Running') {
$completedJob = $updateInfoJobs | Wait-Job -Any
$completedCount++
[int]$percentComplete = $completedCount / $jobCount * 100
Write-Verbose "Completed $($completedJob.Name) help"
Write-Progress -Id 1 -Activity 'Updating Help' -Status "$completedCount/${jobCount}: Updated $($completedJob.Name)" -PercentComplete $percentComplete
$completedJob | Receive-Job -Wait -AutoRemoveJob
[void]$updateInfoJobs.Remove($completedJob)
}
} finally {
$updateInfoJobs | Remove-Job -Force
}
@sdwheeler
Copy link

@JustinGrote Nice update, thanks!

@o-l-a-v
Copy link

o-l-a-v commented Jul 20, 2024

With 5.1 it does not handle that TheadJob is renamed to Microsoft.PowerShell.ThreadJob, and you only have the newest version of this module installed.

Remove the #Requires -Module ThreadJob and check for import either Microsoft.PowerShell.ThreadJob (priority #1) or ThreadJob? Quick and dirty:

try {
    Import-Module -ErrorAction Stop -Name (
        Get-Module -ListAvailable -Name 'Microsoft.PowerShell.ThreadJob', 'ThreadJob' | Sort-Object -Property 'Version' | Select-Object -Last 1
    ).'Name'
}
catch {
    throw 'This script requires the ThreadJob module. Run Install-Module -Name Microsoft.PowerShell.ThreadJob -Scope CurrentUser -Force to install it.'
}

It also crashes for me with pwsh -noprofile v7.4.3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment