Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Extracting Icons with PowerShell

Posted on December 7, 2020December 7, 2020

Last week I was seeing what else I could add to my Windows Terminal setup. If you can launch a console from the command line, you can probably create a Windows Terminal profile for it. Recently, I've added Ruby and Python to my desktop, both of which have interactive consoles. I thought, "Why not add them to Windows Terminal?"

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

I looked at the properties for the Ruby console and copied and command line. With this, it was easy enough to add a new profile.

{
    // Ruby cmd
    "guid" :"{a7849c4a-db74-4723-adf2-c717357f0a1a}",
    "name" : "Ruby",
    "commandline": "C:\\Windows\\System32\\cmd.exe /E:ON /K C:\\Ruby27-x64\\bin\\setrbvars.cmd",
    "tabTitle": "Ruby Cmd"
},

What I didn't have was an icon, but the ruby.exe file did. I needed a PowerShell way to extract the icon and save it to a file. There are plenty of third-party tools that will handle this task, but where's fun in that? I poked around looking for a starting point and came across an old piece of code from Josh Duffney posted on Spiceworks. His code had the key bit I needed, the necessary .NET Framework class and command to extract the icon.

With this inspiration, I wrote this PowerShell script.

#requires -version 5.1

# inspired by https://community.spiceworks.com/topic/592770-extract-icon-from-exe-powershell

[CmdletBinding(SupportsShouldProcess)]
Param(
    [Parameter(Position = 0, Mandatory,HelpMessage = "Specify the path to the file.")]
    [ValidateScript({Test-Path $_})]
    [string]$Path,

    [Parameter(HelpMessage = "Specify the folder to save the file.")]
    [ValidateScript({Test-Path $_})]
    [string]$Destination = ".",

    [parameter(HelpMessage = "Specify an alternate base name for the new image file. Otherwise, the source name will be used.")]
    [ValidateNotNullOrEmpty()]
    [string]$Name,

    [Parameter(HelpMessage = "What format do you want to use? The default is png.")]
    [ValidateSet("ico","bmp","png","jpg","gif")]
    [string]$Format = "png"
    )

    Write-Verbose "Starting $($MyInvocation.MyCommand)"

    Try {
        Add-Type -AssemblyName System.Drawing -ErrorAction Stop
    }
    Catch {
        Write-Warning "Failed to import System.Drawing"
        Throw $_
    }

    Switch ($format) {
        "ico" {$ImageFormat = "icon"}
        "bmp" {$ImageFormat = "Bmp"}
        "png" {$ImageFormat = "Png"}
        "jpg" {$ImageFormat = "Jpeg"}
        "gif" {$ImageFormat = "Gif"}
    }

    $file = Get-Item $path
    Write-Verbose "Processing $($file.fullname)"
    #convert destination to file system path
    $Destination = Convert-Path -path $Destination

    if ($Name) {
        $base = $Name
    }
    else {
        $base = $file.BaseName
    }

    #construct the image file name
    $out = Join-Path -Path $Destination -ChildPath "$base.$format"

    Write-Verbose "Extracting $ImageFormat image to $out"
    $ico =  [System.Drawing.Icon]::ExtractAssociatedIcon($file.FullName)

    if ($ico) {
        #WhatIf (target, action)
        if ($PSCmdlet.ShouldProcess($out, "Extract icon")) {
            $ico.ToBitmap().Save($Out,$Imageformat)
            Get-Item -path $out
        }
    }
    else {
        #this should probably never get called
        Write-Warning "No associated icon image found in $($file.fullname)"
    }

    Write-Verbose "Ending $($MyInvocation.MyCommand)"

The script will extract the icon from the file specified by the Path parameter and save it in the specified format. There are other formats, but I decided on a ValidateSet() attribute with the most likely formats. The script will create an output file name based on the destination and original file name. Or, you can specify an alternate base name. I also added support for -WhatIf.

With this script, I can run a command like this to extract the icon.

extracting icon whatit

That looks good. I'll re-run without -WhatIf to extract the icon.

ruby icon

Now, I can update my Windows Terminal setting.

{
    // Ruby cmd
    "guid" :"{a7849c4a-db74-4723-adf2-c717357f0a1a}",
    "name" : "Ruby",
    "commandline": "C:\\Windows\\System32\\cmd.exe /E:ON /K C:\\Ruby27-x64\\bin\\setrbvars.cmd",
    "tabTitle": "Ruby Cmd",
    "icon": "d:\\onedrive\\windowsterminal\\profileicons\\ruby.png"
},
ruby Windows Terminal session

I can do the same thing with Python.exe.

I hope you find this useful. You could easily turn it into a function. Comments and questions are always welcome.


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

1 thought on “Extracting Icons with PowerShell”

  1. Matt says:
    May 5, 2021 at 2:32 pm

    This is excellent. Thank you. The main thing this had that other posts didn’t was using the ImageFormat parameter to the Save() method of the Bitmap (i.e. System.Drawing.Image) class. All my previous attempts to save in other formats resulted in a loss of color depth. Cheers. == Matt

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d