From fb6f54ceb459ced1a6d077c8ccdd7bcdc0d7ee7a Mon Sep 17 00:00:00 2001 From: Friedrich Weinmann Date: Fri, 4 Oct 2024 21:13:01 +0200 Subject: [PATCH 1/2] test-launcher --- dev/launch.ps1 | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 dev/launch.ps1 diff --git a/dev/launch.ps1 b/dev/launch.ps1 new file mode 100644 index 0000000..a356311 --- /dev/null +++ b/dev/launch.ps1 @@ -0,0 +1,89 @@ +[CmdletBinding()] +param ( + [switch] + $Local, + + [ValidateSet('Desktop', 'Core')] + [string] + $PSVersion +) + +#region Launch in new cponsole +if (-not $Local) { + $application = (Get-Process -id $PID).Path + if ($PSVersion -and $PSVersionTable.Edition -ne $PSVersion) { + $application = 'pwsh.exe' + if ($PSVersion -eq 'Desktop') { $application = 'powershell.exe'} + } + + Start-Process $application -ArgumentList @('-NoExit', '-NoProfile', '-File', "$PSScriptRoot\launch.ps1", '-Local') + return +} +#endregion Launch in new cponsole + +$ErrorActionPreference = 'Stop' +trap { + Write-Warning "Script failed: $_" + throw $_ +} + +#region Functions +function New-TemporaryPath { + [OutputType([string])] + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [string] + $Prefix + ) + + Write-Host "Creating new temporary path: $Prefix" + + # Remove Previous Temporary Paths + Remove-Item -Path "$env:Temp\$Prefix*" -Force -Recurse -ErrorAction SilentlyContinue + + # Create New Temporary Path + $item = New-Item -Path $env:TEMP -Name "$($Prefix)_$(Get-Random)" -ItemType Directory + $item.FullName +} + +function Build-Template { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [string] + $RootPath, + + [Parameter(Mandatory = $true)] + [string] + $ProjectPath + ) + + Write-Host "Building Templates from Source" + $buildScriptPath = Join-Path -Path $ProjectPath -ChildPath "templates\build.ps1" + & $buildScriptPath -Path $RootPath + + Set-PSFConfig -FullName 'PSModuleDevelopment.Template.Store.PSModuleDevelopment' -Value "$RootPath\output" +} + +function Import-PsmdModule { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [string] + $ProjectPath + ) + + Write-Host "Importing PSModuleDevelopment from source code" + Import-Module "$ProjectPath\PSModuleDevelopment\PSModuleDevelopment.psd1" -Global + + # Does not work during initial start + # [Microsoft.PowerShell.PSConsoleReadLine]::AddToHistory("ipmo '$ProjectPath\PSModuleDevelopment\PSModuleDevelopment.psd1'") +} +#endregion Functions + +$projectRoot = Resolve-Path -Path "$PSScriptRoot\.." +$templateRoot = New-TemporaryPath -Prefix PsmdTemplate +#Build-PsmdModule -ProjectPath $projectRoot +Import-PsmdModule -ProjectPath $projectRoot +Build-Template -RootPath $templateRoot -ProjectPath $projectRoot \ No newline at end of file From 1e85b98135f3fdc82bfa423334cac4a2d8113c54 Mon Sep 17 00:00:00 2001 From: FriedrichWeinmann Date: Fri, 4 Oct 2024 23:18:06 +0200 Subject: [PATCH 2/2] Template system update Serialization update for templating to match latest PSFramework version and remove dependency from typeconverter in general --- PSModuleDevelopment/PSModuleDevelopment.psd1 | 4 +- .../bin/PSModuleDevelopment.dll | Bin 22528 -> 25600 bytes .../bin/PSModuleDevelopment.pdb | Bin 83456 -> 89600 bytes .../bin/PSModuleDevelopment.xml | 46 ++++++++++++++++++ PSModuleDevelopment/changelog.md | 6 +++ .../functions/templating/New-PSMDTemplate.ps1 | 4 +- build/vsts-build-library.ps1 | 38 +++++++++++++++ dev/launch.ps1 | 26 +++++++++- .../PSModuleDevelopment.csproj.dtbcache.json | 1 + .../PSModuleDevelopment.csproj | 2 + .../Template/ParameterScript.cs | 10 ++++ .../PSModuleDevelopment/Template/Template.cs | 43 ++++++++++++++++ .../Template/TemplateHost.cs | 39 +++++++++++++++ .../Utility/PSObjectExtension.cs | 46 ++++++++++++++++++ 14 files changed, 259 insertions(+), 6 deletions(-) create mode 100644 build/vsts-build-library.ps1 create mode 100644 library/PSModuleDevelopment/PSModuleDevelopment/.vs/PSModuleDevelopment.csproj.dtbcache.json create mode 100644 library/PSModuleDevelopment/PSModuleDevelopment/Template/TemplateHost.cs create mode 100644 library/PSModuleDevelopment/PSModuleDevelopment/Utility/PSObjectExtension.cs diff --git a/PSModuleDevelopment/PSModuleDevelopment.psd1 b/PSModuleDevelopment/PSModuleDevelopment.psd1 index 8cfb0c9..1e440c0 100644 --- a/PSModuleDevelopment/PSModuleDevelopment.psd1 +++ b/PSModuleDevelopment/PSModuleDevelopment.psd1 @@ -5,7 +5,7 @@ # Version number of this module. - ModuleVersion = '2.2.11.168' + ModuleVersion = '2.2.12.171' # ID used to uniquely identify this module GUID = '37dd5fce-e7b5-4d57-ac37-832055ce49d6' @@ -28,7 +28,7 @@ # Modules that must be imported into the global environment prior to importing # this module RequiredModules = @( - @{ ModuleName = 'PSFramework'; ModuleVersion = '1.7.270' } + @{ ModuleName = 'PSFramework'; ModuleVersion = '1.12.346' } @{ ModuleName = 'string'; ModuleVersion = '1.1.3' } ) diff --git a/PSModuleDevelopment/bin/PSModuleDevelopment.dll b/PSModuleDevelopment/bin/PSModuleDevelopment.dll index 57ef0fa6c4959cae6e6bc81cfce0350b2f2135e5..7b367b5876f5376e7a22442342b4b68fbbf2fc65 100644 GIT binary patch literal 25600 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 literal 22528 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 cU~g;r25y%0AnKk@Cjeb`}Mv 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 diff --git a/PSModuleDevelopment/bin/PSModuleDevelopment.pdb b/PSModuleDevelopment/bin/PSModuleDevelopment.pdb index c0a219a5d048a77f499d57e62204f3277f574fc6..405490d1b588156b035355bfe871f2cc15a1949e 100644 GIT binary patch delta 18348 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 delta 14669 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 diff --git a/PSModuleDevelopment/bin/PSModuleDevelopment.xml b/PSModuleDevelopment/bin/PSModuleDevelopment.xml index 8fb47fb..dd9f075 100644 --- a/PSModuleDevelopment/bin/PSModuleDevelopment.xml +++ b/PSModuleDevelopment/bin/PSModuleDevelopment.xml @@ -449,6 +449,12 @@ The name of the parameter. This is used to insert it into individual files or file names. + + + Creates a prefilled parameter script. Usually used in fixing serialization the hard way. + + The deserialized ParameterScript item + Class containing information relating to where templates are stored @@ -551,6 +557,23 @@ A TemplateInfo object describing this template. + + + Create a blank template object + + + + + Create a template object based on a deserialized template object + + The deserialized tample object to restore + If anything at all is not as it should be. + + + + Static helpers for the template system + + Class containing meta information about a template @@ -823,6 +846,29 @@ The actual value found The original input object offered to the command. + + + Extends the PSObject with C# convenience + + + + + Get the value! + + The type of the value + The object to extend + The name of the property that has the value + The value + + + + Get a hashtable value! + + The type of the values in hashtable + The object to extend + The name of the property that has the hashtable + The hashtable! + What a text can be aligned to diff --git a/PSModuleDevelopment/changelog.md b/PSModuleDevelopment/changelog.md index f48423b..57a505d 100644 --- a/PSModuleDevelopment/changelog.md +++ b/PSModuleDevelopment/changelog.md @@ -1,5 +1,11 @@ # Changelog +## 2.2.12.171 (2024-10-04) + ++ Upd: Raised PSFramework dependency due to critical security update ++ Fix: Invoke-PSMDTemplate - fails on non-Windows ++ Fix: Invoke-PSMDTemplate - fails with latest PSFramework version + ## 2.2.11.168 (2024-05-31) + Upd: Template AzureFunction - added config option to override http Endpoint methods (#198) diff --git a/PSModuleDevelopment/functions/templating/New-PSMDTemplate.ps1 b/PSModuleDevelopment/functions/templating/New-PSMDTemplate.ps1 index 61d9133..2960b9c 100644 --- a/PSModuleDevelopment/functions/templating/New-PSMDTemplate.ps1 +++ b/PSModuleDevelopment/functions/templating/New-PSMDTemplate.ps1 @@ -552,7 +552,7 @@ $template.CreatedOn = (Get-Date).Date - $template | Export-Clixml -Path (Join-Path $exportFolder $fileName) - $template.ToTemplateInfo() | Export-Clixml -Path (Join-Path $exportFolder $infoFileName) + $template | Export-PSFClixml -Path (Join-Path $exportFolder $fileName) -Depth 99 + $template.ToTemplateInfo() | Export-PSFClixml -Path (Join-Path $exportFolder $infoFileName) } } \ No newline at end of file diff --git a/build/vsts-build-library.ps1 b/build/vsts-build-library.ps1 new file mode 100644 index 0000000..88ae099 --- /dev/null +++ b/build/vsts-build-library.ps1 @@ -0,0 +1,38 @@ +<# +.SYNOPSIS + Builds the PSFramework binary library from source. + +.DESCRIPTION + Builds the PSFramework binary library from source. + +.PARAMETER WorkingDirectory + Path where the project root is. + Defaults to the parent folder this file is in. + +.EXAMPLE + PS C:\> .\vsts-build-library.ps1 + + Builds the PSFramework binary library from source. +#> +[CmdletBinding()] +param ( + $WorkingDirectory +) + +#region Handle Working Directory Defaults +if (-not $WorkingDirectory) +{ + if ($env:RELEASE_PRIMARYARTIFACTSOURCEALIAS) + { + $WorkingDirectory = Join-Path -Path $env:SYSTEM_DEFAULTWORKINGDIRECTORY -ChildPath $env:RELEASE_PRIMARYARTIFACTSOURCEALIAS + } + else { $WorkingDirectory = $env:SYSTEM_DEFAULTWORKINGDIRECTORY } +} +if (-not $WorkingDirectory) { $WorkingDirectory = Split-Path $PSScriptRoot } +#endregion Handle Working Directory Defaults + +# Build Library +dotnet build "$WorkingDirectory\library\PSModuleDevelopment\PSModuleDevelopment.sln" +if ($LASTEXITCODE -ne 0) { + throw "Failed to build PSModuleDevelopment.dll!" +} \ No newline at end of file diff --git a/dev/launch.ps1 b/dev/launch.ps1 index a356311..121e286 100644 --- a/dev/launch.ps1 +++ b/dev/launch.ps1 @@ -3,6 +3,9 @@ param ( [switch] $Local, + [switch] + $Build, + [ValidateSet('Desktop', 'Core')] [string] $PSVersion @@ -16,7 +19,10 @@ if (-not $Local) { if ($PSVersion -eq 'Desktop') { $application = 'powershell.exe'} } - Start-Process $application -ArgumentList @('-NoExit', '-NoProfile', '-File', "$PSScriptRoot\launch.ps1", '-Local') + $arguments = @('-NoExit', '-NoProfile', '-File', "$PSScriptRoot\launch.ps1", '-Local') + if ($Build) { $arguments += '-Build' } + + Start-Process $application -ArgumentList $arguments return } #endregion Launch in new cponsole @@ -80,10 +86,26 @@ function Import-PsmdModule { # Does not work during initial start # [Microsoft.PowerShell.PSConsoleReadLine]::AddToHistory("ipmo '$ProjectPath\PSModuleDevelopment\PSModuleDevelopment.psd1'") } + +function Build-PsmdModule { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [string] + $ProjectPath + ) + + Write-Host "Building Library. This may require the .NET 4.8 Targeting Pack" + try { $null = & "$ProjectPath\build\vsts-build-library.ps1" } + catch { + Write-Host "Targeting pack Download Link: https://dotnet.microsoft.com/en-us/download/visual-studio-sdks?cid=getdotnetsdk" + throw + } +} #endregion Functions $projectRoot = Resolve-Path -Path "$PSScriptRoot\.." $templateRoot = New-TemporaryPath -Prefix PsmdTemplate -#Build-PsmdModule -ProjectPath $projectRoot +if ($Build) { Build-PsmdModule -ProjectPath $projectRoot } Import-PsmdModule -ProjectPath $projectRoot Build-Template -RootPath $templateRoot -ProjectPath $projectRoot \ No newline at end of file diff --git a/library/PSModuleDevelopment/PSModuleDevelopment/.vs/PSModuleDevelopment.csproj.dtbcache.json b/library/PSModuleDevelopment/PSModuleDevelopment/.vs/PSModuleDevelopment.csproj.dtbcache.json new file mode 100644 index 0000000..dd3098b --- /dev/null +++ b/library/PSModuleDevelopment/PSModuleDevelopment/.vs/PSModuleDevelopment.csproj.dtbcache.json @@ -0,0 +1 @@ +{"RootPath":"F:\\Code\\Github\\PSModuleDevelopment\\library\\PSModuleDevelopment\\PSModuleDevelopment","ProjectFileName":"PSModuleDevelopment.csproj","Configuration":"Debug|AnyCPU","FrameworkPath":"","Sources":[{"SourceFile":"Format\\Column.cs"},{"SourceFile":"Format\\Alignment.cs"},{"SourceFile":"Format\\ColumnTransformation.cs"},{"SourceFile":"Format\\Document.cs"},{"SourceFile":"Format\\TableDefinition.cs"},{"SourceFile":"Format\\ViewDefinitionBase.cs"},{"SourceFile":"Properties\\AssemblyInfo.cs"},{"SourceFile":"PsmdAssembly\\Constructor.cs"},{"SourceFile":"Template\\Parameter\\ParameterBase.cs"},{"SourceFile":"Template\\ParameterScript.cs"},{"SourceFile":"Template\\Parameter\\ParameterPrompt.cs"},{"SourceFile":"Template\\Parameter\\ParameterScript.cs"},{"SourceFile":"Template\\Parameter\\ScriptExecutionTime.cs"},{"SourceFile":"Template\\Store.cs"},{"SourceFile":"Template\\Template.cs"},{"SourceFile":"Template\\TemplateInfo.cs"},{"SourceFile":"Template\\TemplateItemBase.cs"},{"SourceFile":"Template\\TemplateItemFile.cs"},{"SourceFile":"Template\\TemplateItemFolder.cs"},{"SourceFile":"Template\\TemplateResult.cs"},{"SourceFile":"Template\\TemplateType.cs"},{"SourceFile":"Utility\\LinesOfCode.cs"},{"SourceFile":"Utility\\PropertySearchResult.cs"},{"SourceFile":"Utility\\TextAlignment.cs"},{"SourceFile":"Utility\\TextHeader.cs"},{"SourceFile":"Utility\\UtilityHost.cs"},{"SourceFile":"obj\\Debug\\.NETFramework,Version=v4.8.AssemblyAttributes.cs"}],"References":[{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\Microsoft.CSharp.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\mscorlib.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"F:\\Code\\Github\\psframework\\PSFramework\\bin\\PSFramework.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Core.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Data.DataSetExtensions.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Data.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Windows\\Microsoft.NET\\assembly\\GAC_MSIL\\System.Management.Automation\\v4.0_3.0.0.0__31bf3856ad364e35\\System.Management.Automation.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Net.Http.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Xml.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Xml.Linq.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""}],"Analyzers":[],"Outputs":[{"OutputItemFullPath":"F:\\Code\\Github\\PSModuleDevelopment\\PSModuleDevelopment\\bin\\PSModuleDevelopment.dll","OutputItemRelativePath":"PSModuleDevelopment.dll"},{"OutputItemFullPath":"","OutputItemRelativePath":""}],"CopyToOutputEntries":[]} \ No newline at end of file diff --git a/library/PSModuleDevelopment/PSModuleDevelopment/PSModuleDevelopment.csproj b/library/PSModuleDevelopment/PSModuleDevelopment/PSModuleDevelopment.csproj index b1fa450..d24e403 100644 --- a/library/PSModuleDevelopment/PSModuleDevelopment/PSModuleDevelopment.csproj +++ b/library/PSModuleDevelopment/PSModuleDevelopment/PSModuleDevelopment.csproj @@ -66,6 +66,7 @@ + @@ -74,6 +75,7 @@ + diff --git a/library/PSModuleDevelopment/PSModuleDevelopment/Template/ParameterScript.cs b/library/PSModuleDevelopment/PSModuleDevelopment/Template/ParameterScript.cs index 1e0b020..d34c24f 100644 --- a/library/PSModuleDevelopment/PSModuleDevelopment/Template/ParameterScript.cs +++ b/library/PSModuleDevelopment/PSModuleDevelopment/Template/ParameterScript.cs @@ -50,5 +50,15 @@ public ParameterScript(string Name, ScriptBlock ScriptBlock) this.Name = Name; this.ScriptBlock = ScriptBlock; } + + /// + /// Creates a prefilled parameter script. Usually used in fixing serialization the hard way. + /// + /// The deserialized ParameterScript item + public ParameterScript(PSObject Item) + { + Name = (string)Item.Properties["Name"].Value; + ScriptBlock = ScriptBlock.Create((string)Item.Properties["ScriptBlock"].Value); + } } } diff --git a/library/PSModuleDevelopment/PSModuleDevelopment/Template/Template.cs b/library/PSModuleDevelopment/PSModuleDevelopment/Template/Template.cs index 0fa0d85..494c2eb 100644 --- a/library/PSModuleDevelopment/PSModuleDevelopment/Template/Template.cs +++ b/library/PSModuleDevelopment/PSModuleDevelopment/Template/Template.cs @@ -2,8 +2,10 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Management.Automation; using System.Text; using System.Threading.Tasks; +using PSModuleDevelopment.Utility; namespace PSModuleDevelopment.Template { @@ -96,5 +98,46 @@ public TemplateInfo ToTemplateInfo() return info; } + + /// + /// Create a blank template object + /// + public Template() + { + + } + + /// + /// Create a template object based on a deserialized template object + /// + /// The deserialized tample object to restore + /// If anything at all is not as it should be. + public Template(PSObject Item) + { + try + { + Name = Item.GetValue("Name"); + Type = (TemplateType)Item.GetValue("Type"); + Version = Item.GetValue("Version"); + Description = Item.GetValue("Description"); + Author = Item.GetValue("Author"); + CreatedOn = Item.GetValue("CreatedOn"); + foreach (object item in Item.GetValue("Tags")) + Tags.Add((string)item); + foreach (object item in Item.GetValue("Parameters")) + Parameters.Add((string)item); + foreach (KeyValuePair entry in Item.GetDictionary("Scripts")) + Scripts[entry.Key] =entry.Value; + // Parameters2 not used + foreach (object item in Item.GetValue("Children")) + Children.Add(TemplateHost.GetTemplateItem(item)); + + Generation = Item.GetValue("Generation"); + } + catch (Exception e) + { + throw new ArgumentException($"Cannot convert {Item} of type {Item.BaseObject.GetType().FullName} to type PSModuleDevelopment.Template.Template! {e.Message}", e); + } + } } } diff --git a/library/PSModuleDevelopment/PSModuleDevelopment/Template/TemplateHost.cs b/library/PSModuleDevelopment/PSModuleDevelopment/Template/TemplateHost.cs new file mode 100644 index 0000000..3ed53af --- /dev/null +++ b/library/PSModuleDevelopment/PSModuleDevelopment/Template/TemplateHost.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Management.Automation; +using System.Text; +using System.Threading.Tasks; +using PSModuleDevelopment.Utility; + +namespace PSModuleDevelopment.Template +{ + /// + /// Static helpers for the template system + /// + internal static class TemplateHost + { + internal static TemplateItemBase GetTemplateItem(object Item) + { + if (Item.GetType() == typeof(TemplateItemFile)) + return (TemplateItemFile)Item; + + TemplateItemFolder result = new TemplateItemFolder(); ; + PSObject PSItem = PSObject.AsPSObject(Item); + + foreach (object child in PSItem.GetValue("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")) + result.FileSystemParameterFlat.Add(entry); + foreach (string entry in PSItem.GetValue("FileSystemParameterScript")) + result.FileSystemParameterScript.Add(entry); + + return result; + } + } +} diff --git a/library/PSModuleDevelopment/PSModuleDevelopment/Utility/PSObjectExtension.cs b/library/PSModuleDevelopment/PSModuleDevelopment/Utility/PSObjectExtension.cs new file mode 100644 index 0000000..8fb3235 --- /dev/null +++ b/library/PSModuleDevelopment/PSModuleDevelopment/Utility/PSObjectExtension.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Management.Automation; +using System.Text; +using System.Threading.Tasks; + +namespace PSModuleDevelopment.Utility +{ + /// + /// Extends the PSObject with C# convenience + /// + public static class PSObjectExtension + { + /// + /// Get the value! + /// + /// The type of the value + /// The object to extend + /// The name of the property that has the value + /// The value + public static T GetValue(this PSObject PSObject, string Name) + { + PSObject value = PSObject.AsPSObject(PSObject.Properties[Name].Value); + return (T)value.BaseObject; + } + + /// + /// Get a hashtable value! + /// + /// The type of the values in hashtable + /// The object to extend + /// The name of the property that has the hashtable + /// The hashtable! + public static Dictionary GetDictionary(this PSObject PSObject, string Name) + { + Hashtable temp = PSObject.GetValue(Name); + Dictionary result = new Dictionary(); + foreach (DictionaryEntry pair in temp) + result[(string)pair.Key] = (T)pair.Value; + + return result; + } + } +}