Last active
January 8, 2025 21:13
-
-
Save mavaddat/698408014b9fa3a0c1307c5104f5276d to your computer and use it in GitHub Desktop.
Import-Package PowerShell cmdlet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<#PSScriptInfo | |
.VERSION 1.0 | |
.GUID ed896e0c-b20d-4d70-b894-ac698a1032cb | |
.AUTHOR Mavaddat Javid | |
.COMPANYNAME Mav Jav Education | |
.COPYRIGHT 2023 ©️ Mav Jav Education. All rights reserved. | |
.TAGS package NuGet PackageManagement assembly dll | |
.LICENSEURI https://creativecommons.org/licenses/by/4.0/ | |
.PROJECTURI https://gist.github.com/mavaddat/698408014b9fa3a0c1307c5104f5276d | |
.ICONURI https://i.imgur.com/YOxIHjx.png | |
.EXTERNALMODULEDEPENDENCIES | |
.REQUIREDSCRIPTS | |
.EXTERNALSCRIPTDEPENDENCIES | |
.RELEASENOTES | |
First version; Requires PowerShell Core 6+ for now. | |
.PRIVATEDATA | |
#> | |
#Requires -Module PackageManagement | |
<# | |
.DESCRIPTION | |
A cmdlet to enable easy importing of assemblies (DLL) from installed NuGet packages into the current PowerShell session. | |
#> | |
Param() | |
function Import-Package { | |
[CmdletBinding()] | |
param ( | |
[Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName = 'Name')] | |
[ValidateScript({ | |
if (Get-Package -Name $_ -ErrorAction SilentlyContinue) { | |
$true | |
} | |
else { | |
throw "Package '$($_)' not found" | |
} | |
})] | |
[ArgumentCompleter({ | |
param([string] $commandName, [string] $parameterName, [string] $wordToComplete, [System.Management.Automation.Language.CommandAst] $commandAst, [System.Collections.IDictionary] $preBoundParameters) | |
Get-Package | Where-Object { $_.Source } | Select-Object -ExpandProperty Name | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { if($_ -match '\s') { "'$_'" } else { $_ } } | |
})] | |
[string]$PackageName, | |
[Parameter(Mandatory = $false, ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName = 'Name')] | |
[ValidateScript({ | |
if (Get-Package -Name $PackageName -ErrorAction SilentlyContinue) { | |
$true | |
} | |
else { | |
throw "Package '$PackageName' not found" | |
} | |
})] | |
[ArgumentCompleter({ | |
param([string] $commandName, [string] $parameterName, [string] $wordToComplete, [System.Management.Automation.Language.CommandAst] $commandAst, [System.Collections.IDictionary] $preBoundParameters) | |
# get the value of the -PackageName parameter | |
$package = $commandAst.PipelineElements.CommandElements | Where-Object { $_.ParameterName -eq 'PackageName' } | ForEach-Object { $index = $commandAst.PipelineElements.CommandElements.IndexOf($_) + 1; $commandAst.PipelineElements.CommandElements[$index].Extent.Text } | |
if($null -eq $package) { return } | |
$dlls = $package.Source | Split-Path | Get-ChildItem -Filter *.dll -Recurse -File | |
$frameworks = New-Object -TypeName 'string[]' -ArgumentList @(($dlls.Count)) | |
for ($i = 0; $i -lt $dlls.Count; $i++) { | |
$powershell = [powershell]::Create() | |
[void]$powershell.AddScript([scriptblock]::Create("[System.Reflection.Assembly]::LoadFrom('$($dlls[$i].FullName)') | Write-Output")) | |
$assembly = $powershell.Invoke() | |
$powershell.Runspace.Dispose() | |
$powershell.Dispose() | |
foreach ($framework in $assembly | Where-Object { $_.GetCustomAttributes }) { | |
try { | |
$frameworks[$i] = $framework.GetCustomAttributes($true) | Where-Object { $null -ne $_ -and $_ -is [System.Runtime.Versioning.TargetFrameworkAttribute] } | |
} | |
catch { <# no-op #> } | |
} | |
} | |
$frameworks.FrameworkDisplayName | Where-Object { $_ -like "$wordToComplete*" } | |
})] | |
[string]$FrameworkPreferred, | |
[Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName = 'Path')] | |
[ValidateNotNullOrEmpty()] | |
[string]$Path | |
) | |
begin { | |
switch ($PSEdition) { | |
Core { $script:filter = 'netstandard*'; break } | |
Desktop { $script:filter = 'net*'; break } | |
Default { $script:filter = 'net*'; break } | |
} | |
} | |
process { | |
# if using name, get path | |
switch ($PSCmdlet.ParameterSetName) { | |
Name { | |
Get-Package -Name $PackageName | ForEach-Object { | |
Write-Verbose -Message "Importing package '$($_.Name)' $($_.Version) installed from '$($_.ProviderName)'" | |
Add-Type -LiteralPath ( $_.Source | Split-Path | Get-ChildItem -Filter $script:filter -Recurse -Directory | Get-ChildItem -Filter *.dll -Recurse -File | Select-Object -Last 1).FullName -Verbose:$VerbosePreference | |
} | |
break | |
} | |
Path { | |
if ($Path -notmatch '\.dll$') { | |
$__PackageName = Get-Package -Verbose:$VerbosePreference | Select-Object -ExpandProperty Source | Split-Path -Parent | Split-Path -Leaf | Select-String -Pattern '\D+(?=\.[\d\.]+)' -AllMatches | Where-Object { -not [string]::IsNullOrWhiteSpace($_.Matches.Value) -and $Path -match [regex]::Escape($_.Matches.Value) } | |
Import-Package -PackageName $__PackageName.Matches.Value -Verbose:$VerbosePreference | |
} | |
else { | |
Add-Type -LiteralPath $Path -Verbose:$VerbosePreference | |
} | |
break | |
} | |
} | |
} | |
} |
Where does the parameter FrameworkPreferred come into play?
I have not had time to implement this parameter yet. The purpose was to make the APIs of the Framework 4.5 DLL available in PowerShell Core.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Where does the parameter FrameworkPreferred come into play?