@@ -68,6 +68,11 @@ function Install-NerdFont {
6868 [ValidateSet (' All' , ' Standard' , ' Mono' , ' Propo' )]
6969 [string ] $Variant = ' All' ,
7070
71+ # Max concurrent downloads.
72+ [Parameter ()]
73+ [ValidateRange (1 , 32 )]
74+ [int ] $ThrottleLimit = 8 ,
75+
7176 # Force will overwrite existing fonts
7277 [Parameter ()]
7378 [switch ] $Force
@@ -129,10 +134,9 @@ Please run the command again with elevated rights (Run as Administrator) or prov
129134 )
130135 }
131136
137+ $toProcess = [System.Collections.Generic.List [object ]]::new()
132138 foreach ($nerdFont in $nerdFontsToInstall ) {
133- $URL = $nerdFont.URL
134139 $fontName = $nerdFont.Name
135-
136140 if (-not $Force -and $installedFamilies ) {
137141 $alreadyInstalled = $false
138142 foreach ($family in $installedFamilies ) {
@@ -143,27 +147,37 @@ Please run the command again with elevated rights (Run as Administrator) or prov
143147 continue
144148 }
145149 }
150+ $toProcess.Add ($nerdFont )
151+ }
152+
153+ $extracted = $toProcess | ForEach-Object - ThrottleLimit $ThrottleLimit - Parallel {
154+ $nerdFont = $_
155+ $tempPath = $using :tempPath
156+ $cacheRoot = $using :cacheRoot
157+ $Variant = $using :Variant
158+ $Force = $using :Force
146159
160+ $URL = $nerdFont.URL
161+ $fontName = $nerdFont.Name
147162 $downloadFileName = Split-Path - Path $URL - Leaf
148163 $downloadPath = Join-Path - Path $tempPath - ChildPath $downloadFileName
149-
150- $cacheTag = if ($URL -match ' /releases/download/([^/]+)/' ) { $Matches [1 ] } else { ' unknown' }
164+ $cacheTag = if ($URL -match ' /releases/download/([^/]+)/' ) {
165+ $Matches [1 ]
166+ } else {
167+ ' unknown'
168+ }
151169 $cacheTagDir = Join-Path - Path $cacheRoot - ChildPath $cacheTag
152170 $cachedFile = Join-Path - Path $cacheTagDir - ChildPath $downloadFileName
153171
154172 if ((Test-Path - LiteralPath $cachedFile ) -and -not $Force ) {
155- Write-Verbose " [$fontName ] - Cache hit at [$cachedFile ]"
156173 Copy-Item - LiteralPath $cachedFile - Destination $downloadPath - Force
157174 } else {
158- Write-Verbose " [$fontName ] - Downloading to [$downloadPath ]"
159- if ($PSCmdlet.ShouldProcess (" [$fontName ] to [$downloadPath ]" , ' Download' )) {
160- $previousProgress = $ProgressPreference
161- $ProgressPreference = ' SilentlyContinue'
162- try {
163- Invoke-WebRequest - Uri $URL - OutFile $downloadPath - RetryIntervalSec 5 - MaximumRetryCount 5
164- } finally {
165- $ProgressPreference = $previousProgress
166- }
175+ $previousProgress = $ProgressPreference
176+ $ProgressPreference = ' SilentlyContinue'
177+ try {
178+ Invoke-WebRequest - Uri $URL - OutFile $downloadPath - RetryIntervalSec 5 - MaximumRetryCount 5
179+ } finally {
180+ $ProgressPreference = $previousProgress
167181 }
168182 if (-not (Test-Path - LiteralPath $cacheTagDir )) {
169183 $null = New-Item - ItemType Directory - Path $cacheTagDir - Force
@@ -172,14 +186,12 @@ Please run the command again with elevated rights (Run as Administrator) or prov
172186 }
173187
174188 $extractPath = Join-Path - Path $tempPath - ChildPath $fontName
175- Write-Verbose " [$fontName ] - Extract to [$extractPath ]"
176- if ($PSCmdlet.ShouldProcess (" [$fontName ] to [$extractPath ]" , ' Extract' )) {
177- if (-not (Test-Path - LiteralPath $extractPath )) {
178- $null = New-Item - ItemType Directory - Path $extractPath
179- }
180- [System.IO.Compression.ZipFile ]::ExtractToDirectory($downloadPath , $extractPath , $true )
181- Remove-Item - Path $downloadPath - Force
189+ if (-not (Test-Path - LiteralPath $extractPath )) {
190+ $null = New-Item - ItemType Directory - Path $extractPath
182191 }
192+ Add-Type - AssemblyName System.IO.Compression.FileSystem - ErrorAction SilentlyContinue
193+ [System.IO.Compression.ZipFile ]::ExtractToDirectory($downloadPath , $extractPath , $true )
194+ Remove-Item - Path $downloadPath - Force
183195
184196 if ($Variant -ne ' All' ) {
185197 $allFiles = Get-ChildItem - Path $extractPath - Recurse - File - Include ' *.ttf' , ' *.otf'
@@ -203,20 +215,21 @@ Please run the command again with elevated rights (Run as Administrator) or prov
203215 $keepNames ,
204216 [System.StringComparer ]::OrdinalIgnoreCase
205217 )
206- $removed = 0
207218 foreach ($f in $allFiles ) {
208219 if (-not $keepSet.Contains ($f.FullName )) {
209220 Remove-Item - LiteralPath $f.FullName - Force - ErrorAction SilentlyContinue
210- $removed ++
211221 }
212222 }
213- Write-Verbose " [$fontName ] - Variant '$Variant ' kept $ ( $keep.Count ) files, removed $removed "
214223 }
215224
216- Write-Verbose " [$fontName ] - Install to [$Scope ]"
217- if ($PSCmdlet.ShouldProcess (" [$fontName ] to [$Scope ]" , ' Install font' )) {
218- Install-Font - Path $extractPath - Scope $Scope - Force:$Force
219- Remove-Item - Path $extractPath - Force - Recurse
225+ [pscustomobject ]@ { Name = $fontName ; ExtractPath = $extractPath }
226+ }
227+
228+ foreach ($e in $extracted ) {
229+ Write-Verbose " [$ ( $e.Name ) ] - Install to [$Scope ]"
230+ if ($PSCmdlet.ShouldProcess (" [$ ( $e.Name ) ] to [$Scope ]" , ' Install font' )) {
231+ Install-Font - Path $e.ExtractPath - Scope $Scope - Force:$Force
232+ Remove-Item - Path $e.ExtractPath - Force - Recurse
220233 }
221234 }
222235
0 commit comments