Last active
July 13, 2019 02:18
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.