Skip to content

Commit dcc15df

Browse files
committed
Refactor New-CommandDataFile script
1 parent 4b0117c commit dcc15df

1 file changed

Lines changed: 99 additions & 99 deletions

File tree

Utils/New-CommandDataFile.ps1

Lines changed: 99 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,115 @@
1-
<#
2-
.SYNOPSIS
3-
Create a JSON file containing module found in $pshome and their corresponding exported commands
4-
5-
.EXAMPLE
6-
C:\PS> ./New-CommandDataFile.ps1
7-
8-
Suppose this file is run on the following version of PowerShell: PSVersion = 6.1.0, PSEdition = Core, and Windows 10 operating system. Then this script will create a file named core-6.1.0-windows.json that contains a JSON object of the following form:
9-
{
10-
"Modules" : [
11-
"Module1" : {
12-
"Name" : "Module1"
13-
.
14-
.
15-
"ExportedCommands" : {...}
16-
}
17-
.
18-
.
19-
.
20-
]
21-
"JsonVersion" : "0.0.1"
22-
}
1+
[OutputType([System.IO.FileInfo])]
2+
[CmdletBinding()]
3+
param(
4+
[string]$OutputPath = './' # Default is current directory
5+
)
236

24-
.INPUTS
25-
None
7+
function New-CommandDataFile {
8+
<#
9+
.SYNOPSIS
10+
Create a JSON file containing modules found in $PSHOME and their corresponding exported
11+
commands and aliases.
2612
27-
.OUTPUTS
28-
None
13+
.DESCRIPTION
14+
This script creates a JSON file containing modules found in $PSHOME and their corresponding
15+
exported commands and aliases. The JSON file is created in the current directory by default.
16+
Be sure to run this script in a clean PowerShell session to avoid picking up any aliases
17+
that may have been added by the user's profile script.
2918
30-
#>
19+
.PARAMETER OutputPath
20+
The path where the JSON file is created. If not specified, the file is created in the
21+
current directory.
3122
32-
$jsonVersion = "0.0.1"
33-
$builtinModulePath = Join-Path $pshome 'Modules'
34-
if (-not (Test-Path $builtinModulePath))
35-
{
36-
throw new "$builtinModulePath does not exist! Cannot create command data file."
37-
}
23+
.EXAMPLE
24+
New-CommandDataFile C:\Temp
3825
39-
Function IsPSEditionDesktop
40-
{
41-
$edition = Get-Variable -Name PSEdition -ErrorAction Ignore
42-
($edition -eq $null) -or ($edition.Value -eq 'Desktop') # $edition is of type psvariable
43-
}
26+
If you run this example in PowerShell 7.6.4 on Windows, it creates a file named
27+
core-7.6.4-windows.json in the C:\Temp directory.
28+
29+
.INPUTS
30+
None
31+
32+
.OUTPUTS
33+
System.IO.FileInfo
34+
#>
4435

45-
Function Get-CmdletDataFileName
46-
{
47-
$edition = 'core'
48-
$os = 'windows'
49-
if ((IsPSEditionDesktop))
50-
{
36+
[OutputType([System.IO.FileInfo])]
37+
[CmdletBinding()]
38+
param(
39+
[string]$OutputPath = './' # Default is current directory
40+
)
41+
42+
$builtinModulePath = Microsoft.PowerShell.Management\Join-Path $PSHOME 'Modules'
43+
if (-not (Microsoft.PowerShell.Management\Test-Path $builtinModulePath)) {
44+
throw new "$builtinModulePath does not exist! Cannot create command data file."
45+
}
46+
47+
## Get the PowerShell edition, OS, and platform to create a unique file name for the JSON file
48+
49+
$edition = Microsoft.PowerShell.Utility\Get-Variable -Name PSEdition -ErrorAction Ignore
50+
if (($edition -eq $null) -or ($edition.Value -eq 'Desktop')) {
5151
$edition = 'desktop'
52+
} else {
53+
$edition = 'core'
54+
}
55+
if ($IsLinux) {
56+
$os = 'linux'
57+
} elseif ($IsMacOS) {
58+
$os = 'macos'
59+
} else{
60+
$os = 'windows'
5261
}
53-
else
54-
{
55-
if ($IsLinux)
56-
{
57-
$os = 'linux'
62+
63+
$joinPathSplat = @{
64+
Path = $OutputPath
65+
ChildPath = "$edition-$($PSVersionTable.PSVersion.ToString())-$os.json"
66+
}
67+
$outputFileName = Microsoft.PowerShell.Management\Join-Path @joinPathSplat
68+
69+
$jsonData = @{
70+
SchemaVersion = '0.0.1'
71+
Modules = @()
72+
}
73+
74+
$modules = (Microsoft.PowerShell.Management\Get-ChildItem -Path $builtinModulePath -Directory).Name
75+
$modules += 'Microsoft.PowerShell.Core' # Add the Microsoft.PowerShell.Core snap-in to the list
76+
foreach ($module in $modules) {
77+
Microsoft.PowerShell.Utility\Write-Verbose "Processing module $module"
78+
$commands = Microsoft.PowerShell.Core\Get-Command -Module $module
79+
$shortCommands = $commands |
80+
Microsoft.PowerShell.Utility\Select-Object -Property Name,
81+
@{Label = 'CommandType'; Expression = { $_.CommandType.ToString() } },
82+
@{Label = 'ParameterSets'; Expression = { $_.ParameterSets -join ' ' } }
83+
<#
84+
Microsoft.PowerShell.Core doesn't export aliases so we can't use $module.ExportedAliases.
85+
Some aliases are preloaded during PowerShell startup. This code ensures that we find aliases
86+
for Microsoft.PowerShell.Core or any other aliases that are preloaded. This has the side
87+
effect of also finding aliases for commands that may have been added by the user's profile
88+
script. Run this command in a clean PowerShell session to avoid picking up any aliases that
89+
may have been added by the user's profile script.
90+
#>
91+
$aliases = Microsoft.PowerShell.Utility\Get-Alias * |
92+
Microsoft.PowerShell.Core\Where-Object { ($commands).Name -contains $_.ResolvedCommandName }
93+
if ($null -eq $aliases) {
94+
$aliases = @()
95+
} else {
96+
$aliases = $aliases.Name
5897
}
59-
elseif ($IsMacOS)
60-
{
61-
$os = 'macos'
98+
99+
$jsonData.Modules += [pscustomobject]@{
100+
Name = $module
101+
Version = $commands[0].Version.ToString()
102+
ExportedCommands = $shortCommands
103+
ExportedAliases = $aliases
62104
}
63-
# else it is windows, which is already set
64105
}
65-
$sb = New-Object 'System.Text.StringBuilder'
66-
$sb.Append($edition) | Out-Null
67-
$sb.Append('-') | Out-Null
68-
$sb.Append($PSVersionTable.PSVersion.ToString()) | Out-Null
69-
$sb.Append('-') | Out-Null
70-
$sb.Append($os) | Out-Null
71-
$sb.Append('.json') | Out-Null
72-
$sb.ToString()
73-
}
74106

75-
$jsonData = @{}
76-
$jsonData['SchemaVersion'] = $jsonVersion
77-
$shortModuleInfos = Get-ChildItem -Path $builtinModulePath `
78-
| Where-Object {($_ -is [System.IO.DirectoryInfo]) -and (Get-Module $_.Name -ListAvailable)} `
79-
| ForEach-Object {
80-
$modules = Get-Module $_.Name -ListAvailable
81-
$modules | ForEach-Object {
82-
$module = $_
83-
Write-Progress $module.Name
84-
$commands = Get-Command -Module $module
85-
$shortCommands = $commands | Select-Object -Property Name,@{Label='CommandType';Expression={$_.CommandType.ToString()}},ParameterSets
86-
$shortModuleInfo = $module | Select-Object -Property Name,@{Label='Version';Expression={$_.Version.ToString()}}
87-
Add-Member -InputObject $shortModuleInfo -NotePropertyName 'ExportedCommands' -NotePropertyValue $shortCommands
88-
Add-Member -InputObject $shortModuleInfo -NotePropertyName 'ExportedAliases' -NotePropertyValue $module.ExportedAliases.Keys -PassThru
89-
}
90-
}
107+
$jsonData |
108+
Microsoft.PowerShell.Utility\ConvertTo-Json -Depth 4 |
109+
Microsoft.PowerShell.Utility\Out-File $outputFileName -Encoding utf8
91110

92-
# Microsoft.PowerShell.Core is a PSSnapin, hence not handled by the previous code snippet
93-
# get-module -name 'Microsoft.PowerShell.Core' returns null
94-
# whereas get-PSSnapin is not available on PowerShell Core, so we resort to the following
95-
$psCoreSnapinName = 'Microsoft.PowerShell.Core'
96-
Write-Progress $psCoreSnapinName
97-
$commands = Get-Command -Module $psCoreSnapinName
98-
$shortCommands = $commands | Select-Object -Property Name,@{Label='CommandType';Expression={$_.CommandType.ToString()}},ParameterSets
99-
$shortModuleInfo = New-Object -TypeName PSObject -Property @{Name=$psCoreSnapinName; Version=$commands[0].PSSnapin.PSVersion.ToString()}
100-
Add-Member -InputObject $shortModuleInfo -NotePropertyName 'ExportedCommands' -NotePropertyValue $shortCommands
101-
102-
# Find the exported aliases for the commands in Microsoft.PowerShell.Core
103-
$aliases = Get-Alias * | Where-Object { ($commands).Name -contains $_.ResolvedCommandName }
104-
if ($null -eq $aliases) {
105-
$aliases = @()
106-
}
107-
else {
108-
$aliases = $aliases.Name
111+
Microsoft.PowerShell.Management\Get-Item $outputFileName
109112
}
110113

111-
Add-Member -InputObject $shortModuleInfo -NotePropertyName 'ExportedAliases' -NotePropertyValue $aliases
112114

113-
$allShortModuleInfos = $shortModuleInfos + $shortModuleInfo
114-
$jsonData['Modules'] = $allShortModuleInfos
115-
$jsonData | ConvertTo-Json -Depth 4 | Out-File ((Get-CmdletDataFileName)) -Encoding utf8
115+
New-CommandDataFile -OutputPath $OutputPath

0 commit comments

Comments
 (0)