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

Extending External Scripts in PowerShell

Posted on March 11, 2020

I'm always looking for ways to do more with PowerShell. And often, once I find a technique, I look for other areas where I can apply it. I'm hoping that today might be like that for you. You may not have a need to duplicate my work in this article, but hopefully you'll recognize value in the techniques and concepts and find your own ways to apply them. What I am interested in is extending and improving PowerShell results.

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!

In PowerShell, there are different types of commands. One type is an ExternalScript. These are PowerShell script files that can be run without specifying the path.

get-externalOf course, there is more to the output.get-profileIn short, this is just another file. As such I can get information.

Get-Command profile.ps1 | 
Select-Object -property Name,Path,@{Name="LastWriteTime";Expression={(Get-Item $_.path).lastWriteTime}},
@{Name="Location";Expression={Split-Path $_.source}}

It is important that you follow the object in the pipeline. Get-Command is writing a System.Management.Automation.ExternalScriptInfo object to the pipeline. I already know some of the properties I can use.  But I am also using a hashtable to define new properties. I'm creating a property called LastWriteTime. The value is the LastWriteTime value of the file object which I'm getting with Get-Item. I'm also creating a property called Location which will be the script's parent directory.

get-profile-extendedIt is just as easy now to apply this to all external scripts.

Get-Command -CommandType ExternalScript |Select-Object -property Name,Path,
@{Name="LastWriteTime";Expression={(Get-Item $_.path).lastWriteTime}},
@{Name="Location";Expression={Split-Path $_.source}} | 
Sort-Object -Property Location |
Format-Table -GroupBy Location -property Name,LastWriteTime

get-external-2
Now for the fun part. I want this type of information all the time. But I don't want to have to type out the custom hashtables. The solution is to add custom type extensions. And I can make this very easy.

I'm going to use a command from my PSTypeExtensionToolsmodule which you can install from the PowerShell Gallery. It works in Windows PowerShell and PowerShell 7, even cross-platform. Here's my code.

$tname = "System.Management.Automation.ExternalScriptInfo"
Add-PSTypeExtension -TypeName $tname -MemberType ScriptProperty -MemberName Location -Value {Split-Path $this.source}
Add-PSTypeExtension -TypeName $tname -MemberType ScriptProperty -MemberName Target -Value {
    $f = Get-Item $this.source
    #Use the target if the file is linked
    if ($f.Target) {
        $f.target
    }
    else {
        #use the full name
        $f.fullname
    }
}
Add-PSTypeExtension -TypeName $tname -MemberType ScriptProperty -MemberName LastWriteTime -Value {
    $f = Get-Item $this.source
    if ($f.Target) {
        (Get-Item -path $f.target).LastWriteTime
    }
    else {
        $f.LastWriteTime
    }
}

Yes, you can do something similar with Add-Member. But now see how easy my PowerShell command is.

get-external-3

On my system, I have a few scripts with symlinks which is why I'm showing a Target property.

These changes are only good in this PowerShell session. If I want them all the time, I'd have to insert the code into a profile script. However, I can simplify that  because I can export my extensions to a json file.

Get-PSTypeExtension -TypeName $tname | Export-PSTypeExtension -Path c:\scripts\externalscriptinfo.json

Then in my profile, I can have a single line of code to bring them in.

Import-PSTypeExtension C:\scripts\externalscriptinfo.json

But wait...there's more! Remember that awkward command from earlier to format external scripts as a grouped table? I can simplify that as well.
If you don't have it, install the PSScriptTools module from the PowerShell Gallery. Then you can use the New-PSFormatXML command to create a custom formatting file.

Get-Command mybackuppending.ps1 | New-PSFormatXML -Path c:\scripts\externalscriptinfo.format.ps1xml -Typename $tname -GroupBy Location -Properties Name, Target, LastWriteTime -ViewName location -FormatType table

In my PowerShell profile script I will import this file.

Update-FormatData C:\scripts\externalscriptinfo.format.ps1xml

Look how easy this is now.
get-external-formatted
I don't want to overwrite PowerShell's default view, but I can add my own. I love making PowerShell do what I need it to do. With just a little extra work I now have the information I need. In fact, I can already think of a few additions such as getting the file size and a new format view.

I hope this inspires you to transform PowerShell to make your life and work easier. Good luck!


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

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