Public/New-PSScriptScaffolding.ps1
Function New-PSScriptScaffolding { <# .SYNOPSIS Creates a new PowerShell script. .DESCRIPTION Creates a new PowerShell script and outputs the results to either the console or a file. .PARAMETER Author The name of the script's author. .PARAMETER CompanyName The company name of the script's author. .PARAMETER OutputPath The path to which to export the script. Absolute and relative paths are both supported. .PARAMETER Force Forces an overwrite of an existing file. .PARAMETER PassThru Returns output to the console in addition to producing a file. .EXAMPLE # Outputs a script framework to the console New-PSScriptScaffolding .EXAMPLE # Outputs a script framework to the console with a custon "Author Field" New-PSScriptScaffolding -Author "John Smith" .EXAMPLE # Outputs a script framework to a new script file New-PSScriptScaffolding -OutputPath "C:\Path\To\MyNewScript.ps1" .EXAMPLE # Overwrites a script framework to an existing script file New-PSScriptScaffolding -OutputPath "C:\Path\To\MyExistingScript.ps1" .EXAMPLE # Overwrites a script framework to an existing script file Get-Item "C:\Path\To\MyExistingScript.ps1" | New-PSScriptScaffolding .NOTES - PowerShell script files with the .ps1 extension are the only filetype supported. This is by design; .psm1 files should have an accompanying module manifest that contains the relevant metadata. #> [CmdletBinding(DefaultParameterSetName="Description")] PARAM ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [String]$Author, [Parameter(Mandatory=$false)] [ValidateNotNullOrEmpty()] [String]$CompanyName = $Author, [Parameter(Mandatory=$false)] [ValidateNotNullOrEmpty()] [String]$Version = '1.0.0', [Parameter(Mandatory=$false, Position=1, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Alias("Filename","FullName")] [String]$OutputPath ) # Create dynamic parameters DynamicParam { IF ($OutputPath) { # Create runtine dictionary $ParamDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() # Define parameter attributes $Attribute = [System.Management.Automation.ParameterAttribute]@{ Mandatory = $false } # Create attribute collection $AttributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]$Attribute # Create parameter object and add name, type, attribute collection $PassThruParameter = [System.Management.Automation.RuntimeDefinedParameter]::new('PassThru',[Switch],$AttributeCollection) $PassThruParameter.Value = $false $PSBoundParameters['PassThru'] = $PassThruParameter.Value # Add parameter to runtime dictionary $ParamDictionary.Add('PassThru',$PassThruParameter) # Create parameter object and add name, type, attribute collection $ForceParameter = [System.Management.Automation.RuntimeDefinedParameter]::new('Force',[Switch],$AttributeCollection) $ForceParameter.Value = $false $PSBoundParameters['Force'] = $ForceParameter.Value # Add parameter to runtime dictionary $ParamDictionary.Add('Force',$ForceParameter) return $ParamDictionary } } BEGIN { # Transfer Dynamic Parameters to runtime $PassThru = $PSBoundParameters['PassThru'] $Force = $PSBoundParameters['Force'] # Locally scope ErrorActionPreference for predictable behavior of Try/Catch blocks inside the function $ErrorActionPreference = 'Stop' # Declare Script block $ScriptBlock = Get-Content -Path "$PSScriptRoot/../Templates/Template_Script.ps1" -Raw # Build parameter block for New-ScriptFileInfo command in PROCESS block $Params = @{ Version = $Version Author = $Author CompanyName = $CompanyName Copyright = "(c) $($(Get-Date).Year) $CompanyName" Description = "Blank" } } PROCESS { # Create output variable $Results = '' #region Generate Script Info $ScriptInfo = ((New-ScriptFileInfo @Params -PassThru).Split('>')[0]+'>' + "`r`n`r`n").TrimStart("`r`n") # Add ScriptInfo and ScriptBlock to results $Results = $ScriptInfo + $ScriptBlock IF ($OutputPath) { # Test whether output path is a file or directory SWITCH -Regex ($OutputPath) { # Test whether $OutputPath is a .ps1 file ".ps1$" { $OutputFilename = $OutputPath.Split('\')[-1] $OutputDirectory = $OutputPath.Substring(0,$OutputPath.LastIndexOf('\')) } Default { Write-Error "$OutputPath is not a .ps1 file. Please specify a valid filepath and try again." -ErrorAction Continue Continue } } # Create directory if it doesn't exist IF (!(Test-Path $OutputDirectory)) { TRY { New-Item -Path $OutputDirectory -ItemType File -Force | Out-Null } CATCH { Write-Warning "Unable to create directory $OutputDirectory. Defaulting to present working directory: $PWD" $OutputDirectory = $PWD } } # Output file $Results | Out-File $OutputDirectory\$OutputFilename -Encoding ascii -Force:$Force } # Return results to the console if an output has not been specified or -Passthru has been selected IF(!$OutputPath -or $Passthru) { Write-Output $Results } } END { # Nothing to see here. Move along. } } |