NerdFonts.psm1
[CmdletBinding()] param() $scriptName = 'NerdFonts' Write-Verbose "[$scriptName] - Importing module" #region - From [init] Write-Verbose "[$scriptName] - [init] - Processing folder" #region - From [init] - [initializer] Write-Verbose "[$scriptName] - [init] - [initializer] - Importing" Write-Verbose '----------------------------------------' Write-Verbose '--- Initializing the NerdFonts list ---' Write-Verbose '----------------------------------------' $script:Release = Invoke-RestMethod 'https://api.github.com/repos/ryanoasis/nerd-fonts/releases/latest' $script:NerdFonts = $Release.assets.browser_download_url | Where-Object { $_ -like '*.zip' } | ForEach-Object { [pscustomobject]@{ Name = $_.Split('/')[-1].Split('.')[0] Version = $Release.tag_name URL = $_ } } $script:ArchiveExtension = '.zip' Write-Verbose "[$scriptName] - [init] - [initializer] - Done" #endregion - From [init] - [initializer] Write-Verbose "[$scriptName] - [init] - Done" #endregion - From [init] #region - From [classes] - [private] Write-Verbose "[$scriptName] - [classes] - [private] - Processing folder" #region - From [classes] - [private] - [Scope] Write-Verbose "[$scriptName] - [classes] - [private] - [Scope] - Importing" enum Scope { CurrentUser AllUsers } Write-Verbose "[$scriptName] - [classes] - [private] - [Scope] - Done" #endregion - From [classes] - [private] - [Scope] Write-Verbose "[$scriptName] - [classes] - [private] - Done" #endregion - From [classes] - [private] #region - From [functions] - [public] Write-Verbose "[$scriptName] - [functions] - [public] - Processing folder" #region - From [functions] - [public] - [Get-NerdFont] Write-Verbose "[$scriptName] - [functions] - [public] - [Get-NerdFont] - Importing" function Get-NerdFont { <# .SYNOPSIS Get NerdFonts asset list .DESCRIPTION Get NerdFonts asset list, filtered by name, from the latest release. .EXAMPLE Get-NerdFonts -Name 'FiraCode' .EXAMPLE Get-NerdFonts -Name '*Code' #> [Alias('Get-NerdFonts')] [CmdletBinding()] param ( # Name of the NerdFont to get [Parameter()] [SupportsWildcards()] [string] $Name = '*' ) Write-Verbose "Selecting assets by name: '$Name'" $script:NerdFonts | Where-Object { $_.Name -like $Name } } Write-Verbose "[$scriptName] - [functions] - [public] - [Get-NerdFont] - Done" #endregion - From [functions] - [public] - [Get-NerdFont] #region - From [functions] - [public] - [Install-NerdFont] Write-Verbose "[$scriptName] - [functions] - [public] - [Install-NerdFont] - Importing" #Requires -Modules Admin, Fonts, DynamicParams function Install-NerdFont { <# .SYNOPSIS Installs Nerd Fonts to the system. .DESCRIPTION Installs Nerd Fonts to the system. .EXAMPLE Install-NerdFont -Name 'Fira Code' Installs the font 'Fira Code' to the current user. .EXAMPLE Install-NerdFont -Name 'Fira Code' -Scope AllUsers Installs the font 'Fira Code' to all users. This requires to be run as administrator. .EXAMPLE Install-NerdFont -All Installs all Nerd Fonts to the current user. #> [CmdletBinding( DefaultParameterSetName = 'Name', SupportsShouldProcess )] [Alias('Install-NerdFonts')] param( # Specify to install all Nerd Font(s). [Parameter(ParameterSetName = 'All', Mandatory)] [switch] $All, # Specify the scope of where to install the font(s). [Parameter()] [Scope] $Scope = 'CurrentUser' ) dynamicparam { $DynamicParamDictionary = New-DynamicParamDictionary $dynPath = @{ Name = 'Name' Type = [string[]] Mandatory = $true ParameterSetName = 'Name' HelpMessage = 'Name of the font to install.' ValueFromPipeline = $true ValueFromPipelineByPropertyName = $true ValidateSet = Get-NerdFonts | Select-Object -ExpandProperty Name DynamicParamDictionary = $DynamicParamDictionary } New-DynamicParam @dynPath return $DynamicParamDictionary } begin { if ($Scope -eq 'AllUsers' -and -not (IsAdmin)) { $errorMessage = @' Administrator rights are required to install fonts. Please run the command again with elevated rights (Run as Administrator) or provide '-Scope CurrentUser' to your command." '@ throw $errorMessage } $nerdFontsToInstall = @() $tempPath = Join-Path -Path $HOME -ChildPath '.temp' if (-not (Test-Path -Path $tempPath -PathType Container)) { Write-Verbose "Create folder [$tempPath]" $null = New-Item -Path $tempPath -ItemType Directory $tempFolderCreated = $true } $Name = $PSBoundParameters.Name } process { if ($All) { $nerdFontsToInstall = $script:NerdFonts } else { foreach ($fontName in $Name) { $nerdFontsToInstall += $script:NerdFonts | Where-Object Name -EQ $fontName } } Write-Verbose "[$Scope] - Installing [$($nerdFontsToInstall.count)] fonts" foreach ($NerdFont in $nerdFontsToInstall) { $URL = $NerdFont.URL $fontName = $NerdFont.Name $downloadPath = Join-Path -Path $tempPath -ChildPath "$FontName$script:ArchiveExtension" $extractPath = Join-Path -Path $tempPath -ChildPath "$fontName" Write-Verbose "[$fontName] - Downloading to [$downloadPath]" $storedProgressPreference = $ProgressPreference $ProgressPreference = 'SilentlyContinue' # Suppress progress bar if ($PSCmdlet.ShouldProcess($fontName, "Download $fontName")) { Invoke-WebRequest -Uri $URL -OutFile $downloadPath -Verbose:$false } $ProgressPreference = $storedProgressPreference Write-Verbose "[$fontName] - Unpack to [$extractPath]" if ($PSCmdlet.ShouldProcess($fontName, 'Extract archive')) { Expand-Archive -Path $downloadPath -DestinationPath $extractPath -Force Remove-Item -Path $downloadPath -Force } Write-Verbose "[$fontName] - Install to [$Scope]" if ($PSCmdlet.ShouldProcess($fontName, 'Install font')) { Install-Font -Path $extractPath -Scope $Scope Remove-Item -Path $extractPath -Force -Recurse } } } end { if ($tempFolderCreated) { Write-Verbose "Remove folder [$tempPath]" Remove-Item -Path $tempPath -Force } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Install-NerdFont] - Done" #endregion - From [functions] - [public] - [Install-NerdFont] Write-Verbose "[$scriptName] - [functions] - [public] - Done" #endregion - From [functions] - [public] $exports = @{ Alias = '*' Cmdlet = '' Function = @( 'Get-NerdFont' 'Install-NerdFont' ) } Export-ModuleMember @exports |