Skip to content

Instantly share code, notes, and snippets.

@mavaddat
Last active January 8, 2025 21:13
Show Gist options
  • Save mavaddat/698408014b9fa3a0c1307c5104f5276d to your computer and use it in GitHub Desktop.
Save mavaddat/698408014b9fa3a0c1307c5104f5276d to your computer and use it in GitHub Desktop.
Import-Package PowerShell cmdlet
<#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
}
}
}
}
@JosephColvin
Copy link

Where does the parameter FrameworkPreferred come into play?

@mavaddat
Copy link
Author

mavaddat commented Jan 8, 2025

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