Skip to content

Commit 0b90a87

Browse files
Merge pull request #92 from PowershellFrameworkCollective/template-update
Updating templates
2 parents 6ff9fc9 + 7c8ec78 commit 0b90a87

File tree

14 files changed

+360
-25
lines changed

14 files changed

+360
-25
lines changed

PSModuleDevelopment/PSModuleDevelopment.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
RootModule = 'PSModuleDevelopment.psm1'
55

66
# Version number of this module.
7-
ModuleVersion = '2.2.6.51'
7+
ModuleVersion = '2.2.6.62'
88

99
# ID used to uniquely identify this module
1010
GUID = '37dd5fce-e7b5-4d57-ac37-832055ce49d6'

PSModuleDevelopment/PSModuleDevelopment.psm1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
$script:PSModuleRoot = $PSScriptRoot
2-
$script:PSModuleVersion = "2.2.6.51"
2+
$script:PSModuleVersion = (Import-PowerShellDataFile -Path "$($script:PSModuleRoot)\PSModuleDevelopment.psd1").ModuleVersion
33

44
$script:doDotSource = $false
55
if (Get-PSFConfigValue -FullName PSModuleDevelopment.Import.DoDotSource) { $script:doDotSource = $true }

PSModuleDevelopment/changelog.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
# Changelog
22
##
3-
- Mew: Get-PSMDArgumentCompleter - lists registered argument completers on PS5+
3+
- New: Get-PSMDArgumentCompleter - Lists registered argument completers on PS5+
4+
- New: Template: PSFLoggingProvider - Creates a custom logfile logging provider for module specific logging.
5+
- Upd: Template: PSFTest - Adding test against module tags with whitespace
6+
- Upd: Get-PSMDConstructor - Added `-NonPublic` parameter to show hidden constructors.
7+
- Upd: Template: PSFModule - Improved import speed.
8+
- Upd: Template: PSFProject - Add parameter `-LocalRepo`
9+
- Upd: Template: PSFProject - Add parameter `-AutoVersion`
10+
- Fix: New-PSMDModuleNugetPackage - Resolving input path.
11+
- Fix: New-PSMDModuleNugetPackage - Reregistering temp export repository if accidentally not cleaned up.
12+
- Fix: Template: PSFModule - Fixed format xml closing tag
13+
- Fix: Template: PSFModule - Fixed import from network share.
414

515
## 2.2.6.51 (January 29th, 2019)
616
- New: Format-PSMDParameter - updates legacy parameter notation

PSModuleDevelopment/functions/assembly/Get-PSMDConstructor.ps1

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
1616
.PARAMETER InputObject
1717
The object the constructor of which should be retrieved.
18+
19+
.PARAMETER NonPublic
20+
Show non-public constructors instead.
1821
1922
.EXAMPLE
2023
Get-ChildItem | Get-PSMDConstructor
@@ -30,7 +33,10 @@
3033
[CmdletBinding()]
3134
Param (
3235
[Parameter(ValueFromPipeline = $true)]
33-
$InputObject
36+
$InputObject,
37+
38+
[switch]
39+
$NonPublic
3440
)
3541

3642
begin
@@ -47,16 +53,22 @@
4753

4854
if ($processedTypes -contains $type) { continue }
4955

50-
foreach ($constructor in $type.GetConstructors())
56+
if ($NonPublic)
57+
{
58+
foreach ($constructor in $type.GetConstructors([System.Reflection.BindingFlags]'NonPublic, Instance'))
59+
{
60+
New-Object PSModuleDevelopment.PsmdAssembly.Constructor($constructor)
61+
}
62+
}
63+
else
5164
{
52-
New-Object PSModuleDevelopment.PsmdAssembly.Constructor($constructor)
65+
foreach ($constructor in $type.GetConstructors())
66+
{
67+
New-Object PSModuleDevelopment.PsmdAssembly.Constructor($constructor)
68+
}
5369
}
5470

5571
$processedTypes += $type
5672
}
5773
}
58-
end
59-
{
60-
61-
}
6274
}

PSModuleDevelopment/functions/utility/Get-PSMDArgumentCompleter.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function Get-PSMDArgumentCompleter
1+
function Get-PSMDArgumentCompleter
22
{
33
<#
44
.SYNOPSIS

PSModuleDevelopment/functions/utility/New-PSMDModuleNugetPackage.ps1

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,20 @@
8181
return
8282
}
8383
}
84+
$resolvedPath = (Get-Item -Path $PackagePath).FullName
8485
#endregion Input validation and prerequisites check
8586

8687
#region Prepare local Repository
8788
try
8889
{
90+
if (Get-PSRepository | Where-Object Name -EQ 'PSModuleDevelopment_TempLocalRepository')
91+
{
92+
Unregister-PSRepository -Name 'PSModuleDevelopment_TempLocalRepository'
93+
}
8994
$paramRegisterPSRepository = @{
9095
Name = 'PSModuleDevelopment_TempLocalRepository'
91-
PublishLocation = $PackagePath
92-
SourceLocation = $PackagePath
96+
PublishLocation = $resolvedPath
97+
SourceLocation = $resolvedPath
9398
InstallationPolicy = 'Trusted'
9499
ErrorAction = 'Stop'
95100
}

PSModuleDevelopment/tests/general/manifest.Tests.ps1

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
Describe "Validating the module manifest" {
22
$moduleRoot = (Resolve-Path "$PSScriptRoot\..\..").Path
33
$manifest = ((Get-Content "$moduleRoot\PSModuleDevelopment.psd1") -join "`n") | Invoke-Expression
4-
[version]$moduleVersion = Get-Item "$moduleRoot\PSModuleDevelopment.psm1" | Select-String -Pattern '\$script:PSModuleVersion = "(.*?)"' | ForEach-Object { $_.Matches[0].Groups[1].Value }
54
Context "Basic resources validation" {
65
It "Exports all functions in the public folder" {
76
$files = Get-ChildItem "$moduleRoot\functions" -Recurse -File -Filter "*.ps1"
@@ -13,10 +12,6 @@ Describe "Validating the module manifest" {
1312
$files = Get-ChildItem "$moduleRoot\internal\functions" -Recurse -File -Filter "*.ps1"
1413
$files | Where-Object BaseName -In $manifest.FunctionsToExport | Should Be $null
1514
}
16-
17-
It "Has the same version as the psm1 file" {
18-
([version]$manifest.ModuleVersion) | Should Be $moduleVersion
19-
}
2015
}
2116

2217
Context "Individual file validation" {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
param (
2+
$Path
3+
)
4+
5+
New-PSMDTemplate -FilePath "$PSScriptRoot\þnameþ.provider.ps1" -TemplateName 'PSFLoggingProvider' -OutPath $Path -Description "A Custom Logfile Provider" -Author "Friedrich Weinmann" -Tags 'logging', 'provider', 'file'
Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
# Action that is performed on registration of the provider using Register-PSFLoggingProvider
2+
$registrationEvent = {
3+
4+
}
5+
6+
#region Logging Execution
7+
# Action that is performed when starting the logging script (or the very first time if enabled after launching the logging script)
8+
$begin_event = {
9+
function Get-þnameþPath
10+
{
11+
[CmdletBinding()]
12+
param (
13+
14+
)
15+
16+
$path = Get-PSFConfigValue -FullName 'þmoduleþ.Logging.þnameþ.FilePath'
17+
$logname = Get-PSFConfigValue -FullName 'þmoduleþ.Logging.þnameþ.LogName'
18+
19+
$scriptBlock = {
20+
param (
21+
[string]
22+
$Match
23+
)
24+
25+
$hash = @{
26+
'%date%' = (Get-Date -Format 'yyyy-MM-dd')
27+
'%dayofweek%' = (Get-Date).DayOfWeek
28+
'%day%' = (Get-Date).Day
29+
'%hour%' = (Get-Date).Hour
30+
'%minute%' = (Get-Date).Minute
31+
'%username%' = $env:USERNAME
32+
'%userdomain%' = $env:USERDOMAIN
33+
'%computername%' = $env:COMPUTERNAME
34+
'%processid%' = $PID
35+
'%logname%' = $logname
36+
}
37+
38+
$hash.$Match
39+
}
40+
41+
[regex]::Replace($path, '%day%|%computername%|%hour%|%processid%|%date%|%username%|%dayofweek%|%minute%|%userdomain%|%logname%', $scriptBlock)
42+
}
43+
44+
function Write-þnameþMessage
45+
{
46+
[CmdletBinding()]
47+
param (
48+
[Parameter(ValueFromPipeline = $true)]
49+
$Message,
50+
51+
[bool]
52+
$IncludeHeader,
53+
54+
[string]
55+
$FileType,
56+
57+
[string]
58+
$Path,
59+
60+
[string]
61+
$CsvDelimiter,
62+
63+
[string[]]
64+
$Headers
65+
)
66+
67+
$parent = Split-Path $Path
68+
if (-not (Test-Path $parent))
69+
{
70+
$null = New-Item $parent -ItemType Directory -Force
71+
}
72+
$fileExists = Test-Path $Path
73+
74+
#region Type-Based Output
75+
switch ($FileType)
76+
{
77+
#region Csv
78+
"Csv"
79+
{
80+
if ((-not $fileExists) -and $IncludeHeader) { $Message | ConvertTo-Csv -NoTypeInformation -Delimiter $CsvDelimiter | Set-Content -Path $Path -Encoding UTF8 }
81+
else { $Message | ConvertTo-Csv -NoTypeInformation -Delimiter $CsvDelimiter | Select-Object -Skip 1 | Add-Content -Path $Path -Encoding UTF8 }
82+
}
83+
#endregion Csv
84+
#region Json
85+
"Json"
86+
{
87+
if ($fileExists) { Add-Content -Path $Path -Value "," -Encoding UTF8 }
88+
$Message | ConvertTo-Json | Add-Content -Path $Path -NoNewline -Encoding UTF8
89+
}
90+
#endregion Json
91+
#region XML
92+
"XML"
93+
{
94+
[xml]$xml = $message | ConvertTo-Xml -NoTypeInformation
95+
$xml.Objects.InnerXml | Add-Content -Path $Path -Encoding UTF8
96+
}
97+
#endregion XML
98+
#region Html
99+
"Html"
100+
{
101+
[xml]$xml = $message | ConvertTo-Html -Fragment
102+
103+
if ((-not $fileExists) -and $IncludeHeader)
104+
{
105+
$xml.table.tr[0].OuterXml | Add-Content -Path $Path -Encoding UTF8
106+
}
107+
108+
$xml.table.tr[1].OuterXml | Add-Content -Path $Path -Encoding UTF8
109+
}
110+
#endregion Html
111+
}
112+
#endregion Type-Based Output
113+
}
114+
115+
$þnameþ_includeheader = Get-PSFConfigValue -FullName 'þmoduleþ.Logging.þnameþ.IncludeHeader'
116+
$þnameþ_headers = Get-PSFConfigValue -FullName 'þmoduleþ.Logging.þnameþ.Headers'
117+
$þnameþ_filetype = Get-PSFConfigValue -FullName 'þmoduleþ.Logging.þnameþ.FileType'
118+
$þnameþ_CsvDelimiter = Get-PSFConfigValue -FullName 'þmoduleþ.Logging.þnameþ.CsvDelimiter'
119+
120+
if ($þnameþ_headers -contains 'Tags')
121+
{
122+
$þnameþ_headers = $þnameþ_headers | ForEach-Object {
123+
switch ($_)
124+
{
125+
'Tags'
126+
{
127+
@{
128+
Name = 'Tags'
129+
Expression = { $_.Tags -join "," }
130+
}
131+
}
132+
'Message'
133+
{
134+
@{
135+
Name = 'Message'
136+
Expression = { $_.LogMessage }
137+
}
138+
}
139+
default { $_ }
140+
}
141+
}
142+
}
143+
144+
$þnameþ_paramWriteLogFileMessage = @{
145+
IncludeHeader = $þnameþ_includeheader
146+
FileType = $þnameþ_filetype
147+
CsvDelimiter = $þnameþ_CsvDelimiter
148+
Headers = $þnameþ_headers
149+
}
150+
}
151+
152+
# Action that is performed at the beginning of each logging cycle
153+
$start_event = {
154+
$þnameþ_paramWriteLogFileMessage["Path"] = Get-þnameþPath
155+
}
156+
157+
# Action that is performed for each message item that is being logged
158+
$message_Event = {
159+
Param (
160+
$Message
161+
)
162+
163+
$Message | Select-Object $þnameþ_headers | Write-þnameþMessage @þnameþ_paramWriteLogFileMessage
164+
}
165+
166+
# Action that is performed for each error item that is being logged
167+
$error_Event = {
168+
Param (
169+
$ErrorItem
170+
)
171+
172+
173+
}
174+
175+
# Action that is performed at the end of each logging cycle
176+
$end_event = {
177+
178+
}
179+
180+
# Action that is performed when stopping the logging script
181+
$final_event = {
182+
183+
}
184+
#endregion Logging Execution
185+
186+
#region Function Extension / Integration
187+
# Script that generates the necessary dynamic parameter for Set-PSFLoggingProvider
188+
$configurationParameters = {
189+
$configroot = "þmoduleþ.Logging.þnameþ"
190+
191+
$configurations = Get-PSFConfig -FullName "$configroot.*"
192+
193+
$RuntimeParamDic = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
194+
195+
foreach ($config in $configurations)
196+
{
197+
$ParamAttrib = New-Object System.Management.Automation.ParameterAttribute
198+
$ParamAttrib.ParameterSetName = '__AllParameterSets'
199+
$AttribColl = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
200+
$AttribColl.Add($ParamAttrib)
201+
$RuntimeParam = New-Object System.Management.Automation.RuntimeDefinedParameter(($config.FullName.Replace($configroot, "").Trim(".")), $config.Value.GetType(), $AttribColl)
202+
203+
$RuntimeParamDic.Add(($config.FullName.Replace($configroot, "").Trim(".")), $RuntimeParam)
204+
}
205+
return $RuntimeParamDic
206+
}
207+
208+
# Script that is executes when configuring the provider using Set-PSFLoggingProvider
209+
$configurationScript = {
210+
$configroot = "þmoduleþ.Logging.þnameþ"
211+
212+
$configurations = Get-PSFConfig -FullName "$configroot.*"
213+
214+
foreach ($config in $configurations)
215+
{
216+
if ($PSBoundParameters.ContainsKey(($config.FullName.Replace($configroot, "").Trim("."))))
217+
{
218+
Set-PSFConfig -Module $config.Module -Name $config.Name -Value $PSBoundParameters[($config.FullName.Replace($configroot, "").Trim("."))]
219+
}
220+
}
221+
}
222+
223+
# Script that returns a boolean value. "True" if all prerequisites are installed, "False" if installation is required
224+
$isInstalledScript = {
225+
return $true
226+
}
227+
228+
# Script that provides dynamic parameter for Install-PSFLoggingProvider
229+
$installationParameters = {
230+
# None needed
231+
}
232+
233+
# Script that performs the actual installation, based on the parameters (if any) specified in the $installationParameters script
234+
$installationScript = {
235+
# Nothing to be done - if you need to install your filesystem, you probably have other issues you need to deal with first ;)
236+
}
237+
#endregion Function Extension / Integration
238+
239+
# Configuration settings to initialize
240+
$configuration_Settings = {
241+
Set-PSFConfig -Module þmoduleþ -Name 'Logging.þnameþ.FilePath' -Value "" -Initialize -Validation string -Handler { } -Description "The path to where the logfile is written. Supports some placeholders such as %Date% to allow for timestamp in the name. For full documentation on the supported wildcards, see the documentation on https://psframework.org"
242+
Set-PSFConfig -Module þmoduleþ -Name 'Logging.þnameþ.Logname' -Value "" -Initialize -Validation string -Handler { } -Description "A special string you can use as a placeholder in the logfile path (by using '%logname%' as placeholder)"
243+
Set-PSFConfig -Module þmoduleþ -Name 'Logging.þnameþ.IncludeHeader' -Value $true -Initialize -Validation bool -Handler { } -Description "Whether a written csv file will include headers"
244+
Set-PSFConfig -Module þmoduleþ -Name 'Logging.þnameþ.Headers' -Value @('ComputerName', 'File', 'FunctionName', 'Level', 'Line', 'Message', 'ModuleName', 'Runspace', 'Tags', 'TargetObject', 'Timestamp', 'Type', 'Username') -Initialize -Validation stringarray -Handler { } -Description "The properties to export, in the order to select them."
245+
Set-PSFConfig -Module þmoduleþ -Name 'Logging.þnameþ.FileType' -Value "CSV" -Initialize -Validation psframework.logfilefiletype -Handler { } -Description "In what format to write the logfile. Supported styles: CSV, XML, Html or Json. Html, XML and Json will be written as fragments."
246+
Set-PSFConfig -Module þmoduleþ -Name 'Logging.þnameþ.CsvDelimiter' -Value "," -Initialize -Validation string -Handler { } -Description "The delimiter to use when writing to csv."
247+
248+
Set-PSFConfig -Module LoggingProvider -Name 'þnameþ.Enabled' -Value $false -Initialize -Validation "bool" -Handler { if ([PSFramework.Logging.ProviderHost]::Providers['þnameþ']) { [PSFramework.Logging.ProviderHost]::Providers['þnameþ'].Enabled = $args[0] } } -Description "Whether the logging provider should be enabled on registration"
249+
Set-PSFConfig -Module LoggingProvider -Name 'þnameþ.AutoInstall' -Value $false -Initialize -Validation "bool" -Handler { } -Description "Whether the logging provider should be installed on registration"
250+
Set-PSFConfig -Module LoggingProvider -Name 'þnameþ.InstallOptional' -Value $true -Initialize -Validation "bool" -Handler { } -Description "Whether installing the logging provider is mandatory, in order for it to be enabled"
251+
Set-PSFConfig -Module LoggingProvider -Name 'þnameþ.IncludeModules' -Value @() -Initialize -Validation "stringarray" -Handler { if ([PSFramework.Logging.ProviderHost]::Providers['þnameþ']) { [PSFramework.Logging.ProviderHost]::Providers['þnameþ'].IncludeModules = ($args[0] | Write-Output) } } -Description "Module whitelist. Only messages from listed modules will be logged"
252+
Set-PSFConfig -Module LoggingProvider -Name 'þnameþ.ExcludeModules' -Value @() -Initialize -Validation "stringarray" -Handler { if ([PSFramework.Logging.ProviderHost]::Providers['þnameþ']) { [PSFramework.Logging.ProviderHost]::Providers['þnameþ'].ExcludeModules = ($args[0] | Write-Output) } } -Description "Module blacklist. Messages from listed modules will not be logged"
253+
Set-PSFConfig -Module LoggingProvider -Name 'þnameþ.IncludeTags' -Value @() -Initialize -Validation "stringarray" -Handler { if ([PSFramework.Logging.ProviderHost]::Providers['þnameþ']) { [PSFramework.Logging.ProviderHost]::Providers['þnameþ'].IncludeTags = ($args[0] | Write-Output) } } -Description "Tag whitelist. Only messages with these tags will be logged"
254+
Set-PSFConfig -Module LoggingProvider -Name 'þnameþ.ExcludeTags' -Value @() -Initialize -Validation "stringarray" -Handler { if ([PSFramework.Logging.ProviderHost]::Providers['þnameþ']) { [PSFramework.Logging.ProviderHost]::Providers['þnameþ'].ExcludeTags = ($args[0] | Write-Output) } } -Description "Tag blacklist. Messages with these tags will not be logged"
255+
}
256+
257+
Register-PSFLoggingProvider -Name "þnameþ" -RegistrationEvent $registrationEvent -BeginEvent $begin_event -StartEvent $start_event -MessageEvent $message_Event -ErrorEvent $error_Event -EndEvent $end_event -FinalEvent $final_event -ConfigurationParameters $configurationParameters -ConfigurationScript $configurationScript -IsInstalledScript $isInstalledScript -InstallationScript $installationScript -InstallationParameters $installationParameters -ConfigurationSettings $configuration_Settings

0 commit comments

Comments
 (0)