diff --git a/PSModuleDevelopment/PSModuleDevelopment.psd1 b/PSModuleDevelopment/PSModuleDevelopment.psd1
index 1e440c0..083f7e4 100644
--- a/PSModuleDevelopment/PSModuleDevelopment.psd1
+++ b/PSModuleDevelopment/PSModuleDevelopment.psd1
@@ -5,7 +5,7 @@
# Version number of this module.
- ModuleVersion = '2.2.12.171'
+ ModuleVersion = '2.2.12.172'
# ID used to uniquely identify this module
GUID = '37dd5fce-e7b5-4d57-ac37-832055ce49d6'
@@ -29,7 +29,7 @@
# this module
RequiredModules = @(
@{ ModuleName = 'PSFramework'; ModuleVersion = '1.12.346' }
- @{ ModuleName = 'string'; ModuleVersion = '1.1.3' }
+ @{ ModuleName = 'string'; ModuleVersion = '1.1.5' }
)
# Assemblies that must be loaded prior to importing this module
diff --git a/PSModuleDevelopment/bin/PSModuleDevelopment.dll b/PSModuleDevelopment/bin/PSModuleDevelopment.dll
index 7b367b5..85c4f32 100644
Binary files a/PSModuleDevelopment/bin/PSModuleDevelopment.dll and b/PSModuleDevelopment/bin/PSModuleDevelopment.dll differ
diff --git a/PSModuleDevelopment/bin/PSModuleDevelopment.pdb b/PSModuleDevelopment/bin/PSModuleDevelopment.pdb
index 405490d..fd83f8b 100644
Binary files a/PSModuleDevelopment/bin/PSModuleDevelopment.pdb and b/PSModuleDevelopment/bin/PSModuleDevelopment.pdb differ
diff --git a/PSModuleDevelopment/bin/PSModuleDevelopment.xml b/PSModuleDevelopment/bin/PSModuleDevelopment.xml
index dd9f075..dca5b42 100644
--- a/PSModuleDevelopment/bin/PSModuleDevelopment.xml
+++ b/PSModuleDevelopment/bin/PSModuleDevelopment.xml
@@ -574,6 +574,13 @@
Static helpers for the template system
+
+
+ Convert a deserialized template item into a fully valid object of its type.
+
+ The PSObject to transform back into what it was meant to be
+ The resultant TemplateItemBase
+
Class containing meta information about a template
@@ -695,6 +702,18 @@
List of script value insertion parameters for the plaintext file
+
+
+ Creates an empty TemplateItemFile
+
+
+
+
+ Creates a filled-out TemplateItemFile.
+ Usually called when deserializing a template.
+
+ The deserialized instance of this template item file.
+
Describes a folder that is part of a template
@@ -860,7 +879,16 @@
The name of the property that has the value
The value
-
+
+
+ Get the Values!
+ Always as an arraylist, empty if null
+
+ The object to extend
+ >The name of the property that has the values
+ The values
+
+
Get a hashtable value!
diff --git a/PSModuleDevelopment/changelog.md b/PSModuleDevelopment/changelog.md
index 57a505d..0c53e6d 100644
--- a/PSModuleDevelopment/changelog.md
+++ b/PSModuleDevelopment/changelog.md
@@ -1,5 +1,9 @@
# Changelog
+## 2.2.12.172 (2024-10-06)
+
++ Fix: Invoke-PSMDTemplate - On WinPS, script-logic on templates is not executed
+
## 2.2.12.171 (2024-10-04)
+ Upd: Raised PSFramework dependency due to critical security update
diff --git a/PSModuleDevelopment/functions/templating/Get-PSMDTemplate.ps1 b/PSModuleDevelopment/functions/templating/Get-PSMDTemplate.ps1
index 00df036..96a0d77 100644
--- a/PSModuleDevelopment/functions/templating/Get-PSMDTemplate.ps1
+++ b/PSModuleDevelopment/functions/templating/Get-PSMDTemplate.ps1
@@ -91,12 +91,12 @@
#region Scan folders
if (Test-PSFParameterBinding -ParameterName "Path")
{
- $templateInfos = Get-ChildItem -Path $Path -Filter "$($TemplateName)-*.Info.xml" | Where-Object { ($_.Name -replace "-\d+(\.\d+){0,3}.Info.xml$") -like $TemplateName }
+ $templateInfos = Get-ChildItem -Path $Path -Filter "$($TemplateName)-*-Info.xml" | Where-Object { ($_.Name -replace "-\d+(\.\d+){0,3}-Info.xml$") -like $TemplateName }
foreach ($info in $templateInfos)
{
$data = Import-PSFClixml $info.FullName
- $data.Path = $info.FullName -replace '\.Info\.xml$','.xml'
+ $data.Path = $info.FullName -replace '-Info\.xml$','.xml'
$prospects += $data
}
}
diff --git a/PSModuleDevelopment/functions/templating/Invoke-PSMDTemplate.ps1 b/PSModuleDevelopment/functions/templating/Invoke-PSMDTemplate.ps1
index 639a7cd..fbb82cc 100644
--- a/PSModuleDevelopment/functions/templating/Invoke-PSMDTemplate.ps1
+++ b/PSModuleDevelopment/functions/templating/Invoke-PSMDTemplate.ps1
@@ -317,7 +317,9 @@
[OutputType([PSModuleDevelopment.Template.TemplateResult])]
[CmdletBinding()]
param (
- [PSModuleDevelopment.Template.TemplateItemBase]
+ # Fixing that in the next PSFramework release: https://github.com/PowershellFrameworkCollective/psframework/issues/646
+ #[PSFramework.Utility.ScriptTransformation('PSModuleDevelopment.TemplateItem', [PSModuleDevelopment.Template.TemplateItemBase])]
+ #[PSModuleDevelopment.Template.TemplateItemBase]
$Item,
[string]
diff --git a/PSModuleDevelopment/internal/scripts/initialize.ps1 b/PSModuleDevelopment/internal/scripts/initialize.ps1
index 865cf43..08f0b27 100644
--- a/PSModuleDevelopment/internal/scripts/initialize.ps1
+++ b/PSModuleDevelopment/internal/scripts/initialize.ps1
@@ -10,4 +10,10 @@ if (-not (Test-Path (Get-PSFConfigValue -FullName 'PSModuleDevelopment.Debug.Con
#endregion Ensure Config path exists
# Pass on the host UI to the library
-[PSModuleDevelopment.Utility.UtilityHost]::RawUI = $host.UI.RawUI
\ No newline at end of file
+[PSModuleDevelopment.Utility.UtilityHost]::RawUI = $host.UI.RawUI
+
+# Register Type-Conversion to fix template issues in serialization edge-casaes
+Register-PSFArgumentTransformationScriptblock -Name 'PSModuleDevelopment.TemplateItem' -Scriptblock {
+ if ($_ -is [PSModuleDevelopment.Template.TemplateItemBase]) { return $_ }
+ [PSModuleDevelopment.Template.TemplateHost]::GetTemplateItem($_)
+}
\ No newline at end of file
diff --git a/PSModuleDevelopment/tests/functions/Templates.Tests.ps1 b/PSModuleDevelopment/tests/functions/Templates.Tests.ps1
new file mode 100644
index 0000000..3e38b57
--- /dev/null
+++ b/PSModuleDevelopment/tests/functions/Templates.Tests.ps1
@@ -0,0 +1,40 @@
+Describe "Verifying templating component" {
+ BeforeAll {
+ $outPath = (Get-Item -Path 'TestDrive:\').FullName
+ $resourcePath = Resolve-PSFPath -Path "$PSScriptRoot\..\resources"
+ $templateName = 'TestTemplate-{0}' -f (Get-Random)
+ }
+
+ It "Should Record the template correctly" {
+ { New-PSMDTemplate -TemplateName $templateName -FilePath "$resourcePath\þnameþ.txt" -OutPath $outPath -EnableException -ErrorAction Stop } | Should -Not -Throw
+ $templateInfo = Get-PSMDTemplate -TemplateName $templateName -Path $outPath
+ $templateRaw = Import-PSFClixml -Path $templateInfo.Path
+ try { $template = [PSModuleDevelopment.Template.Template]$templateRaw }
+ catch {
+ Write-Warning "Conversion to template Failed!"
+ Write-Warning "======================================================================="
+ $_ | Format-List -Force | Out-Host
+ Write-Warning "======================================================================="
+ $_.Exception | Format-List -Force | Out-Host
+ Write-Warning "======================================================================="
+ throw
+ }
+ $template.Name | Should -Be $templateName
+ $template.Parameters.Count | Should -Be 1
+ $template.Scripts.Count | Should -Be 1
+ $template.Scripts.Values.ScriptBlock | Should -BeOfType ([scriptblock])
+ }
+
+ It "Should Invoke the template correctly" {
+ { Invoke-PSMDTemplate -TemplateName $templateName -Path $outPath -OutPath $outPath -Name Test -EnableException } | Should -Not -Throw
+ $content = Get-Content -Path "TestDrive:\Test.txt" -ErrorAction Stop
+ $values = $content | ConvertFrom-StringData -ErrorAction Stop
+ $values.Name | Should -Be Test
+ $values.Value | Should -Be '123'
+ }
+
+ It "Should Remove the template correctly" {
+ { Remove-PSMDTemplate -TemplateName $templateName -EnableException -Confirm:$false } | Should -Not -Throw
+ Get-PSMDTemplate -TemplateName $templateName | Should -BeNullOrEmpty
+ }
+}
\ No newline at end of file
diff --git "a/PSModuleDevelopment/tests/resources/\303\276name\303\276.txt" "b/PSModuleDevelopment/tests/resources/\303\276name\303\276.txt"
new file mode 100644
index 0000000..faaf9b3
--- /dev/null
+++ "b/PSModuleDevelopment/tests/resources/\303\276name\303\276.txt"
@@ -0,0 +1,2 @@
+Name = þnameþ
+Value = þ{ "123" }þ
\ No newline at end of file
diff --git a/PSModuleDevelopment/xml/PSModuleDevelopment.Types.ps1xml b/PSModuleDevelopment/xml/PSModuleDevelopment.Types.ps1xml
index fc2ef4a..01ae5a4 100644
--- a/PSModuleDevelopment/xml/PSModuleDevelopment.Types.ps1xml
+++ b/PSModuleDevelopment/xml/PSModuleDevelopment.Types.ps1xml
@@ -1,7 +1,7 @@
-
+
diff --git a/library/PSModuleDevelopment/PSModuleDevelopment/Template/Template.cs b/library/PSModuleDevelopment/PSModuleDevelopment/Template/Template.cs
index 494c2eb..def8553 100644
--- a/library/PSModuleDevelopment/PSModuleDevelopment/Template/Template.cs
+++ b/library/PSModuleDevelopment/PSModuleDevelopment/Template/Template.cs
@@ -122,14 +122,14 @@ public Template(PSObject Item)
Description = Item.GetValue("Description");
Author = Item.GetValue("Author");
CreatedOn = Item.GetValue("CreatedOn");
- foreach (object item in Item.GetValue("Tags"))
+ foreach (object item in Item.GetValues("Tags"))
Tags.Add((string)item);
- foreach (object item in Item.GetValue("Parameters"))
+ foreach (object item in Item.GetValues("Parameters"))
Parameters.Add((string)item);
- foreach (KeyValuePair entry in Item.GetDictionary("Scripts"))
+ foreach (KeyValuePair entry in Item.GetParameterScriptDictionary("Scripts"))
Scripts[entry.Key] =entry.Value;
// Parameters2 not used
- foreach (object item in Item.GetValue("Children"))
+ foreach (object item in Item.GetValues("Children"))
Children.Add(TemplateHost.GetTemplateItem(item));
Generation = Item.GetValue("Generation");
diff --git a/library/PSModuleDevelopment/PSModuleDevelopment/Template/TemplateHost.cs b/library/PSModuleDevelopment/PSModuleDevelopment/Template/TemplateHost.cs
index 3ed53af..21b6173 100644
--- a/library/PSModuleDevelopment/PSModuleDevelopment/Template/TemplateHost.cs
+++ b/library/PSModuleDevelopment/PSModuleDevelopment/Template/TemplateHost.cs
@@ -12,25 +12,33 @@ namespace PSModuleDevelopment.Template
///
/// Static helpers for the template system
///
- internal static class TemplateHost
+ public static class TemplateHost
{
- internal static TemplateItemBase GetTemplateItem(object Item)
+ ///
+ /// Convert a deserialized template item into a fully valid object of its type.
+ ///
+ /// The PSObject to transform back into what it was meant to be
+ /// The resultant TemplateItemBase
+ public static TemplateItemBase GetTemplateItem(object Item)
{
if (Item.GetType() == typeof(TemplateItemFile))
return (TemplateItemFile)Item;
- TemplateItemFolder result = new TemplateItemFolder(); ;
PSObject PSItem = PSObject.AsPSObject(Item);
+ if (PSItem.TypeNames.Contains("Deserialized.PSModuleDevelopment.Template.TemplateItemFile"))
+ return new TemplateItemFile(PSItem);
- foreach (object child in PSItem.GetValue("Children"))
+ TemplateItemFolder result = new TemplateItemFolder();
+
+ foreach (object child in PSItem.GetValues("Children"))
result.Children.Add(GetTemplateItem(child));
result.Name = PSItem.GetValue("Name");
result.RelativePath = PSItem.GetValue("RelativePath");
result.Identifier = PSItem.GetValue("Identifier");
- foreach (string entry in PSItem.GetValue("FileSystemParameterFlat"))
+ foreach (string entry in PSItem.GetValues("FileSystemParameterFlat"))
result.FileSystemParameterFlat.Add(entry);
- foreach (string entry in PSItem.GetValue("FileSystemParameterScript"))
+ foreach (string entry in PSItem.GetValues("FileSystemParameterScript"))
result.FileSystemParameterScript.Add(entry);
return result;
diff --git a/library/PSModuleDevelopment/PSModuleDevelopment/Template/TemplateItemFile.cs b/library/PSModuleDevelopment/PSModuleDevelopment/Template/TemplateItemFile.cs
index e936a5b..f1a8e75 100644
--- a/library/PSModuleDevelopment/PSModuleDevelopment/Template/TemplateItemFile.cs
+++ b/library/PSModuleDevelopment/PSModuleDevelopment/Template/TemplateItemFile.cs
@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Management.Automation;
using System.Text;
using System.Threading.Tasks;
+using PSModuleDevelopment.Utility;
namespace PSModuleDevelopment.Template
{
@@ -31,5 +33,37 @@ public class TemplateItemFile : TemplateItemBase
/// List of script value insertion parameters for the plaintext file
///
public List ContentParameterScript = new List();
+
+ ///
+ /// Creates an empty TemplateItemFile
+ ///
+ public TemplateItemFile()
+ {
+
+ }
+
+ ///
+ /// Creates a filled-out TemplateItemFile.
+ /// Usually called when deserializing a template.
+ ///
+ /// The deserialized instance of this template item file.
+ public TemplateItemFile(PSObject PSItem)
+ {
+ Name = PSItem.GetValue("Name");
+ RelativePath = PSItem.GetValue("RelativePath");
+ Identifier = PSItem.GetValue("Identifier");
+ foreach (string entry in PSItem.GetValues("FileSystemParameterFlat"))
+ FileSystemParameterFlat.Add(entry);
+ foreach (string entry in PSItem.GetValues("FileSystemParameterScript"))
+ FileSystemParameterScript.Add(entry);
+
+ foreach (string entry in PSItem.GetValues("ContentParameterFlat"))
+ ContentParameterFlat.Add(entry);
+ foreach (string entry in PSItem.GetValues("ContentParameterScript"))
+ ContentParameterScript.Add(entry);
+
+ Value = PSItem.GetValue("Value");
+ PlainText = PSItem.GetValue("PlainText");
+ }
}
}
diff --git a/library/PSModuleDevelopment/PSModuleDevelopment/Utility/PSObjectExtension.cs b/library/PSModuleDevelopment/PSModuleDevelopment/Utility/PSObjectExtension.cs
index 8fb3235..00c5098 100644
--- a/library/PSModuleDevelopment/PSModuleDevelopment/Utility/PSObjectExtension.cs
+++ b/library/PSModuleDevelopment/PSModuleDevelopment/Utility/PSObjectExtension.cs
@@ -1,4 +1,5 @@
-using System;
+using PSModuleDevelopment.Template;
+using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
@@ -26,6 +27,23 @@ public static T GetValue(this PSObject PSObject, string Name)
return (T)value.BaseObject;
}
+ ///
+ /// Get the Values!
+ /// Always as an arraylist, empty if null
+ ///
+ /// The object to extend
+ /// >The name of the property that has the values
+ /// The values
+ public static ArrayList GetValues(this PSObject PSObject, string Name)
+ {
+ if (null == PSObject || null == PSObject.Properties || null == PSObject.Properties[Name] || null == PSObject.Properties[Name]?.Value)
+ return new ArrayList();
+ PSObject value = PSObject.AsPSObject(PSObject.Properties[Name].Value);
+ if (null == value.BaseObject)
+ return new ArrayList();
+ return (ArrayList)value.BaseObject;
+ }
+
///
/// Get a hashtable value!
///
@@ -33,12 +51,12 @@ public static T GetValue(this PSObject PSObject, string Name)
/// The object to extend
/// The name of the property that has the hashtable
/// The hashtable!
- public static Dictionary GetDictionary(this PSObject PSObject, string Name)
+ public static Dictionary GetParameterScriptDictionary(this PSObject PSObject, string Name)
{
Hashtable temp = PSObject.GetValue(Name);
- Dictionary result = new Dictionary();
+ Dictionary result = new Dictionary();
foreach (DictionaryEntry pair in temp)
- result[(string)pair.Key] = (T)pair.Value;
+ result[(string)pair.Key] = new ParameterScript((PSObject)pair.Value);
return result;
}