Skip to content

Instantly share code, notes, and snippets.

@NakedPowerShell
Last active July 13, 2019 02:18
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save NakedPowerShell/9711e57e18fa4c4cd0fed148497f900e to your computer and use it in GitHub Desktop.
Save NakedPowerShell/9711e57e18fa4c4cd0fed148497f900e to your computer and use it in GitHub Desktop.
Script to generate all the exploration I normally do when I want to install a new PowerShell module
Function Show-ModExplore {
<#
.SYNOPSIS
Generate all the exploration I normally do when I want to install a new PowerShell module
.DESCRIPTION
Script to generate all the exploration I normally do when I want to install a new PowerShell module
and look at what each function does
.PARAMETER Module
The name of the PowerShell module to explore
.EXAMPLE
Show-ModExplore "dbachecks"
.NOTES
Script to generate all the exploration I normally do when I want to install a new PowerShell module
and look at what each function does
When I explore a new PowerShell module, I find I do the same steps over and over again
It was time to automate the exploration a little bit
For each parameter, the generated line for a splat will look something like this:
'PersonalAccessToken'='blank'; # String (None) [true]
PersonalAccessToken is the parameter name
'blank' is the default my code assigns it - based upon parameter data type
After the comment # is the data type; String, Int, DateTime,Bolean etc
In the () is the default of the parameter inside the function
In the [] is if the parameter is required i.e. mandatory, either true or false
Version History
v1.0 - [Twitter: @NakedPowerShell] [Blog: https://nakedpowershell.blogspot.com/ ] - Initial Release: 07/10/2018
#>
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $true, Mandatory = $true)]
[string]$Module
)
Clear-Host
$Today = Get-Date
if (Get-Module -ListAvailable -Name $Module) {
Write-Host "Module $Module is all ready installed"
}
else {
Write-Output "Run this command first to install the module $Module"
Write-Output "Install-Module $module -Verbose -Force -Scope CurrentUser"
Exit
}
$Version = Get-InstalledModule -Name $Module | Select-object Version
Write-Output "# Started Generated Exploration Code for $module : Version: $Version Created $Today By: $env:UserName"
$commands = Get-Command -Module $module | Where-Object -FilterScript {$_.Commandtype -eq 'function'}
$Outfile = "startup_" + $module + "_1.ps1"
#$eOutfile = "startup_" + $module + "_Error.txt"
#Write-Output "# Generated Exploration Code for $module : Version: $Version Created $Today By: $env:UserName" | Out-File $eoutFile
#Write-Output "" | Out-File $eoutFile -Append
Write-Output "# Generated Exploration Code for $module : Version: $Version Created $Today By: $env:UserName" | Out-File $outFile
Write-Output "" | Out-File $outFile -Append
Write-Output "Install-Module $module -Verbose -Force -Scope CurrentUser" | Out-File $outFile -Append
Write-Output "" | Out-File $outFile -Append
Write-Output "Import-Module $module" | Out-File $outFile -Append
Write-Output "" | Out-File $outFile -Append
Write-Output "Update-Module $module" | Out-File $outFile -Append
Write-Output "" | Out-File $outFile -Append
Write-Output "Get-Help $module -Examples" | Out-File $outFile -Append
Write-Output "" | Out-File $outFile -Append
Write-Output "Get-Help $module -Full" | Out-File $outFile -Append
Write-Output "" | Out-File $outFile -Append
Write-Output "Get-Help $module -Detailed" | Out-File $outFile -Append
Write-Output "" | Out-File $outFile -Append
foreach ($command in $commands) {
$commandName = $command.Name
Write-Output "# Function $commandname for $module"
Write-Output "# Function $commandname for $module" | Out-File $outFile -Append
Write-Output "" | Out-File $outFile -Append
Write-Output "Get-Help $commandname -Examples" | Out-File $outFile -Append
Write-Output "" | Out-File $outFile -Append
Write-Output "Get-Help $commandname -Full" | Out-File $outFile -Append
Write-Output "" | Out-File $outFile -Append
Write-Output "Get-Help $commandname -Detailed" | Out-File $outFile -Append
Write-Output "" | Out-File $outFile -Append
$Common = 'Debug', 'ErrorAction', 'ErrorVariable', 'InformationAction', 'InformationVariable', 'OutBuffer', 'OutVariable',
'PipelineVariable', 'Verbose', 'WarningAction', 'WarningVariable'
$Help = Get-Help $commandName -ErrorAction SilentlyContinue
$parameters = $command.ParameterSets.Parameters | Sort-Object -Property Name -Unique | Where-Object Name -notin $common
$O = "$" + "parms = @{"
Write-Output $O | Out-File $outFile -Append
foreach ($parameter in $parameters) {
$parameterName = $parameter.Name
$parameterHelp = $Help.parameters.parameter | Where-Object Name -EQ $parameterName
$p_PV = $parameterHelp.parameterValue
$p_DV = $parameterHelp.defaultValue
$p_MM = $parameterHelp.required
switch ( $p_PV ) {
"String" {
Write-Output "'$parametername'='blank'; # $p_PV ($p_DV) [$p_MM]" | Out-File $outFile -Append
}
"String[]" {
Write-Output "'$parametername'='blank'; # $p_PV ($p_DV) [$p_MM]" | Out-File $outFile -Append
}
"GUID" {
$G = [guid]::NewGuid()
Write-Output "'$parametername'='$G'; # $p_PV ($p_DV) [$p_MM]" | Out-File $outFile -Append
}
"GUID[]" {
$G = [guid]::NewGuid()
Write-Output "'$parametername'='$G'; # $p_PV ($p_DV) [$p_MM]" | Out-File $outFile -Append
}
"SwitchParameter" {
Write-Output "'$parametername'=`$false; # $p_PV ($p_DV) [$p_MM]" | Out-File $outFile -Append
}
"Int" {
Write-Output "'$parametername'=1; # $p_PV ($p_DV) [$p_MM]" | Out-File $outFile -Append
}
"Int[]" {
Write-Output "'$parametername'=1; # $p_PV ($p_DV) [$p_MM]" | Out-File $outFile -Append
}
"Int32" {
Write-Output "'$parametername'=1; # $p_PV ($p_DV) [$p_MM]" | Out-File $outFile -Append
}
"Int32[]" {
Write-Output "'$parametername'=1; # $p_PV ($p_DV) [$p_MM]" | Out-File $outFile -Append
}
"Bool" {
Write-Output "'$parametername'=`$false; # $p_PV ($p_DV) [$p_MM]" | Out-File $outFile -Append
}
"Boolean" {
Write-Output "'$parametername'=`$false; # $p_PV ($p_DV) [$p_MM]" | Out-File $outFile -Append
}
"Datetime" {
Write-Output "'$parametername'='$today'; # $p_PV ($p_DV) [$p_MM]" | Out-File $outFile -Append
}
default {
Write-Output "'$parametername'='blank'; # $p_PV ($p_DV) [$p_MM]" | Out-File $outFile -Append
#Write-Output "'$parametername'='blank'; # $p_PV ($p_DV) [$p_MM]" | Out-File $eoutFile -Append
}
}
}
Write-Output "}" | Out-File $outFile -Append
Write-Output "$commandName @parms -verbose -WhatIf" | Out-File $outFile -Append
Write-Output "" | Out-File $outFile -Append
}
Write-Output "# End Generated Exploration Code for $module : Created $Today By: $env:UserName"
Write-Output ""
Write-Output "# PowerShell script generated for module $module is : $outfile"
} # End of Show-ModExplore
Show-ModExplore "VSTeam"
@StevenDvn
Copy link

Some recommendations/questions:

Best practices state that you should output an object that can be passed on to other cmdlets/functions. I know this would be tricky with the type of output this generates, but there is no way to see the output other than to check the file contents.

Why not set the Module parameter as an array and use a process block and foreach loop to handle multiple modules passed into the function?

I would add a FileName parameter with a default location of $PSScriptRoot and filename like line 67 to allow the filename and location of the output to be specified (unless you take my previous advice and output an object). I would also add parameter validation to make sure the path specified exists but that the file specified does not, assuming you don't want to overwrite an existing file.

Clear-Host in your function? Please don't do that to the unsuspecting users of your otherwise awesome function. ;)

Why use Write-Host on line 53 and Write-Output on 56,57,63, etc.? If you don't want to pollute your success stream with informational messages then do use Write-Host, but you should also use it on lines 182 - 186.

Line 67 would be handled in the parameter block, however I would add a create file/write validation test at the top of the function to make sure the file can be created and/or written to.

Starting at line 73, the way I output to screen while also capturing to a file is to use Tee-Object. For example:
Write-Output "# Generated Exploration Code for $module : Version: $Version Created $Today By: $env:UserName" | Out-File $outFile
vs.
"# Generated Exploration Code for $module : Version: $Version Created $Today By: $env:UserName" | Tee-Object -FilePath $outFile -Append

The last line will always try to run the function on "VSTeam" whenever the function is loaded. Need to comment that line out to be able to properly use this function with a specified Module parameter.

Thanks for sharing your function. The above is what I would suggest for anyone's function, including my own. I like your idea and hope that my suggestions are helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment