Skip to content

Instantly share code, notes, and snippets.

@davidwallis3101
Created April 2, 2019 10:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidwallis3101/58de8462bf37c8683b377cb0c7a5a95b to your computer and use it in GitHub Desktop.
Save davidwallis3101/58de8462bf37c8683b377cb0c7a5a95b to your computer and use it in GitHub Desktop.
Refactor PSM1 powershell module into seperate ps1 files
<#
.SYNOPSIS
RefactorPSM1.ps1
.DESCRIPTION
RefactorPSM1.ps1
.NOTES
For additonal information please contact david@wallis2000.co.uk
.LINK
http://blog.wallis2000.co.uk/2019/04/refactoring-psm1-based-modules-into.html
#>
[Cmdletbinding()]
Param(
[Parameter(Mandatory=$true)]
[ValidateScript({
if(-Not ($_ | Test-Path) ){
throw "File does not exist"
}
if(-Not ($_ | Test-Path -PathType Leaf) ){
throw "The Path argument must be a file. Folder paths are not allowed."
}
return $true
})]
[System.IO.FileInfo]$PSM1FileName,
[Parameter(Mandatory=$true)]
[ValidateScript({
if(-Not ($_ | Test-Path) ) {
throw "Folder does not exist"
}
if(-Not ($_ | Test-Path -PathType Container)) {
throw "The Path argument must be a folder. File paths are not allowed."
}
return $true
})]
[System.IO.FileInfo]$OutputPath
)
$token = $null
$err = $null
$ast = [System.Management.Automation.Language.Parser]::ParseFile($PSM1FileName, [ref]$token, [ref]$err)
$functionDefinitions = $ast.FindAll({
param(
[System.Management.Automation.Language.Ast]$Ast
)
$Ast -is [System.Management.Automation.Language.FunctionDefinitionAst] `
-and ($PSVersionTable.PSVersion.Major -lt 5 `
-or $Ast.Parent -isnot [System.Management.Automation.Language.FunctionMemberAst])
}, $true)
$OutputPath = "$($OutputPath)\{0}\Public" -f [System.IO.Path]::GetFileNameWithoutExtension($PSM1FileName)
if (-not (Test-Path $outputPath)) {
$null = New-Item -Path $OutputPath -ItemType Container
}
$PSM1 = @'
# Get public and private function definition files.
$Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue )
$Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue )
# Dot source the files
ForEach ($import in @($Public + $Private)) {
Try {
. $import.fullname
}
Catch {
Write-Error -Message "Failed to import function $($import.fullname): $_"
}
}
Export-ModuleMember -Function $Public.Basename
'@
Write-Warning "Only code within functions will be 'refactored'"
$functionDefinitions | ForEach-Object {
Write-Verbose "Processing Function: $($_.Name)"
$_.Extent.Text | Out-File (Join-Path -Path $OutputPath -ChildPath "$($_.Name).ps1")
}
# Create a PSM1 file that dot sources all the public functions - by default all are created as 'Public'
$PSM1 | Out-File (Join-Path -Path ($OutputPath | Split-Path -Parent) -ChildPath ([System.IO.Path]::GetFileName($PSM1FileName)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment