PowerShell: script to show detailed information on a set of assemblies

To get some insight in your assemblies you can use the script below. It gets all information out that I required, but you can extend it if you need for example all assemblies an assembly depends on.

One thing that was new for we was that I needed functions in a script that can be executed in a pipeline. You can define these functions in the begin {} block.

Save the following code as Get-AssemblyInformation.ps1. Call for example as follows:

get-childitem -path "D:\MyProject\tools" -filter '*.dll' -recurse | D:\bin\Get-AssemblyInformation.ps1

Or if all files are in a folder:

Get-AssemblyInformation.ps1 –Path "D:\MyProject\tools"

Get-AssemblyInformation.s1
  1. #requires -version 2.0
  2.  
  3. [CmdletBinding(DefaultParameterSetName="Path")]
  4. param(
  5.    [Parameter(Mandatory=$true,
  6.               Position=0,
  7.               ParameterSetName="Path",
  8.               ValueFromPipeline=$true,
  9.               ValueFromPipelineByPropertyName=$true)]
  10.    [ValidateNotNullOrEmpty()]
  11.    [string[]]
  12.    $Path,
  13.    
  14.    [Alias("PSPath")]
  15.    [Parameter(Mandatory=$true,
  16.               Position=0,
  17.               ParameterSetName="LiteralPath",
  18.               ValueFromPipelineByPropertyName=$true)]
  19.    [ValidateNotNullOrEmpty()]
  20.    [string[]]
  21.    $LiteralPath
  22. )
  23.  
  24. Begin
  25. {
  26.    Set-StrictMode -Version 2.0
  27.     
  28.     function Get-AssemblyCustomProperty
  29.     {
  30.         param
  31.         (
  32.             $assembly,
  33.             $TypeNameLike,
  34.             $Property = $null
  35.         )
  36.         
  37.         $value = $null
  38.         foreach ($attribute in $assembly.GetCustomAttributes($false))
  39.         {
  40.             if ($attribute.GetType().ToString() -like "*$TypeNameLike*")
  41.             {
  42.                 if ($Property -ne $null)
  43.                 {
  44.                     # Select-Object -ExpandProperty fails if property value is $null
  45.                     try {
  46.                         $value = $attribute | Select-Object -ExpandProperty $Property
  47.                     }
  48.                     catch {
  49.                         $value = $null
  50.                     }
  51.                 }
  52.                 else
  53.                 {
  54.                     $value = $attribute
  55.                 }
  56.                 break;
  57.             }
  58.         }
  59.         
  60.         $value
  61.     }
  62.  
  63.     function Get-AssemblyInfoAsHashtable
  64.     {
  65.         param
  66.         (
  67.             [System.Reflection.Assembly]$assembly
  68.         )
  69.         $info = @{}
  70.             
  71.         $info.FullName = $assembly.FullName
  72.         $info.Name = $assembly.ManifestModule.Name
  73.         $info.Location = $assembly.Location
  74.         $info.ImageRuntimeVersion = $assembly.ImageRuntimeVersion
  75.         $info.GlobalAssemblyCache = $assembly.GlobalAssemblyCache
  76.         $info.Title = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'Title' -Property 'Title'
  77.         $info.Configuration = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'Configuration' -Property 'Configuration'
  78.         $info.Description = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'Description' -Property 'Description'
  79.         $info.Company = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'Company' -Property 'Company'
  80.         $info.Product = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'Product' -Property 'Product'
  81.         $info.Copyright = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'Copyright' -Property 'Copyright'
  82.         $info.Trademark = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'Trademark' -Property 'Trademark'
  83.         $info.DelaySign = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'DelaySign' -Property 'DelaySign'
  84.         $info.KeyName = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'KeyName' -Property 'KeyName'
  85.         $info.ClsCompliant = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'ClsCompliant' -Property 'IsCompliant'
  86.         $info.ComVisible = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'ComVisible' -Property 'Value'
  87.         $info.IsJITTrackingEnabled = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'System.Diagnostics.DebuggableAttribute' -Property 'IsJITTrackingEnabled'
  88.         $info.IsJITOptimizerDisabled = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'System.Diagnostics.DebuggableAttribute' -Property 'IsJITOptimizerDisabled'
  89.         $info.DebuggingFlags = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'System.Diagnostics.DebuggableAttribute' -Property 'DebuggingFlags'
  90.         $info.CompilationRelaxations = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'CompilationRelaxations' -Property 'CompilationRelaxations'
  91.         $info.WrapNonExceptionThrows = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'System.Runtime.CompilerServices.RuntimeCompatibilityAttribute' -Property 'WrapNonExceptionThrows'
  92.  
  93.         $info
  94.     }
  95.  
  96.     function Get-AssemblyInformation
  97.     {
  98.         param
  99.         (
  100.             $AssemblyFile
  101.         )
  102.  
  103.         try
  104.         {
  105.             $assembly = [Reflection.Assembly]::LoadFile($AssemblyFile)
  106.             $info = Get-AssemblyInfoAsHashtable -assembly $assembly
  107.             $info.IsValidDotNetAssembly  = $true
  108.         }
  109.         catch { # it is not a valid dotnet assembly
  110.             $info = @{
  111.                 FullName = $AssemblyFile;
  112.                 Name = Split-Path -Path $AssemblyFile -Leaf;
  113.                 IsValidDotNetAssembly = $false
  114.             }
  115.         }
  116.         
  117.         $info
  118.     }
  119. }
  120.  
  121. Process
  122. {
  123.    if ($psCmdlet.ParameterSetName -eq "Path")
  124.    {
  125.        # In the non-literal case we may need to resolve a wildcarded path
  126.         $resolvedPaths = @()
  127.        foreach ($apath in $Path)
  128.        {
  129.            $resolvedPaths += @(Resolve-Path $apath | Foreach { $_.Path })
  130.        }
  131.    }
  132.    else
  133.    {
  134.        $resolvedPaths = $LiteralPath
  135.    }
  136.    
  137.            
  138.    foreach ($rpath in $resolvedPaths)
  139.    {
  140.        $PathIntrinsics = $ExecutionContext.SessionState.Path
  141.        
  142.        if ($PathIntrinsics.IsProviderQualified($rpath))
  143.        {
  144.            $rpath = $PathIntrinsics.GetUnresolvedProviderPathFromPSPath($rpath)
  145.        }
  146.        
  147.         $assemblyInfo = Get-AssemblyInformation -AssemblyFile $rpath
  148.         Write-Host "***************************************************************************************************"
  149.         Write-Host "**************** $($assemblyInfo.Name)"
  150.         Write-Host "***************************************************************************************************"
  151.         $assemblyInfo
  152.         Write-Host ""
  153.     }
  154. }

Thanks goes to Keith Hill for some of the more advances parameter stuff which is lent from http://rkeithhill.wordpress.com/2009/01/28/tail-content-%E2%80%93-better-performance-for-grabbing-last-lines-from-large-ascii-log-files/.

2 Comments

Comments have been disabled for this content.