IconForGUI.psm1

#Add required assemblies
Add-Type -AssemblyName System.Drawing, WindowsBase, PresentationCore

#Add Win32 API Functions
Add-Type -Namespace Win32API -Name Icon -MemberDefinition @'
    [DllImport("Shell32.dll", SetLastError=true)]
    public static extern int ExtractIconEx(string lpszFile, int nIconIndex, out IntPtr phiconLarge, out IntPtr phiconSmall, int nIcons);
 
    [DllImport("gdi32.dll", SetLastError=true)]
    public static extern bool DeleteObject(IntPtr hObject);
'@


Function Get-IconFromFile {
    <#
    .SYNOPSIS
    Gets icons from .exe, .dll, and icon files
 
    .DESCRIPTION
    Get-IconFromFile retrieves icons from .exe, .dll, and icon files. If the file contains more than one, you can specify the index of the icon with the Index parameter.
 
    By default the command retrieves the small version of the icons, but it can return the large version, if they exist, by using the LargeIcon switch.
    .PARAMETER Path
    The path to the file containing the icon to retrieve.
    .PARAMETER Index
    The index of the icon if the file contains more than one.
    .PARAMETER LargeIcon
    Specifies that the large version should be retrieved.
    .INPUTS
    System.String
 
    Get-IconFromFile accepts string objects of file paths to the Path parameter binding to the Path property.
    .OUTPUTS
    System.Drawing.Icon
 
    Get-IconFromFile outputs a System.Drawing.Icon object representing the icon.
    .EXAMPLE
    PS C:> Get-IconFromFile -Path setupapi.dll -Index 21
 
    This command will retrieve the small icon located in the setupapi.dll file located at the 21st index.
    .EXAMPLE
    PS C:> Get-IconFromFile -Path setupapi.dll -Index 21 -LargeIcon
 
    This command will retrieve the large icon located in the setupapi.dll file located at the 21st index.
    .NOTES
    The basis for this command came from a post by Kazun on the forum http://social.technet.microsoft.com/Forums/en/winserverpowershell/thread/16444c7a-ad61-44a7-8c6f-b8d619381a27
    #>


    [CmdletBinding()]

    Param(
        [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
            [Alias("FullName")]
            [String[]]$Path,

        [Parameter(Position=1)]
            [Int]$Index=0,

        [Switch]$LargeIcon
    )

    Process {
        foreach ($p in $Path) {
            #Initialize variables for reference conversion
            $large,$small = 0,0

            #Call Win32 API Function for handles
            [Win32API.Icon]::ExtractIconEx($p, $Index, [ref]$large, [ref]$small, 1) | Out-Null

            #If large icon desired store large handle, default to small handle
            $handle = if ($LargeIcon) {$large} else {$small}
    
            #Get the icon from the handle
            if ($handle) {
                [System.Drawing.Icon]::FromHandle($handle)
            }

            #If the handles are valid, delete them for good memory practice
            $large, $small, $handle | Where-Object {$_} | ForEach-Object {[Win32API.Icon]::DeleteObject($_)} | Out-Null
        }
    }
}

Function Get-AssociatedIcon {
    <#
    .SYNOPSIS
    Gets the icon associated with a program or file.
 
    .DESCRIPTION
    Get-AssociatedIcon retrieves the icon that Windows associates with that program or file.
    .PARAMETER Path
    The path to the file containing the image to retrieve.
    .INPUTS
    System.String
 
    Get-AssociatedIcon accepts string objects of file paths to the Path parameter binding to the Path property.
    .OUTPUTS
    System.Drawing.Icon
 
    Get-AssociatedIcon outputs a System.Drawing.Icon object representing the icon.
    .EXAMPLE
    PS C:> Get-AssociatedIcon -Path C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
 
    This command will retrieve the icon associated with the PowerShell program.
    #>


    [CmdletBinding()]

    Param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
            [Alias("FullName")]
            [String[]]$Path
    )

    Process {
        foreach ($p in $Path) {
            [System.Drawing.Icon]::ExtractAssociatedIcon($p)
        }
    }
}
        

Function Get-ImageSourceFromFile {
    <#
    .SYNOPSIS
    Gets ImageSource object from a bitmap file to be used as an icon.
 
    .DESCRIPTION
    Get-ImageSourceFromFile gets an ImageSource object from a bitmap file to use as an icon. The Path parameter can accept file paths, network shares, or web addresses, as long as the destination is a bitmap image, such as a .png or .ico.
    .PARAMETER Path
    The path to the file containing the bitmap image to retrieve.
    .INPUTS
    System.String
 
    Get-ImageSourceFromFile accepts string objects of URI paths to the Path parameter binding to the Path property.
    .OUTPUTS
    System.Windows.Media.Imaging.BitmapImage
 
    Get-ImageSourceFromFile outputs a System.Windows.Media.Imaging.BitmapImage object representing the bitmap image.
    .EXAMPLE
    PS C:> Get-ImageSourceFromFile -Path C:\SomeIconFile.ico
 
    This command will retrieve the ImageSource object from the bitmap file.
    #>


    [CmdletBinding()]

    Param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
            [Alias("FullName")]
            [String[]]$Path
    )

    Process {
        foreach ($p in $Path) {
            New-Object System.Windows.Media.Imaging.BitmapImage -ArgumentList $p
        }
    }
}

Function ConvertTo-ImageSource {
    <#
    .SYNOPSIS
    Converts a System.Drawing.Icon into a System.Windows.Interop.InteropBitmap.
 
    .DESCRIPTION
    ConvertTo-ImageSource converts a System.Drawing.Icon, which are used in Windows Forms applications, into a System.Windows.InteropBitmap, a descendent of the ImageSource class used by icons for WPF applications.
    .PARAMETER Icon
    The icon to convert into an ImageSource
    .INPUTS
    System.Drawing.Icon
 
    ConvertTo-ImageSource accepts System.Drawing.Icon objects to the Icon parameter binding to the Icon property.
    .OUTPUTS
    System.Windows.Interop.InteropBitmap
 
    ConvertTo-ImageSource outputs a System.Windows.Interop.InteropBitmap object representing the bitmap image.
    .EXAMPLE
    PS C:> ConvertTo-ImageSource -Icon $Form.Icon
 
    This command will convert the icon used in the Windows Form $Form into an ImageSource derived bitmap image that can be used in WPF applications.
    .EXAMPLE
    PS C:> Get-IconFromFile -Path setupapi.dll -Index 21 | ConvertTo-ImageSource
 
    This command will get the icon at index 21 from the setupapi.dll and then convert it to an ImageSource derived bitmap image that can be used in WPF applications.
    #>


    [CmdletBinding()]
    
    Param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
            [System.Drawing.Icon]$Icon
    )

    Process {
        foreach ($i in $Icon) {
            [System.Windows.Interop.Imaging]::CreateBitmapSourceFromHIcon(
                $i.Handle, 
                (New-Object System.Windows.Int32Rect -Args 0,0,$i.Width, $i.Height),
                [System.Windows.Media.Imaging.BitmapSizeOptions]::FromEmptyOptions()
            )
        }
    }
}

New-Alias -Name gif -Value Get-IconFromFile
New-Alias -Name gai -Value Get-AssociatedIcon
New-Alias -Name gisf -Value Get-ImageSourceFromFile
New-Alias -Name ctis -Value ConvertTo-ImageSource