Skip to content

Instantly share code, notes, and snippets.

@applejag
Last active January 6, 2020 15:07
Show Gist options
  • Save applejag/66c3bdddf2c60c0dcb5f9cb21cb6a19f to your computer and use it in GitHub Desktop.
Save applejag/66c3bdddf2c60c0dcb5f9cb21cb6a19f to your computer and use it in GitHub Desktop.
Assembly describer for powershell

Better DLL describer for PowerShell

I just want more info than what AssemblyName gives.

What it does

Writes AssemblyName values, values of all Assembly attributes starting with Assembly (i.e. /^Assembly.*/), and also prints the strong name key, if any.

How to install

Requires Visual Studio 2019 Community edition to be installed for the Strong Name Utility. If you have a different Visual Studio installation, change the "Import-Module" @ line 56 in the code to match it.

Add the content of the Get-AssemblyInfo.ps1 script below into your powershell profile.

Short script doing just that:

$profileText = Get-Content $PROFILE -ErrorAction SilentlyContinue -Raw;
if ($null -ne $profileText -and $profileText.Contains("https://gist.github.com/jilleJr/66c3bdddf2c60c0dcb5f9cb21cb6a19f")) {
    Write-Host "Already installed to $PROFILE" -ForegroundColor DarkYellow
} else {
    $content = (Invoke-WebRequest -UseBasicParsing 'https://gist.github.com/jilleJr/66c3bdddf2c60c0dcb5f9cb21cb6a19f/raw/e304d031fb253814e943fb3f249ce07c5bc1987b/Get-AssemblyInfo.ps1').Content;
    [IO.File]::WriteAllLines($PROFILE, "$profileText`n$content");
    Write-Host "Installed to $PROFILE" -ForegroundColor Green;
}

Sample output

AssemblyName values

Name                  : Moq
Version               : 4.8.0.0
CultureInfo           :
CultureName           :
CodeBase              : file:///C:/Users/kalle/.nuget/packages/moq/4.8.1/lib/net45/Moq.dll
EscapedCodeBase       : file:///C:/Users/kalle/.nuget/packages/moq/4.8.1/lib/net45/Moq.dll
ProcessorArchitecture : MSIL
ContentType           : Default
Flags                 : PublicKey
HashAlgorithm         : SHA1
VersionCompatibility  : SameMachine
KeyPair               :
FullName              : Moq, Version=4.8.0.0, Culture=neutral, PublicKeyToken=69f491c39445e920



Assembly attributes values

Name                 Value
----                 -----
Company              "Clarius Consulting, Manas Technology Solutions, InSTEDD"
Configuration        "RELEASE"
FileVersion          <null>
InformationalVersion "4.8.1-tags/v4.8.1+de5c25c"
Product              "Moq"
Title                "Moq"
Trademark            ""



Assembly references

Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc
mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Threading.Tasks.Extensions, Version=4.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
System.ValueTuple, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51



Assembly Strong Name Utility values

**********************************************************************
** Visual Studio 2019 Developer PowerShell v16.4.2
** Copyright (c) 2019 Microsoft Corporation
**********************************************************************
#Public key token:

Microsoft (R) .NET Framework Strong Name Utility  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Public key (hash algorithm: sha1):
00240000048000009400000006020000002400005253413100040000010001009f7a95086500f8
f66d892174803850fed9c22225c2ccfff21f39c8af8abfa5415b1664efd0d8e0a6f7f2513b1c11
659bd84723dc7900c3d481b833a73a2bcf1ed94c16c4be64d54352c86956c89930444e9ac15124
d3693e3f029818e8410f167399d6b995324b635e95353ba97bfab856abbaeb9b40c9b160070c63
25e22ddc

Public key token is 69f491c39445e920

#Verified?

Microsoft (R) .NET Framework Strong Name Utility  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Assembly 'C:\Users\kalle\.nuget\packages\moq\4.8.1\lib\net45\Moq.dll' is valid

Enable / Disable strong name verification

This tool can only operate if the assembly strong name is valid or if strong name verification is disabled.

If you are working with unverifiable assemblies (such as delayed signed) you will have to disable strong name verification for that assembly.

Caution: Use this option only during development. Adding an assembly to the skip verification list creates a security vulnerability. A malicious assembly could use the fully specified assembly name (assembly name, version, culture, and public key token) of the assembly added to the skip verification list to fake its identity. This would allow the malicious assembly to also skip verification.

https://docs.microsoft.com/en-us/dotnet/framework/tools/sn-exe-strong-name-tool

Register verification skipping for strong name

Run as administrator. Example shows how to disable verification for Newtonsoft.Json

reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\StrongName\Verification\Newtonsoft.Json,30ad4fe6b2a6aeed" /f
if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") {
    reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\StrongName\Verification\Newtonsoft.Json,30ad4fe6b2a6aeed" /f
}

Remove verification skipping for strong name

Run as administrator. Example shows how to reenable verification for Newtonsoft.Json

reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\StrongName\Verification\Newtonsoft.Json,30ad4fe6b2a6aeed" /f
if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") {
    reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\StrongName\Verification\Newtonsoft.Json,30ad4fe6b2a6aeed" /f
}
# Source: https://gist.github.com/jilleJr/66c3bdddf2c60c0dcb5f9cb21cb6a19f
function Get-AssemblyInfo {
param (
[Parameter(Mandatory, ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[System.IO.FileInfo]
$Path
)
$Path = [string] (Resolve-Path $Path)
$job = Start-Job {
param (
[string] $Path
)
class AttrDetails {
[string] $Name
[string] $Value
AttrDetails([string] $Name, [string] $Value) {
$this.Name = $Name
$this.Value = $Value
}
}
Write-Host ""
try {
$asm = [System.Reflection.Assembly]::LoadFile($Path)
Write-Host "AssemblyName values" -ForegroundColor White -NoNewline
$asm.GetName() | Format-List | Out-Host
$attr = $asm.GetCustomAttributes($false)
$asmAttr = $attr.Where({$_.GetType().Name.StartsWith('Assembly')})
Write-Host "Assembly attributes values" -ForegroundColor White
$resultList = [System.Collections.Generic.List[AttrDetails]]::new()
$attrPrefixLength = "Assembly".Length
$attrSuffixLength = "Attribute".Length
foreach ($a in $asmAttr) {
$name = $a.GetType().Name
$name = $name.Substring($attrPrefixLength, $name.Length - $attrPrefixLength - $attrSuffixLength)
$value = $a.PSObject.Properties[$name].Value
$value = if ($null -eq $value) { "<null>" } else { "`"$value`"" }
$attrDetails = [AttrDetails]::new($name, $value)
$resultList.Add($attrDetails)
}
$result = $resultList | Sort-Object -Property Name | Format-Table
$result | Out-Host
if ($resultList.Count -eq 0) {
Write-Host "<no assembly attributes>" -ForegroundColor DarkGray
}
Write-Host ""
Write-Host "Assembly references" -ForegroundColor White
Write-Host ""
$referencedAssemblies = [System.Linq.Enumerable]::ToList($asm.GetReferencedAssemblies())
$referencedAssemblies.Sort({
param ([System.Reflection.AssemblyName] $a, [System.Reflection.AssemblyName] $b)
return $a.FullName.CompareTo($b.FullName)
})
foreach ($refAsm in $referencedAssemblies) {
Write-Host $refAsm.FullName
}
if ($referencedAssemblies.Count -eq 0) {
Write-Host "<no referenced assemblies>" -ForegroundColor DarkGray
}
Write-Host ""
Write-Host ""
Write-Host ""
} catch {
if ($null -ne $_.Exception.InnerException -and $_.Exception.InnerException.GetType() -eq [System.IO.FileLoadException]) {
Write-Error -Exception $_.Exception.InnerException
$asmName = [System.Reflection.AssemblyName]::GetAssemblyName($Path)
$name = $asmName.Name
$key = $asmName.FullName -replace ".*PublicKeyToken=([0-9a-f]+)","`$1"
Write-Host ""
Write-Host "You may need to enable strong name verification skipping to read this assembly." -ForegroundColor DarkYellow
Write-Host "Do so by executing the following in a command prompt as administrator" -ForegroundColor DarkYellow
Write-Host ""
Write-Host "reg add `"HKEY\SOFTWARE\Microsoft\StrongName\Verification\$name,$key`" /f" -ForegroundColor Yellow
if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") {
Write-Host "reg add `"HKEY\SOFTWARE\Wow6432Node\Microsoft\StrongName\Verification\$name,$key`" /f" -ForegroundColor Yellow
}
Write-Host ""
Write-Host "Disable the strong name verification skipping using the following commands as administrator" -ForegroundColor DarkYellow
Write-Host ""
Write-Host "reg delete `"HKEY\SOFTWARE\Microsoft\StrongName\Verification\$name,$key`" /f" -ForegroundColor Yellow
if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") {
Write-Host "reg delete `"HKEY\SOFTWARE\Wow6432Node\Microsoft\StrongName\Verification\$name,$key`" /f" -ForegroundColor Yellow
}
Write-Host ""
Write-Host "Caution: " -NoNewline -ForegroundColor Red
Write-Host "Use this option only during development. Adding an assembly to the skip verification list creates a security vulnerability. A malicious assembly could use the fully specified assembly name (assembly name, version, culture, and public key token) of the assembly added to the skip verification list to fake its identity. This would allow the malicious assembly to also skip verification." -ForegroundColor DarkYellow
Write-Host ""
Write-Host ""
} else {
throw
}
}
&{
Write-Host "Assembly Strong Name Utility values" -ForegroundColor White
Write-Host ""
$vsInstallPath = &"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -property installationpath
Import-Module (Join-Path $vsInstallPath "Common7\Tools\Microsoft.VisualStudio.DevShell.dll")
Enter-VsDevShell -VsInstallPath $vsInstallPath -SkipAutomaticLocation | Out-Host
Write-Host "#Public key token:"
sn -Tp $Path | Out-Host
Write-Host ""
Write-Host "#Verified?"
sn -vf $Path | Out-Host
}
} -ArgumentList $Path.FullName
$result = Receive-Job -Job $job -AutoRemoveJob -Wait
Write-Host $result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment