42

I'm learning some PowerShell. Is it possible to see the source code for a built-in cmdlet like Get-ChildItem?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 2
    You can now - https://github.com/PowerShell/PowerShell/blob/HEAD/src/Microsoft.PowerShell.Commands.Management/commands/management/GetChildrenCommand.cs. – codekaizen Aug 21 '16 at 16:46

10 Answers10

35

The source for Powershell is now available on Github.
The source for Get-ChildItem can be found here.

Zev Spitz
  • 13,950
  • 6
  • 64
  • 136
22

Actually, your best bet is to go check out PowerShell Community Extensions. This open source software community project is "aimed at providing a widely useful set of additional cmdlets...". The developers on the project are PowerShell MVPs and know their stuff.

As far as using reflection on the existing PowerShell cmdlets, PowerShell MVP Oisin Grehan made a handy function titled "Reflect-Cmdlet". I won't steal his code and place it here, but basically what you do is:

Get-Command Get-ChildItem | Reflect-Cmdlet

And then .NET Reflector pops up with the right assembly opened up and expanded and everything. It's really pretty cool.

KyleMit
  • 30,350
  • 66
  • 462
  • 664
halr9000
  • 9,879
  • 5
  • 33
  • 34
  • 5
    +1 for the link to `Reflect-Cmdlet`, it was very helpful. Modified to make it work with Jetbrains DotPeek. https://gist.github.com/dennisroche/013c5a56d9a7f16851cb – Dennis Aug 10 '14 at 03:48
  • That cmd-let has an invalid SSL certificate. This also appears to be [possibly without using any third-party tools](https://stackoverflow.com/a/32189485/542251) – Liam Mar 03 '20 at 16:26
16

For compiled Cmdlets, you can get the path to the .dll with:

(Get-Command Get-ChildItem).DLL

(Replace Get-ChildItem with the cmdlet you are interested in)

Example:

PS C:\Windows\system32> (Get-Command Get-StoragePool).DLL

PS C:\Windows\system32> 

Once you know the path to the .dll, you can open it with a .NET disassembler like dotPeek:

& dotPeek64.exe (Get-Command Get-ChildItem).DLL
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
Michael Kropat
  • 14,557
  • 12
  • 70
  • 91
  • Fascinating, this doesn't seem to work in PowerShell 7.0 with the DnsClient module, for example. Also, `Get-Module DnsClient|Get-Member` shows no DLL property/member. – 0xC0000022L Jan 10 '22 at 11:50
13

I think if you were just starting PowerShell, this is what you'd be looking for:

$metadata = New-Object system.management.automation.commandmetadata (Get-Command Get-Process)
[System.management.automation.proxycommand]::Create($MetaData) | out-file C:\powershell\get-process.ps1

This will create a script which shows how Get-Process runs. Put in any cmdlet you want to replace Get-Process. If you want to google more about it, this is how you would create a proxy function.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ImpossibleSqui
  • 263
  • 1
  • 3
  • 6
  • Nice and simple, no need for Reflector.NET or DotPeek, cheers. By the way, `[System.management.automation.proxycommand]::Create($MetaData)` seems sufficient for me, to just display the results on screen. – Simon Elms Apr 18 '15 at 05:00
  • 7
    This creates a [proxy command](http://blogs.msdn.com/b/powershell/archive/2009/01/04/extending-and-or-modifing-commands-with-proxies.aspx), which isn't the same thing as looking at the source code at all. This doesn't give you the source code for Get-Process, or show you how it runs; it returns a base script that you could use to modify the cmdlet, for example, by adding additional parameters to it. – Micah R Ledbetter May 18 '15 at 21:55
3

You might also like to take a look at Windows Installer PowerShell Snap-In on CodePlex. It's a smaller project than the community extensions, so it is easier to get your head around what's going on.

Check out Professional Windows PowerShell Programming: Snapins, Cmdlets, Hosts and Providers (Wrox Professional Guides), ISBN: 0470173939 - it's one of the most useful books I've found for writing cmdlets and providers.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
2

You should be able to use .NET Reflector to "see" the source code. You need to know the assembly though, but it should also accessible using the GetType method or similar.

This PowerShellLanguage .NET Reflector Add-In can perhaps be useful.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
dalle
  • 18,057
  • 5
  • 57
  • 81
1

For some cmdlets that are installed with Install-Module and contain source code and not binaries, (e.g. PSnmap):

Install-Module -Name PSnmap

...you can view their code by looking at the Definition property from:

Get-Command Invoke-PSnmap | Format-List

If not, most likely, you will need to decompile some binary (e.g. the file specified in the DLL property).

user2173353
  • 4,316
  • 4
  • 47
  • 79
1

PowerShell cmdlets' assemblies are located in GAC. You can find "Get-ChildItem" cmdlet in:

Microsoft.PowerShell.Commands.Management assembly, Microsoft.PowerShell.Commands.GetChildItemCommand class.

I've used ILSpy .NET decompiler and filtered GAC assemblies by "powershell" string. As I understand, Microsoft.PowerShell.Commands.* assemblies contain built-in cmdlets.

Charlie Joynt
  • 4,411
  • 1
  • 24
  • 46
0

Some code can be found on the Reference Resource Site: http://referencesource.microsoft.com/#System.Management.Automation/System/Management/Automation/ChildItemCmdletProviderIntrinsics.cs,c6eed9f6a5417c19

This only gives the outline though; not the code's detail.

JohnLBevan
  • 22,735
  • 13
  • 96
  • 178
-1

I do not believe that the source code for PowerShell has ever been released.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
EBGreen
  • 36,735
  • 12
  • 65
  • 85