Private/PSResourceGetRegistry.ps1
using module ./_EntryRegistry.psm1 [NoRunspaceAffinity()] class PSResourceGetRegistry : EntryRegistry { $entries = [System.Collections.Generic.List[PowerShellRun.SelectorEntry]]::new() $subMenuEntries = [System.Collections.Generic.List[PowerShellRun.SelectorEntry]]::new() $isEntryUpdated = $false PSResourceGetRegistry() { } [System.Collections.Generic.List[PowerShellRun.SelectorEntry]] GetEntries([String[]]$categories) { if ($categories -contains 'Utility') { return $this.entries } return $null } [void] InitializeEntries([String[]]$categories) { $enabled = $categories -contains 'Utility' $enabled = $enabled -and $this.IsPSResourceGetInstalled() if ($enabled) { $this.RegisterEntries() } } [bool] IsPSResourceGetInstalled() { $module = Get-Module -Name Microsoft.PowerShell.PSResourceGet -ListAvailable if (-not $module) { return $false } return $true } [void] RegisterEntries() { $callback = { $thisClass = $args[0].ArgumentList $option = $script:globalStore.GetPSRunSelectorOption() $option.Prompt = 'PSResourceGet (PSRun)' $option.QuitWithBackspaceOnEmptyQuery = $true $context = $null while ($true) { $result = Invoke-PSRunSelectorCustom -Entry $thisClass.subMenuEntries -Option $option -Context $context $context = $result.Context $entry = $result.FocusedEntry if (-not $entry) { return } if ($result.KeyCombination -eq $script:globalStore.firstActionKey) { & $entry.UserData.ScriptBlock $entry.UserData.ArgumentList } if ([PowerShellRun.ExitStatus]::Type -ne [PowerShellRun.ExitType]::QuitWithBackspaceOnEmptyQuery) { return } } } $topEntry = [PowerShellRun.SelectorEntry]::new() $topEntry.Icon = '📦' $topEntry.Name = 'PSResourceGet (PSRun)' $topEntry.Description = 'Install and manage PowerShell modules using PSResourceGet' $topEntry.ActionKeys = @( [PowerShellRun.ActionKey]::new($script:globalStore.firstActionKey, 'Open PSResourceGet menu') ) $topEntry.UserData = @{ ScriptBlock = $callback ArgumentList = $this } $this.entries.Add($topEntry) $this.subMenuEntries.Add($this.CreateInstallEntry()) $this.subMenuEntries.Add($this.CreateUpgradeEntry()) $this.subMenuEntries.Add($this.CreateUninstallEntry()) $this.isEntryUpdated = $true } [PowerShellRun.SelectorEntry] CreatePSResourceEntry($resource, $scope) { $entry = [PowerShellRun.SelectorEntry]::new() $entry.Icon = if ($resource.Type -eq 'Module') { '📦' } elseif ($resource.Type -eq 'Script') { '📝' } $entry.Name = $resource.Name $repoString = "[$($resource.Repository)]".PadRight('[PSGallery]'.Length + 2) $versionString = "[$($resource.Version)]".PadRight('[10.10.100]'.Length) if ($scope) { $scopeString = "[$scope]".PadRight('[CurrentUser]'.Length) $entry.Description = '{0} {1} {2}' -f $scopeString, $repoString, $versionString $entry.UserData = [PSCustomObject]@{ Resource = $resource Scope = $scope } } else { $entry.Description = '{0} {1}' -f $repoString, $versionString $entry.UserData = $resource } return $entry } [PowerShellRun.SelectorEntry] CreateInstallEntry() { $callback = { param ($thisClass) $option = $script:globalStore.GetPSRunSelectorOption() $option.QuitWithBackspaceOnEmptyQuery = $true $promptContext = $null $originalPrompt = $option.Prompt while ($true) { $option.Prompt = 'Type module name to search' $promptResult = Invoke-PSRunPrompt -Option $option -Context $promptContext $promptContext = $promptResult.Context if ([string]::IsNullOrEmpty($promptResult.Input)) { return } Write-Host ('Searching modules [{0}]...' -f $promptResult.Input) $searchWord = '*{0}*' -f $promptResult.Input $resources = Find-PSResource -Name $searchWord if (-not $resources) { Write-Warning -Message ('[{0}] No available PSResource found.' -f $promptResult.Input) return } $actionKeys = @( [PowerShellRun.ActionKey]::new($script:globalStore.firstActionKey, 'Install for CurrentUser') [PowerShellRun.ActionKey]::new($script:globalStore.secondActionKey, 'Install for AllUsers') [PowerShellRun.ActionKey]::new($script:globalStore.copyActionKey, 'Copy install command to Clipboard') ) $option.Prompt = $originalPrompt $result = $resources | ForEach-Object { $entry = $thisClass.CreatePSResourceEntry($_, $null) $entry.ActionKeys = $actionKeys $entry.ActionKeysMultiSelection = $actionKeys $entry.PreviewAsyncScript = { param ($resource) $resource | Format-List | Out-String } $entry.PreviewAsyncScriptArgumentList = $_ $entry } | Invoke-PSRunSelectorCustom -Option $option -MultiSelection if ([PowerShellRun.ExitStatus]::Type -eq [PowerShellRun.ExitType]::QuitWithBackspaceOnEmptyQuery) { continue } if ($result.MarkedEntries) { $installResources = $result.MarkedEntries.UserData } else { $installResources = $result.FocusedEntry.UserData } if (-not $installResources) { return } if ($result.KeyCombination -eq $script:globalStore.firstActionKey) { $installResources | ForEach-Object { Write-Host "Installing [$($_.Name)]..." Install-PSResource $_ -Scope CurrentUser -PassThru } } elseif ($result.KeyCombination -eq $script:globalStore.secondActionKey) { $installResources | ForEach-Object { Write-Host "Installing [$($_.Name)]..." Install-PSResource $_ -Scope AllUsers -PassThru } } elseif ($result.KeyCombination -eq $script:globalStore.copyActionKey) { $command = @() $installResources | ForEach-Object { $command += 'Install-PSResource -Name {0} -Version {1}' -f $_.Name, $_.Version } $command | Set-Clipboard } return } } $entry = [PowerShellRun.SelectorEntry]::new() $entry.Icon = '🔽' $entry.Name = 'Install' $entry.Description = 'Search PowerShell modules by name and install them' $entry.ActionKeys = @( [PowerShellRun.ActionKey]::new($script:globalStore.firstActionKey, 'Open Install menu') ) $entry.UserData = @{ ScriptBlock = $callback ArgumentList = $this } return $entry } [PowerShellRun.SelectorEntry] CreateUpgradeEntry() { $callback = { param ($thisClass) $option = $script:globalStore.GetPSRunSelectorOption() $option.QuitWithBackspaceOnEmptyQuery = $true Write-Host 'Searching upgradable modules...' $upgradableResourcesAllUsers = $thisClass.GetUpgradableResources('AllUsers') $upgradableResourcesCurrentUser = $thisClass.GetUpgradableResources('CurrentUser') if (($upgradableResourcesAllUsers.Count -eq 0) -and ($upgradableResourcesCurrentUser.Count -eq 0)) { Write-Warning -Message 'No upgradable module found.' return } $actionKeys = @( [PowerShellRun.ActionKey]::new($script:globalStore.firstActionKey, 'Upgrade') [PowerShellRun.ActionKey]::new($script:globalStore.copyActionKey, 'Copy upgrade command to Clipboard') ) $entries = [System.Collections.Generic.List[PowerShellRun.SelectorEntry]]::new() $upgradableResourcesAllUsers | ForEach-Object { $entry = $thisClass.CreatePSResourceEntry($_.Resource, 'AllUsers') $entry.Description = $entry.Description + ' ← [Installed: {0}]' -f $_.InstalledVersion $entry.ActionKeys = $actionKeys $entry.ActionKeysMultiSelection = $actionKeys $entry.Preview = $_.Resource | Format-List | Out-String $entries.Add($entry) } $upgradableResourcesCurrentUser | ForEach-Object { $entry = $thisClass.CreatePSResourceEntry($_.Resource, 'CurrentUser') $entry.Description = $entry.Description + ' ← [Installed: {0}]' -f $_.InstalledVersion $entry.ActionKeys = $actionKeys $entry.ActionKeysMultiSelection = $actionKeys $entry.Preview = $_.Resource | Format-List | Out-String $entries.Add($entry) } $result = Invoke-PSRunSelectorCustom -Entry $entries -Option $option -MultiSelection if ($result.MarkedEntries) { $upgradeResources = $result.MarkedEntries.UserData } else { $upgradeResources = $result.FocusedEntry.UserData } if (-not $upgradeResources) { return } if ($result.KeyCombination -eq $script:globalStore.firstActionKey) { $upgradeResources | ForEach-Object { Write-Host "Upgrading [$($_.Resource.Name)] to [$($_.Resource.Version)]..." Update-PSResource -Name $_.Resource.Name -Scope $_.Scope -PassThru } } elseif ($result.KeyCombination -eq $script:globalStore.copyActionKey) { $command = @() $upgradeResources | ForEach-Object { $command += 'Update-PSResource -Name {0} -Scope {1}' -f $_.Resource.Name, $_.Scope } $command | Set-Clipboard } } $entry = [PowerShellRun.SelectorEntry]::new() $entry.Icon = '💫' $entry.Name = 'Upgrade' $entry.Description = 'List upgradable modules and upgrade selected ones' $entry.ActionKeys = @( [PowerShellRun.ActionKey]::new($script:globalStore.firstActionKey, 'Open Upgrade menu') ) $entry.UserData = @{ ScriptBlock = $callback ArgumentList = $this } return $entry } [PowerShellRun.SelectorEntry] CreateUninstallEntry() { $callback = { param ($thisClass) $option = $script:globalStore.GetPSRunSelectorOption() $option.QuitWithBackspaceOnEmptyQuery = $true $resourcesAllUsers = Get-InstalledPSResource -Scope AllUsers $resourcesCurrentUser = Get-InstalledPSResource -Scope CurrentUser if ((-not $resourcesAllUsers) -and (-not $resourcesCurrentUser)) { Write-Warning -Message 'No module found.' return } $actionKeys = @( [PowerShellRun.ActionKey]::new($script:globalStore.firstActionKey, 'Uninstall') [PowerShellRun.ActionKey]::new($script:globalStore.copyActionKey, 'Copy uninstall command to Clipboard') ) $entries = [System.Collections.Generic.List[PowerShellRun.SelectorEntry]]::new() $resourcesAllUsers | ForEach-Object { $entry = $thisClass.CreatePSResourceEntry($_, 'AllUsers') $entry.ActionKeys = $actionKeys $entry.ActionKeysMultiSelection = $actionKeys $entry.Preview = $_ | Format-List | Out-String $entries.Add($entry) } $resourcesCurrentUser | ForEach-Object { $entry = $thisClass.CreatePSResourceEntry($_, 'CurrentUser') $entry.ActionKeys = $actionKeys $entry.ActionKeysMultiSelection = $actionKeys $entry.Preview = $_ | Format-List | Out-String $entries.Add($entry) } $result = Invoke-PSRunSelectorCustom -Entry $entries -Option $option -MultiSelection if ($result.MarkedEntries) { $uninstallResources = $result.MarkedEntries.UserData } else { $uninstallResources = $result.FocusedEntry.UserData } if (-not $uninstallResources) { return } if ($result.KeyCombination -eq $script:globalStore.firstActionKey) { $uninstallResources | ForEach-Object { Write-Host "Uninstalling [$($_.Resource.Name) $($_.Resource.Version)]..." Uninstall-PSResource $_.Resource -Scope $_.Scope } } elseif ($result.KeyCombination -eq $script:globalStore.copyActionKey) { $command = @() $uninstallResources | ForEach-Object { $command += 'Uninstall-PSResource -Name {0} -Scope {1}' -f $_.Resource.Name, $_.Scope } $command | Set-Clipboard } } $entry = [PowerShellRun.SelectorEntry]::new() $entry.Icon = '⛔' $entry.Name = 'Uninstall' $entry.Description = 'List installed modules and uninstall selected ones' $entry.ActionKeys = @( [PowerShellRun.ActionKey]::new($script:globalStore.firstActionKey, 'Open Uninstall menu') ) $entry.UserData = @{ ScriptBlock = $callback ArgumentList = $this } return $entry } [Object[]] GetUpgradableResources($scope) { $installedResourceVersions = @{} Get-InstalledPSResource -Scope $scope | ForEach-Object { if ($installedResourceVersions.ContainsKey($_.Name)) { if ($_.Version -gt $installedResourceVersions[$_.Name]) { $installedResourceVersions[$_.Name] = $_.Version } } else { $installedResourceVersions[$_.Name] = $_.Version } } $upgradableResources = @() if ($installedResourceVersions.Count -eq 0) { return $upgradableResources } $resourceNames = [string[]]$installedResourceVersions.Keys Find-PSResource -Name $resourceNames | ForEach-Object { if ($_.Version -gt $installedResourceVersions[$_.Name]) { $upgradableResources += [PSCustomObject]@{ Resource = $_ InstalledVersion = $installedResourceVersions[$_.Name] } } } return $upgradableResources } [bool] UpdateEntries() { $updated = $this.isEntryUpdated $this.isEntryUpdated = $false return $updated } } |