functions/utility/New-PssModuleProject.ps1
function New-PssModuleProject { <# .SYNOPSIS Builds a Sapien PowerShell Studio Module Project from a regular module. .DESCRIPTION Builds a Sapien PowerShell Studio Module Project, either a clean one, or imports from a regular module. Will ignore all hidden files and folders, will also ignore all files and folders in the root folder that start with a dot ("."). Importing from an existing module requires the module to have a valid manifest. .PARAMETER Name The name of the folder to create the project in. Will also be used to name a blank module project. (When importing a module into a project, the name will be taken from the manifest file). .PARAMETER Path The path to create the new module-project folder in. Will default to the PowerShell Studio project folder. The function will fail if PSS is not found on the system and no path was specified. .PARAMETER SourcePath The path to the module to import from. Specify the path the the root folder the actual module files are in. .PARAMETER Force Force causes the function to overwrite all stuff in the destination folder ($Path\$Name), if it already exists. .EXAMPLE PS C:\> New-PssModuleProject -Name 'Foo' Creates a new module project named "Foo" in your default project folder. .EXAMPLE PS C:\> New-PssModuleProject -Name dbatools -SourcePath "C:\Github\dbatools" Imports the dbatools github repo's local copy into a new PSS module project in your default project folder. .EXAMPLE PS C:\> New-PssModuleProject -name 'Northwind' -SourcePath "C:\Github\Northwind" -Path "C:\Projects" -Force Will create a new module project, importing from "C:\Github\Northwind" and storing it in "C:\Projects". It will overwrite any existing folder named "Northwind" in the destination folder. .NOTES Author: Friedrich Weinmann Editors: - Created on: 01.03.2017 Last Change: 01.03.2017 Version: 1.0 Release 1.0 (01.03.2017, Friedrich Weinmann) - Initial Release #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding(DefaultParameterSetName = "Vanilla")] Param ( [Parameter(Mandatory = $true)] [string] $Name, [ValidateScript({ Test-Path -Path $_ -PathType Container })] [string] $Path, [Parameter(Mandatory = $true, ParameterSetName = "Import")] [string] $SourcePath, [switch] $Force ) if (Test-PSFParameterBinding -ParameterName "Path" -Not) { try { $pssRoot = (Get-ChildItem "HKCU:\Software\SAPIEN Technologies, Inc." -ErrorAction Stop | Where-Object Name -like "*PowerShell Studio*" | Select-Object -last 1 -ExpandProperty Name).Replace("HKEY_CURRENT_USER", "HKCU:") $Path = (Get-ItemProperty -Path "$pssRoot\Settings" -Name "DefaultProjectDirectory" -ErrorAction Stop).DefaultProjectDirectory } catch { throw "No local PowerShell Studio found and no path specified. Going to take a break now. Bye!" } } switch ($PSCmdlet.ParameterSetName) { #region Vanilla "Vanilla" { if ((-not $Force) -and (Test-Path (Join-Path $Path $Name))) { throw "There already is an existing folder in '$Path\$Name', cannot create module!" } $root = New-Item -Path $Path -Name $Name -ItemType Directory -Force:$Force $Guid = [guid]::NewGuid().Guid # Create empty .psm1 file Set-Content -Path "$($root.FullName)\$Name.psm1" -Value "" #region Create Manifest Set-Content -Path "$($root.FullName)\$Name.psd1" -Value @" @{ # Script module or binary module file associated with this manifest ModuleToProcess = '$Name.psm1' # Version number of this module. ModuleVersion = '1.0.0.0' # ID used to uniquely identify this module GUID = '$Guid' # Author of this module Author = '' # Company or vendor of this module CompanyName = '' # Copyright statement for this module Copyright = '(c) $((Get-Date).Year). All rights reserved.' # Description of the functionality provided by this module Description = 'Module description' # Minimum version of the Windows PowerShell engine required by this module PowerShellVersion = '2.0' # Name of the Windows PowerShell host required by this module PowerShellHostName = '' # Minimum version of the Windows PowerShell host required by this module PowerShellHostVersion = '' # Minimum version of the .NET Framework required by this module DotNetFrameworkVersion = '2.0' # Minimum version of the common language runtime (CLR) required by this module CLRVersion = '2.0.50727' # Processor architecture (None, X86, Amd64, IA64) required by this module ProcessorArchitecture = 'None' # Modules that must be imported into the global environment prior to importing # this module RequiredModules = @() # Assemblies that must be loaded prior to importing this module RequiredAssemblies = @() # Script files (.ps1) that are run in the caller's environment prior to # importing this module ScriptsToProcess = @() # Type files (.ps1xml) to be loaded when importing this module TypesToProcess = @() # Format files (.ps1xml) to be loaded when importing this module FormatsToProcess = @() # Modules to import as nested modules of the module specified in # ModuleToProcess NestedModules = @() # Functions to export from this module FunctionsToExport = '*' #For performanace, list functions explicity # Cmdlets to export from this module CmdletsToExport = '*' # Variables to export from this module VariablesToExport = '*' # Aliases to export from this module AliasesToExport = '*' #For performanace, list alias explicity # List of all modules packaged with this module ModuleList = @() # List of all files packaged with this module FileList = @() # Private data to pass to the module specified in ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. PrivateData = @{ #Support for PowerShellGet galleries. PSData = @{ # Tags applied to this module. These help with module discovery in online galleries. # Tags = @() # A URL to the license for this module. # LicenseUri = '' # A URL to the main website for this project. # ProjectUri = '' # A URL to an icon representing this module. # IconUri = '' # ReleaseNotes of this module # ReleaseNotes = '' } # End of PSData hashtable } # End of PrivateData hashtable } "@ #endregion Create Manifest #region Create project file Set-Content -Path "$($root.FullName)\$Name.psproj" -Value @" <Project> <Version>2.0</Version> <FileID>$Guid</FileID> <ProjectType>1</ProjectType> <Folders /> <Files> <File Build="2">$Name.psd1</File> <File Build="0">$Name.psm1</File> </Files> </Project> "@ #endregion Create project file } #endregion Vanilla #region Import "Import" { $SourcePath = Resolve-Path $SourcePath if (-not (Test-Path $SourcePath)) { throw "Source path was not detectable!" } if ((-not $Force) -and (Test-Path (Join-Path $Path $Name))) { throw "There already is an existing folder in '$Path\$Name', cannot create module!" } $items = Get-ChildItem -Path $SourcePath | Where-Object Name -NotLike ".*" $root = New-Item -Path $Path -Name $Name -ItemType Directory -Force:$Force $items | Copy-Item -Destination $root.FullName -Recurse -Force $items_directories = Get-ChildItem -Path $root.FullName -Recurse -Directory $items_psd = Get-Item "$($root.FullName)\*.psd1" | Select-Object -First 1 if (-not $items_psd) { throw "no module manifest found!" } $ModuleName = $items_psd.BaseName $items_files = Get-ChildItem -Path $root.FullName -Recurse -File | Where-Object { ($_.FullName -ne $items_psd.FullName) -and ($_.FullName -ne $items_psd.FullName.Replace(".psd1",".psm1")) } $Guid = (Get-Content $items_psd.FullName | Select-String "GUID = '(.+?)'").Matches[0].Groups[1].Value $string_Files = ($items_files | Select-Object -ExpandProperty FullName | ForEach-Object { " <File Build=`"2`" Shared=`"True`">$(($_ -replace ([regex]::Escape(($root.FullName + "\"))), ''))</File>" }) -join "`n" $string_Directories = ($items_Directories | Select-Object -ExpandProperty FullName | ForEach-Object { " <Folder>$(($_ -replace ([regex]::Escape(($root.FullName + "\"))), ''))</Folder>" }) -join "`n" Set-Content -Path "$($root.FullName)\$ModuleName.psproj" -Value @" <Project> <Version>2.0</Version> <FileID>$Guid</FileID> <ProjectType>1</ProjectType> <Folders> $($string_Directories) </Folders> <Files> <File Build="2">$ModuleName.psd1</File> <File Build="0">$ModuleName.psm1</File> $($string_Files) </Files> </Project> "@ } #endregion Import } } |