From 25942583decf0651f6e40d1df5e1c61bcacef569 Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Sat, 29 Apr 2023 16:54:07 +0200 Subject: [PATCH 01/16] Replaced `ConvertTo-Expression` by an empty dummy --- .../Modules/JeaDsc.Common/JeaDsc.Common.psm1 | 580 +----------------- 1 file changed, 5 insertions(+), 575 deletions(-) diff --git a/source/Modules/JeaDsc.Common/JeaDsc.Common.psm1 b/source/Modules/JeaDsc.Common/JeaDsc.Common.psm1 index f0c8c91..4ea773a 100644 --- a/source/Modules/JeaDsc.Common/JeaDsc.Common.psm1 +++ b/source/Modules/JeaDsc.Common/JeaDsc.Common.psm1 @@ -21,581 +21,6 @@ function Convert-ObjectToHashtable } } -function ConvertTo-Expression -{ - <# - .SYNOPSIS - Serializes an object to a PowerShell expression. - - .DESCRIPTION - The ConvertTo-Expression cmdlet converts (serializes) an object to a - PowerShell expression. The object can be stored in a variable, file or - any other common storage for later use or to be ported to another - system. - - An expression can be restored to an object using the native - Invoke-Expression cmdlet: - - $Object = Invoke-Expression ($Object | ConverTo-Expression) - - Or Converting it to a [scriptblock] and invoking it with cmdlets - along with `Invoke-Command` or using the call operator (`&`): - - $Object = &([scriptblock]::Create($Object | ConverTo-Expression)) - - An expression that is stored in a PowerShell (.ps1) file might also - be directly invoked by the PowerShell dot-sourcing technique, e.g.: - - $Object | ConvertTo-Expression | Out-File .\Expression.ps1 - $Object = . .\Expression.ps1 - - Warning: Invoking partly trusted input with Invoke-Expression or - [scriptblock]::Create() methods could be abused by malicious code - injections. - - .INPUTS - Any. Each objects provided through the pipeline will converted to an - expression. To concatinate all piped objects in a single expression, - use the unary comma operator, e.g.: ,$Object | ConvertTo-Expression - - .OUTPUTS - String[]. ConvertTo-Expression returns a PowerShell expression for - each input object. - - .PARAMETER InputObject - Specifies the objects to convert to a PowerShell expression. Enter a - variable that contains the objects, or type a command or expression - that gets the objects. You can also pipe one or more objects to - ConvertTo-Expression. - - .PARAMETER Depth - Specifies how many levels of contained objects are included in the - PowerShell representation. The default value is 9. - - .PARAMETER Expand - Specifies till what level the contained objects are expanded over - separate lines and indented according to the -Indentation and - -IndentChar parameters. The default value is equal to the -Depth value. - - A negative value will remove redundant spaces and compress the - PowerShell expression to a single line (except for multi-line strings). - - Xml documents and multi-line strings are embedded in a "here string" - and aligned to the left. - - .PARAMETER Indentation - Specifies how many IndentChars to write for each level in the - hierarchy. - - .PARAMETER IndentChar - Specifies which character to use for indenting. - - .PARAMETER Strong - By default, the ConvertTo-Expression cmdlet will return a weakly typed - expression which is best for transfing objects between differend - PowerShell systems. - The -Strong parameter will strickly define value types and objects - in a way that they can still be read by same PowerShell system and - PowerShell system with the same configuration (installed modules etc.). - - .PARAMETER Explore - In explore mode, all type prefixes are omitted in the output expression - (objects will cast to to hash tables). In case the -Strong parameter is - also supplied, all orginal (.Net) type names are shown. - The -Explore switch is usefull for exploring object hyrachies and data - type, not for saving and transfering objects. - - .EXAMPLE - - PS C:\> (Get-UICulture).Calendar | ConvertTo-Expression - - [pscustomobject]@{ - 'AlgorithmType' = 1 - 'CalendarType' = 1 - 'Eras' = ,1 - 'IsReadOnly' = $false - 'MaxSupportedDateTime' = [datetime]'9999-12-31T23:59:59.9999999' - 'MinSupportedDateTime' = [datetime]'0001-01-01T00:00:00.0000000' - 'TwoDigitYearMax' = 2029 - } - - PS C:\> (Get-UICulture).Calendar | ConvertTo-Expression -Strong - - [pscustomobject]@{ - 'AlgorithmType' = [System.Globalization.CalendarAlgorithmType]'SolarCalendar' - 'CalendarType' = [System.Globalization.GregorianCalendarTypes]'Localized' - 'Eras' = [array][int]1 - 'IsReadOnly' = [bool]$false - 'MaxSupportedDateTime' = [datetime]'9999-12-31T23:59:59.9999999' - 'MinSupportedDateTime' = [datetime]'0001-01-01T00:00:00.0000000' - 'TwoDigitYearMax' = [int]2029 - } - - .EXAMPLE - - PS C:\>Get-Date | Select-Object -Property * | ConvertTo-Expression | Out-File .\Now.ps1 - - PS C:\>$Now = .\Now.ps1 # $Now = Get-Content .\Now.Ps1 -Raw | Invoke-Expression - - PS C:\>$Now - - Date : 1963-10-07 12:00:00 AM - DateTime : Monday, October 7, 1963 10:47:00 PM - Day : 7 - DayOfWeek : Monday - DayOfYear : 280 - DisplayHint : DateTime - Hour : 22 - Kind : Local - Millisecond : 0 - Minute : 22 - Month : 1 - Second : 0 - Ticks : 619388596200000000 - TimeOfDay : 22:47:00 - Year : 1963 - - .EXAMPLE - - PS C:\>@{Account="User01";Domain="Domain01";Admin="True"} | ConvertTo-Expression -Expand -1 # Compress the PowerShell output - - @{'Admin'='True';'Account'='User01';'Domain'='Domain01'} - - .EXAMPLE - - PS C:\>WinInitProcess = Get-Process WinInit | ConvertTo-Expression # Convert the WinInit Process to a PowerShell expression - - .EXAMPLE - - PS C:\>Get-Host | ConvertTo-Expression -Depth 4 # Reveal complex object hierarchies - - .LINK - https://www.powershellgallery.com/packages/ConvertFrom-Expression - #> - [CmdletBinding()] - [OutputType([scriptblock])] - param ( - [Parameter(ValueFromPipeLine = $true)] - [Alias('InputObject')] - [object]$Object, - - [Parameter()] - [int]$Depth = 9, - - [Parameter()] - [int]$Expand = $Depth, - - [Parameter()] - [int]$Indentation = 1, - - [Parameter()] - [string]$IndentChar = "`t", - - [Parameter()] - [switch]$Strong, - - [Parameter()] - [switch]$Explore, - - [Parameter()] - [string]$NewLine = [System.Environment]::NewLine - ) - begin - { - $listItem = $null - $Tab = $IndentChar * $Indentation - function Serialize - { - param ( - [Parameter()] - [object]$Object, - - [Parameter()] - $Iteration, - - [Parameter()] - $Indent - ) - - function Quote - { - param ( - [Parameter()] - [string]$Item - ) - - "'$($Item.Replace('''', ''''''))'" - } - function Here - { - param ( - [Parameter()] - [string]$Item - ) - - if ($Item -match '[\r\n]') - { - "@'$NewLine$Item$NewLine'@$NewLine" - } - else - { - Quote -Item $Item - } - } - function Stringify - { - param ( - [Parameter()] - [object]$Object, - - [Parameter()] - [string]$Cast = $Type, - - [Parameter()] - [string]$Convert - ) - - $casted = $PSBoundParameters.ContainsKey('Cast') - function Prefix - { - param ( - [Parameter()] - [object]$Object, - - [Parameter()] - [switch]$Parenthesis - ) - - if ($Convert) - { - if ($listItem) - { - $Object = "($Convert $Object)" - } - else - { - $Object = "$Convert $Object" - } - } - if ($Parenthesis) - { - $Object = "($Object)" - } - if ($Explore) - { - if ($Strong) - { - "[$Type]$Object" - } - else - { - $Object - } - } - elseif ($Strong -or $casted) - { - if ($Cast) - { - "[$Cast]$Object" - } - } - else - { - $Object - } - } - function Iterate - { - param ( - [Parameter()] - [object]$Object, - - [Parameter()] - [switch]$Strong = $Strong, - - [Parameter()] - [switch]$listItem, - - [Parameter()] - [switch]$Level - ) - - if ($Iteration -lt $Depth) - { - Serialize -Object $Object -Iteration ($Iteration + 1) -Indent ($Indent + 1 - [int][Bool]$Level) - } - else - { - "'...'" - } - } - if ($Object -is [string]) - { - Prefix -Object $Object - } - else - { - $List = $null - $Properties = $null - $Methods = $Object.PSObject.Methods.Name - - if ($Methods -contains 'GetEnumerator') - { - if ($Methods -contains 'get_Keys' -and $Methods -contains 'get_Values') - { - $List = [Ordered]@{ } - foreach ($Key in $Object.get_Keys()) - { - $List[(Quote $Key)] = Iterate $Object[$Key] - } - } - else - { - $Level = @($Object).Count -eq 1 -or ($null -eq $Indent -and -not $Explore -and -not $Strong) - $StrongItem = $Strong -and $Type.Name -eq 'Object[]' - $List = @(foreach ($Item in $Object) - { - Iterate $Item -ListItem -Level:$Level -Strong:$StrongItem - }) - } - } - else - { - $Properties = $Object.PSObject.Properties | Where-Object { $_.MemberType -eq 'Property' } - if (-not $Properties) - { - $Properties = $Object.PSObject.Properties | Where-Object { $_.MemberType -eq 'NoteProperty' } - } - if ($Properties) - { - $List = [Ordered]@{ }; foreach ($Property in $Properties) - { - $List[(Quote $Property.Name)] = Iterate $Property.Value - } - } - } - if ($List -is [Array]) - { - if (-not $casted -and ($Type.Name -eq 'Object[]' -or "$Type".Contains('.'))) - { - $Cast = 'array' - } - if (-not $List.Count) - { - Prefix '@()' - } - elseif ($List.Count -eq 1) - { - if ($Strong) - { - Prefix "$List" - } - elseif ($listItem) - { - "(,$List)" - } - else - { - ",$List" - } - } - elseif ($Indent -ge $Expand - 1 -or $Type.GetElementType().IsPrimitive) - { - $Content = if ($Expand -ge 0) - { - $List -join ', ' - } - else - { - $List -join ',' - } - Prefix -Parenthesis:($listItem -or $Strong) $Content - } - elseif ($null -eq $Indent -and -not $Strong -and -not $Convert) - { - Prefix ($List -join ",$NewLine") - } - else - { - $LineFeed = $NewLine + ($Tab * $Indent) - $Content = "$LineFeed$Tab" + ($List -join ",$LineFeed$Tab") - if ($Convert) - { - $Content = "($Content)" - } - if ($listItem -or $Strong) - { - Prefix -Parenthesis "$Content$LineFeed" - } - else - { - Prefix $Content - } - } - } - elseif ($List -is [System.Collections.Specialized.OrderedDictionary]) - { - if (-not $casted) - { - if ($Properties) - { - $casted = $true; $Cast = 'pscustomobject' - } - else - { - $Cast = 'hashtable' - } - } - if (-not $List.Count) - { - Prefix '@{}' - } - elseif ($Expand -lt 0) - { - Prefix ('@{' + (@(foreach ($Key in $List.get_Keys()) - { - "$Key=" + $List[$Key] - }) -join ';') + '}') - } - elseif ($List.Count -eq 1 -or $Indent -ge $Expand - 1) - { - Prefix ('@{' + (@(foreach ($Key in $List.get_Keys()) - { - "$Key = " + $List[$Key] - }) -join '; ') + '}') - } - else - { - $LineFeed = $NewLine + ($Tab * $Indent) - Prefix ("@{$LineFeed$Tab" + (@(foreach ($Key in $List.get_Keys()) - { - if (($List[$Key])[0] -NotMatch '[\S]') - { - "$Key =" + $List[$Key].TrimEnd() - } - else - { - "$Key = " + $List[$Key].TrimEnd() - } - }) -join "$LineFeed$Tab") + "$LineFeed}") - } - } - else - { - Prefix ",$List" - } - } - } - if ($null -eq $Object) - { - "`$null" - } - else - { - $Type = $Object.GetType() - if ($Object -is [Boolean]) - { - if ($Object) - { - Stringify '$true' - } - else - { - Stringify '$false' - } - } - elseif ($Object -is [adsi]) - { - Stringify "'$($Object.ADsPath)'" $Type - } - elseif ('Char', 'mailaddress', 'Regex', 'Semver', 'Type', 'Version', 'Uri' -contains $Type.Name) - { - Stringify "'$($Object)'" $Type - } - elseif ($Type.IsPrimitive) - { - Stringify "$Object" - } - elseif ($Object -is [string]) - { - Stringify (Here $Object) - } - elseif ($Object -is [SecureString]) - { - Stringify "'$($Object | ConvertFrom-SecureString)'" -Convert 'ConvertTo-SecureString' - } - elseif ($Object -is [PSCredential]) - { - Stringify $Object.Username, $Object.Password -Convert 'New-Object PSCredential' - } - elseif ($Object -is [datetime]) - { - Stringify "'$($Object.ToString('o'))'" $Type - } - elseif ($Object -is [System.Enum]) - { - if ("$Type".Contains('.')) - { - Stringify "$(0 + $Object)" - } - else - { - Stringify "'$Object'" $Type - } - } - elseif ($Object -is [scriptblock]) - { - if ($Object -Match "\#.*?$") - { - Stringify "{$Object$NewLine}" - } - else - { - Stringify "{$Object}" - } - } - elseif ($Object -is [System.RuntimeTypeHandle]) - { - Stringify "$($Object.Value)" - } - elseif ($Object -is [xml]) - { - $sw = New-Object System.IO.StringWriter; $xw = New-Object System.Xml.XmlTextWriter $sw - $xw.Formatting = if ($Indent -lt $Expand - 1) - { - 'Indented' - } - else - { - 'None' - } - $xw.Indentation = $Indentation; $xw.IndentChar = $IndentChar; $Object.WriteContentTo($xw); Stringify (Here $sw) $Type - } - elseif ($Object -is [System.Data.DataTable]) - { - Stringify $Object.Rows - } - elseif ($Type.Name -eq "OrderedDictionary") - { - Stringify $Object 'ordered' - } - elseif ($Object -is [System.ValueType]) - { - Stringify "'$($Object)'" $Type - } - else - { - Stringify $Object - } - } - } - } - process - { - (Serialize $Object).TrimEnd() - } -} - function Convert-StringToObject { [CmdletBinding()] @@ -730,6 +155,11 @@ function Sync-Parameter $Parameters } +function ConvertTo-Expression +{ + 'TOBEREPACED' +} + $modulePath = Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -ChildPath Modules Import-Module -Name (Join-Path -Path $modulePath -ChildPath DscResource.Common) From c8827193cf844caa48191f1fb9fac5ef3fa044e2 Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Sat, 29 Apr 2023 17:11:54 +0200 Subject: [PATCH 02/16] Moved function into a separate module --- source/Modules/ConvertToExpression/ConvertToExpression.psm1 | 4 ++++ source/Modules/JeaDsc.Common/JeaDsc.Common.psm1 | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) create mode 100644 source/Modules/ConvertToExpression/ConvertToExpression.psm1 diff --git a/source/Modules/ConvertToExpression/ConvertToExpression.psm1 b/source/Modules/ConvertToExpression/ConvertToExpression.psm1 new file mode 100644 index 0000000..00ac2d6 --- /dev/null +++ b/source/Modules/ConvertToExpression/ConvertToExpression.psm1 @@ -0,0 +1,4 @@ +function ConvertTo-Expression +{ + 'TOBEREPACED' +} diff --git a/source/Modules/JeaDsc.Common/JeaDsc.Common.psm1 b/source/Modules/JeaDsc.Common/JeaDsc.Common.psm1 index 4ea773a..89b017b 100644 --- a/source/Modules/JeaDsc.Common/JeaDsc.Common.psm1 +++ b/source/Modules/JeaDsc.Common/JeaDsc.Common.psm1 @@ -155,11 +155,6 @@ function Sync-Parameter $Parameters } -function ConvertTo-Expression -{ - 'TOBEREPACED' -} - $modulePath = Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -ChildPath Modules Import-Module -Name (Join-Path -Path $modulePath -ChildPath DscResource.Common) From ce117be0955b6aa7eee98b04f706619c8e89f278 Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Sat, 29 Apr 2023 17:12:14 +0200 Subject: [PATCH 03/16] Removed tests for now external code --- tests/Unit/ConvertTo-Expression.Tests.ps1 | 1278 --------------------- 1 file changed, 1278 deletions(-) delete mode 100644 tests/Unit/ConvertTo-Expression.Tests.ps1 diff --git a/tests/Unit/ConvertTo-Expression.Tests.ps1 b/tests/Unit/ConvertTo-Expression.Tests.ps1 deleted file mode 100644 index 519590e..0000000 --- a/tests/Unit/ConvertTo-Expression.Tests.ps1 +++ /dev/null @@ -1,1278 +0,0 @@ -Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath ..\..\output\JeaDsc) - -InModuleScope JeaDsc { - - Describe 'ConvertTo-Expression' { - - $Version = [System.Version]'1.2.3.4' - $Guid = [guid]'5f167621-6abe-4153-a26c-f643e1716720' - $TimeSpan = New-TimeSpan -Hours 1 -Minutes 25 - $DateTime = Get-Date - Mock Get-Date -ParameterFilter { - $null -eq $Date - } { - $DateTime - } - - $PSDefaultParameterValues = @{ - 'Test-Format:Indentation' = 4 - 'Test-Format:IndentChar' = ' ' - } - - function Should-BeEqualTo - { - param ( - [Parameter(Mandatory = $true)] - [object]$Value2, - - [Parameter(ValueFromPipeLine = $true)] - [object]$Value1 - ) - - $Value1 | Should -Be $Value2 - $Value1 | Should -BeOfType $Value2.GetType().Name - } - - function Test-Format - { - param ( - [Parameter(Mandatory = $true)] - [string]$Expression, - - [Parameter()] - [switch]$Strong, - - [Parameter()] - [int]$Expand = 9, - - [Parameter()] - [int]$Indentation = 1, - - [Parameter()] - [string]$IndentChar = "`t" - ) - - $object = &([scriptblock]::Create("$Expression")) - $actual = ConvertTo-Expression $object -Strong:$Strong -Expand $Expand -Indentation $Indentation -IndentChar $IndentChar - It "$Expression" { - "$actual" | Should -Be "$Expression" - } - } - - Context 'custom object' { - $DataTable = New-Object -TypeName Data.DataTable - $null = $DataTable.Columns.Add((New-Object -TypeName Data.DataColumn -ArgumentList 'Column1'), [string]) - $null = $DataTable.Columns.Add((New-Object -TypeName Data.DataColumn -ArgumentList 'Column2'), [int]) - $DataRow = $DataTable.NewRow() - $DataRow.Item('Column1') = 'A' - $DataRow.Item('Column2') = 1 - $DataTable.Rows.Add($DataRow) - $DataRow = $DataTable.NewRow() - $DataRow.Item('Column1') = 'B' - $DataRow.Item('Column2') = 2 - $DataTable.Rows.Add($DataRow) - - $Object = @{ - String = [string]'String' - Text = [string]"Hello`r`nWorld" - Char = [char]65 - Byte = [byte]66 - Int = [int]67 - Long = [long]68 - Null = $null - Booleans = $false, $true - Decimal = [decimal]69 - Single = [single]70 - Double = [double]71 - Adsi = [adsi]'WinNT://./Administrators' - DateTime = $DateTime - TimeSpan = $TimeSpan - Version = $Version - Guid = $Guid - Script = { - 2 * 3 - } - Array = @('One', 'Two', @('Three', 'Four'), 'Five') - EmptyArray = @() - HashTable = @{ - city = 'New York' - currency = "Dollar (`$)" - postalCode = 10021 - Etc = @('Three', 'Four', 'Five') - } - Ordered = [ordered]@{ - One = 1 - Two = 2 - Three = 3 - Four = 4 - } - Object = New-Object -TypeName PSObject -Property @{ - Name = 'One' - Value = 1 - Group = @('First', 'Last') - } - DataTable = $DataTable - Xml = [xml]@" - - - Cake - 0.55 - - Regular - Chocolate - Blueberry - - None - Glazed - Sugar - Sprinkles - Chocolate - Maple - - - -"@ - } - - It 'default conversion' { - $Expression = $Object | ConvertTo-Expression - - $Actual = &([scriptblock]::Create($Expression)) - - $Actual.String | Should -Be $Object.String - $Actual.Text | Should -Be $Object.Text - $Actual.Char | Should -Be $Object.Char - $Actual.Byte | Should -Be $Object.Byte - $Actual.Int | Should -Be $Object.Int - $Actual.Long | Should -Be $Object.Long - $Actual.Null | Should -Be $Object.Null - $Actual.Booleans[0] | Should -Be $Object.Booleans[0] - $Actual.Booleans[1] | Should -Be $Object.Booleans[1] - $Actual.Decimal | Should -Be $Object.Decimal - $Actual.Single | Should -Be $Object.Single - $Actual.Double | Should -Be $Object.Double - $Actual.Long | Should -Be $Object.Long - $Actual.Adsi | Should -BeOfType [adsi] - $Actual.DateTime | Should -Be $DateTime - $Actual.TimeSpan | Should -Be $TimeSpan - $Actual.Version | Should -Be $Version - $Actual.Guid | Should -Be $Guid - &$Actual.Script | Should -Be (&$Object.Script) - $Actual.Array | Should -Be $Object.Array - , $Actual.EmptyArray | Should -BeOfType [array] - $Actual.HashTable.City | Should -Be $Object.HashTable.City - $Actual.HashTable.Currency | Should -Be $Object.HashTable.Currency - $Actual.HashTable.PostalCode | Should -Be $Object.HashTable.PostalCode - $Actual.HashTable.Etc | Should -Be $Object.HashTable.Etc - $Actual.Ordered.One | Should -Be $Object.Ordered.One - $Actual.Ordered.Two | Should -Be $Object.Ordered.Two - $Actual.Ordered.Three | Should -Be $Object.Ordered.Three - $Actual.Ordered.Four | Should -Be $Object.Ordered.Four - $Actual.Object.Name | Should -Be $Object.Object.Name - $Actual.Object.Value | Should -Be $Object.Object.Value - $Actual.Object.Group | Should -Be $Object.Object.Group - $Actual.DataTable.Column1[0] | Should -Be $Object.DataTable.Column1[0] - $Actual.DataTable.Column1[1] | Should -Be $Object.DataTable.Column1[1] - $Actual.DataTable.Column2[0] | Should -Be $Object.DataTable.Column2[0] - $Actual.DataTable.Column2[1] | Should -Be $Object.DataTable.Column2[1] - } - - It 'compress' { - $Expression = $Object | ConvertTo-Expression -Expand -1 - - $Actual = &([scriptblock]::Create($Expression)) - - $Actual.String | Should -Be $Object.String - $Actual.Text | Should -Be $Object.Text - $Actual.Char | Should -Be $Object.Char - $Actual.Byte | Should -Be $Object.Byte - $Actual.Int | Should -Be $Object.Int - $Actual.Long | Should -Be $Object.Long - $Actual.Null | Should -Be $Object.Null - $Actual.Booleans[0] | Should -Be $Object.Booleans[0] - $Actual.Booleans[1] | Should -Be $Object.Booleans[1] - $Actual.Decimal | Should -Be $Object.Decimal - $Actual.Single | Should -Be $Object.Single - $Actual.Double | Should -Be $Object.Double - $Actual.Long | Should -Be $Object.Long - $Actual.Adsi | Should -BeOfType [adsi] - $Actual.DateTime | Should -Be $DateTime - $Actual.TimeSpan | Should -Be $TimeSpan - $Actual.Guid | Should -Be $Guid - $Actual.Version | Should -Be $Version - &$Actual.Script | Should -Be (&$Object.Script) - $Actual.Array | Should -Be $Object.Array - , $Actual.EmptyArray | Should -BeOfType [array] - $Actual.HashTable.City | Should -Be $Object.HashTable.City - $Actual.HashTable.Currency | Should -Be $Object.HashTable.Currency - $Actual.HashTable.PostalCode | Should -Be $Object.HashTable.PostalCode - $Actual.HashTable.Etc | Should -Be $Object.HashTable.Etc - $Actual.Ordered.One | Should -Be $Object.Ordered.One - $Actual.Ordered.Two | Should -Be $Object.Ordered.Two - $Actual.Ordered.Three | Should -Be $Object.Ordered.Three - $Actual.Ordered.Four | Should -Be $Object.Ordered.Four - $Actual.Object.Name | Should -Be $Object.Object.Name - $Actual.Object.Value | Should -Be $Object.Object.Value - $Actual.Object.Group | Should -Be $Object.Object.Group - $Actual.DataTable.Column1[0] | Should -Be $Object.DataTable.Column1[0] - $Actual.DataTable.Column1[1] | Should -Be $Object.DataTable.Column1[1] - $Actual.DataTable.Column2[0] | Should -Be $Object.DataTable.Column2[0] - $Actual.DataTable.Column2[1] | Should -Be $Object.DataTable.Column2[1] - } - - It 'converts strong type' { - $Expression = $Object | ConvertTo-Expression -Strong - - $Actual = &([scriptblock]::Create($Expression)) - - $Actual.String | Should-BeEqualTo $Object.String - $Actual.Text | Should-BeEqualTo $Object.Text - $Actual.Char | Should-BeEqualTo $Object.Char - $Actual.Byte | Should-BeEqualTo $Object.Byte - $Actual.Int | Should-BeEqualTo $Object.Int - $Actual.Long | Should-BeEqualTo $Object.Long - $Actual.Null | Should -Be $Object.Null - $Actual.Booleans[0] | Should-BeEqualTo $Object.Booleans[0] - $Actual.Booleans[1] | Should-BeEqualTo $Object.Booleans[1] - $Actual.Decimal | Should-BeEqualTo $Object.Decimal - $Actual.Single | Should-BeEqualTo $Object.Single - $Actual.Double | Should-BeEqualTo $Object.Double - $Actual.Long | Should-BeEqualTo $Object.Long - $Actual.Adsi | Should -BeOfType [adsi] - $Actual.DateTime | Should-BeEqualTo $DateTime - $Actual.TimeSpan | Should-BeEqualTo $TimeSpan - $Actual.Version | Should-BeEqualTo $Version - $Actual.Guid | Should-BeEqualTo $Guid - &$Actual.Script | Should-BeEqualTo (&$Object.Script) - $Actual.Array | Should -Be $Object.Array - , $Actual.EmptyArray | Should -BeOfType [array] - $Actual.HashTable.City | Should -Be $Object.HashTable.City - $Actual.HashTable.Currency | Should -Be $Object.HashTable.Currency - $Actual.HashTable.PostalCode | Should -Be $Object.HashTable.PostalCode - $Actual.HashTable.Etc | Should -Be $Object.HashTable.Etc - $Actual.Ordered.One | Should -Be $Object.Ordered.One - $Actual.Ordered.Two | Should -Be $Object.Ordered.Two - $Actual.Ordered.Three | Should -Be $Object.Ordered.Three - $Actual.Ordered.Four | Should -Be $Object.Ordered.Four - $Actual.Object.Name | Should -Be $Object.Object.Name - $Actual.Object.Value | Should -Be $Object.Object.Value - $Actual.Object.Group | Should -Be $Object.Object.Group - $Actual.DataTable.Column1[0] | Should -Be $Object.DataTable.Column1[0] - $Actual.DataTable.Column1[1] | Should -Be $Object.DataTable.Column1[1] - $Actual.DataTable.Column2[0] | Should -Be $Object.DataTable.Column2[0] - $Actual.DataTable.Column2[1] | Should -Be $Object.DataTable.Column2[1] - $Actual.XML | Should -BeOfType [System.Xml.XmlDocument] - } - - It 'convert calendar to expression' { - $Calendar = (Get-UICulture).Calendar - - $Expression = $Calendar | ConvertTo-Expression - - $Actual = &([scriptblock]::Create($Expression)) - - $Actual.AlgorithmType | Should -Be $Calendar.AlgorithmType - $Actual.CalendarType | Should -Be $Calendar.CalendarType - $Actual.Eras | Should -Be $Calendar.Eras - $Actual.IsReadOnly | Should -Be $Calendar.IsReadOnly - $Actual.MaxSupportedDateTime | Should -Be $Calendar.MaxSupportedDateTime - $Actual.MinSupportedDateTime | Should -Be $Calendar.MinSupportedDateTime - $Actual.TwoDigitYearMax | Should -Be $Calendar.TwoDigitYearMax - } - - It 'compress ConvertTo-Expression' { - $User = @{ - Account = 'User01' - Domain = 'Domain01' - Admin = $true - } - - $Expression = $User | ConvertTo-Expression -Expand -1 - - "$Expression".Contains(' ') | Should -Be $false - - $Actual = &([scriptblock]::Create($Expression)) - - $Actual.Account | Should-BeEqualTo $User.Account - $Actual.Domain | Should-BeEqualTo $User.Domain - $Actual.Admin | Should-BeEqualTo $User.Admin - } - - It 'convert Date' { - $Date = Get-Date | Select-Object -Property * - - $Expression = $Date | ConvertTo-Expression - - $Actual = &([scriptblock]::Create($Expression)) - - $Actual.Date | Should -Be $Date.Date - $Actual.DateTime | Should -Be $Date.DateTime - $Actual.Day | Should -Be $Date.Day - $Actual.DayOfWeek | Should -Be $Date.DayOfWeek - $Actual.DayOfYear | Should -Be $Date.DayOfYear - $Actual.DisplayHint | Should -Be $Date.DisplayHint - $Actual.Hour | Should -Be $Date.Hour - $Actual.Kind | Should -Be $Date.Kind - $Actual.Millisecond | Should -Be $Date.Millisecond - $Actual.Minute | Should -Be $Date.Minute - $Actual.Month | Should -Be $Date.Month - $Actual.Second | Should -Be $Date.Second - $Actual.Ticks | Should -Be $Date.Ticks - $Actual.TimeOfDay | Should -Be $Date.TimeOfDay - $Actual.Year | Should -Be $Date.Year - } - } - - Context 'system objects' { - $WinInitProcess = Get-Process WinInit - - It 'convert (wininit) process' { - $Expression = $WinInitProcess | ConvertTo-Expression - - $Actual = &([scriptblock]::Create($Expression)) - - # $Actual.ProcessName | Should-BeEqualTo $WinInitProcess.ProcessName - # $Actual.StartInfo.Environment['TEMP'] | Should -Be $WinInitProcess.StartInfo.Environment['TEMP'] - # $Actual.StartInfo.EnvironmentVariables['TEMP'] | Should -Be $WinInitProcess.StartInfo.EnvironmentVariables['TEMP'] - } - - It 'convert (wininit) process (Strong)' { - $Expression = $WinInitProcess | ConvertTo-Expression -Strong - - $Actual = &([scriptblock]::Create($Expression)) - - # $Actual.ProcessName | Should-BeEqualTo $WinInitProcess.ProcessName - # $Actual.StartInfo.Environment['TEMP'] | Should -Be $WinInitProcess.StartInfo.Environment['TEMP'] - # $Actual.StartInfo.EnvironmentVariables['TEMP'] | Should -Be $WinInitProcess.StartInfo.EnvironmentVariables['TEMP'] - } - - It 'convert MyInvocation' { - $Expression = $MyInvocation | ConvertTo-Expression - - $Actual = &([scriptblock]::Create($Expression)) - - $Actual.MyCommand.Name | Should -Be $MyInvocation.MyCommand.Name - } - - It 'convert MyInvocation (Strong)' { - $Expression = $MyInvocation | ConvertTo-Expression -Strong - - $Actual = &([scriptblock]::Create($Expression)) - - $Actual.MyCommand.Name | Should -Be $MyInvocation.MyCommand.Name - } - } - - Context 'cast types' { - $Ordered = [ordered]@{ - a = 1 - b = 2 - } - - It 'default' { - $Expression = $Ordered | ConvertTo-Expression -Expand 0 - "$Expression" | Should -Be "[ordered]@{'a' = 1; 'b' = 2}" - } - - It 'strong' { - $Expression = $Ordered | ConvertTo-Expression -Expand 0 -Strong - "$Expression" | Should -Be "[ordered]@{'a' = [int]1; 'b' = [int]2}" - } - - It 'explore' { - $Expression = $Ordered | ConvertTo-Expression -Expand 0 -Explore - "$Expression" | Should -Be "@{'a' = 1; 'b' = 2}" - } - - It 'explore strong' { - $Expression = $Ordered | ConvertTo-Expression -Expand 0 -Explore -Strong - "$Expression" | Should -Be "[System.Collections.Specialized.OrderedDictionary]@{'a' = [int]1; 'b' = [int]2}" - } - } - - Context 'default formatting' { - Test-Format '1' - - Test-Format "'One'" - - # Test-Format ",'One'" - - Test-Format @" -1, -2, -3 -"@ - - Test-Format @" -'One', -'Two', -'Three' -"@ - - Test-Format @" -'One', -'Two', -'Three', -'Four' -"@ - - Test-Format @" -'One', -(,'Two'), -'Three', -'Four' -"@ - - Test-Format @" -'One', -( - 'Two', - 'Three' -), -'Four' -"@ - - Test-Format @" -'One', -@{'Two' = 2}, -'Three', -'Four' -"@ - - Test-Format @" -[pscustomobject]@{'value' = 1}, -[pscustomobject]@{'value' = 2}, -[pscustomobject]@{'value' = 3} -"@ - - Test-Format @" -[pscustomobject]@{ - 'One' = 1 - 'Two' = 2 - 'Three' = 3 - 'Four' = 4 -} -"@ - - Test-Format @" -'One', -[ordered]@{ - 'Two' = 2 - 'Three' = 3 -}, -'Four' -"@ - - Test-Format "@{'One' = 1}" - - Test-Format @" -[ordered]@{ - 'One' = 1 - 'Two' = 2 - 'Three' = 3 - 'Four' = 4 -} -"@ - - Test-Format @" -[ordered]@{ - 'One' = 1 - 'Two' = 2 - 'Three.1' = ,3.1 - 'Four' = 4 -} -"@ - - Test-Format @" -[ordered]@{ - 'One' = 1 - 'Two' = 2 - 'Three.12' = - 3.1, - 3.2 - 'Four' = 4 -} -"@ - - Test-Format @" -[ordered]@{ - 'One' = 1 - 'Two' = 2 - 'Three' = @{'One' = 3.1} - 'Four' = 4 -} -"@ - - Test-Format @" -[ordered]@{ - 'One' = 1 - 'Two' = 2 - 'Three' = [ordered]@{ - 'One' = 3.1 - 'Two' = 3.2 - } - 'Four' = 4 -} -"@ - - Test-Format @" -[ordered]@{ - 'String' = 'String' - 'HereString' = @' -Hello -World -'@ - 'Int' = 67 - 'Double' = 1.2 - 'Long' = 1234567890123456 - 'DateTime' = [datetime]'1963-10-07T17:56:53.8139055' - 'Version' = [version]'1.2.34567.890' - 'Guid' = [guid]'5f167621-6abe-4153-a26c-f643e1716720' - 'Script' = {2 * 3} - 'Array' = - 'One', - 'Two', - 'Three', - 'Four' - 'ByteArray' = - 1, - 2, - 3 - 'StringArray' = - 'One', - 'Two', - 'Three' - 'EmptyArray' = @() - 'SingleValueArray' = ,'one' - 'SubArray' = - 'One', - ( - 'Two', - 'Three' - ), - 'Four' - 'HashTable' = @{'Name' = 'Value'} - 'Ordered' = [ordered]@{ - 'One' = 1 - 'Two' = 2 - 'Three' = 3 - 'Four' = 4 - } - 'Object' = [pscustomobject]@{'Name' = 'Value'} -} -"@ - } - - Context 'strong formatting' { - Test-Format -Strong '[int]1' - - Test-Format -Strong "[string]'One'" - - # Test-Format -Strong "[byte[]](1, 2, 3)" - - # Test-Format -Strong @" - # [string[]]( - # 'One', - # 'Two', - # 'Three' - # ) - # "@ - - Test-Format -Strong @" -[array]( - [string]'One', - [string]'Two', - [string]'Three', - [string]'Four' -) -"@ - - Test-Format -Strong @" -[array]( - [string]'One', - [array][string]'Two', - [string]'Three', - [string]'Four' -) -"@ - - Test-Format -Strong @" -[array]( - [string]'One', - [array]( - [string]'Two', - [string]'Three' - ), - [string]'Four' -) -"@ - - Test-Format -Strong @" -[array]( - [string]'One', - [hashtable]@{'Two' = [int]2}, - [string]'Three', - [string]'Four' -) -"@ - - Test-Format -Strong @" -[array]( - [pscustomobject]@{'value' = [int]1}, - [pscustomobject]@{'value' = [int]2}, - [pscustomobject]@{'value' = [int]3} -) -"@ - - Test-Format -Strong @" -[pscustomobject]@{ - 'One' = [int]1 - 'Two' = [int]2 - 'Three' = [int]3 - 'Four' = [int]4 -} -"@ - - Test-Format -Strong @" -[array]( - [string]'One', - [ordered]@{ - 'Two' = [int]2 - 'Three' = [int]3 - }, - [string]'Four' -) -"@ - - Test-Format -Strong "[hashtable]@{'One' = [int]1}" - - Test-Format -Strong @" -[ordered]@{ - 'One' = [int]1 - 'Two' = [int]2 - 'Three' = [int]3 - 'Four' = [int]4 -} -"@ - - Test-Format -Strong @" -[ordered]@{ - 'One' = [int]1 - 'Two' = [int]2 - 'Three.1' = [array][double]3.1 - 'Four' = [int]4 -} -"@ - - Test-Format -Strong @" -[ordered]@{ - 'One' = [int]1 - 'Two' = [int]2 - 'Three.12' = [array]( - [double]3.1, - [double]3.2 - ) - 'Four' = [int]4 -} -"@ - - Test-Format -Strong @" -[ordered]@{ - 'One' = [int]1 - 'Two' = [int]2 - 'Three' = [hashtable]@{'One' = [double]3.1} - 'Four' = [int]4 -} -"@ - - Test-Format -Strong @" -[ordered]@{ - 'One' = [int]1 - 'Two' = [int]2 - 'Three' = [ordered]@{ - 'One' = [double]3.1 - 'Two' = [double]3.2 - } - 'Four' = [int]4 -} -"@ - - Test-Format -Strong @" -[ordered]@{ - 'String' = [string]'String' - 'HereString' = [string]@' -Hello -World -'@ - 'Int' = [int]67 - 'Double' = [double]1.2 - 'Long' = [long]1234567890123456 - 'DateTime' = [datetime]'1963-10-07T17:56:53.8139055' - 'Version' = [version]'1.2.34567.890' - 'Guid' = [guid]'5f167621-6abe-4153-a26c-f643e1716720' - 'Script' = [scriptblock]{2 * 3} - 'Array' = [array]( - [string]'One', - [string]'Two', - [string]'Three', - [string]'Four' - ) - 'ByteArray' = [byte[]](1, 2, 3) - 'StringArray' = [string[]]( - 'One', - 'Two', - 'Three' - ) - 'EmptyArray' = [array]@() - 'SingleValueArray' = [array][string]'one' - 'SubArray' = [array]( - [string]'One', - [array]( - [string]'Two', - [string]'Three' - ), - [string]'Four' - ) - 'HashTable' = [hashtable]@{'Name' = [string]'Value'} - 'Ordered' = [ordered]@{ - 'One' = [int]1 - 'Two' = [int]2 - 'Three' = [int]3 - 'Four' = [int]4 - } - 'Object' = [pscustomobject]@{'Name' = [string]'Value'} -} -"@ - } - - Context 'formatting -expand 1' { - Test-Format -Expand 1 '1' - - Test-Format -Expand 1 "'One'" - - Test-Format -Expand 1 @" -1, -2, -3 -"@ - - Test-Format -Expand 1 @" -'One', -'Two', -'Three' -"@ - - Test-Format -Expand 1 @" -'One', -'Two', -'Three', -'Four' -"@ - - Test-Format -Expand 1 @" -'One', -(,'Two'), -'Three', -'Four' -"@ - - Test-Format -Expand 1 @" -'One', -('Two', 'Three'), -'Four' -"@ - - Test-Format -Expand 1 @" -'One', -@{'Two' = 2}, -'Three', -'Four' -"@ - - Test-Format -Expand 1 @" -[pscustomobject]@{'value' = 1}, -[pscustomobject]@{'value' = 2}, -[pscustomobject]@{'value' = 3} -"@ - - Test-Format -Expand 1 @" -[pscustomobject]@{ - 'One' = 1 - 'Two' = 2 - 'Three' = 3 - 'Four' = 4 -} -"@ - - Test-Format -Expand 1 @" -'One', -[ordered]@{'Two' = 2; 'Three' = 3}, -'Four' -"@ - - Test-Format -Expand 1 "@{'One' = 1}" - - Test-Format -Expand 1 @" -[ordered]@{ - 'One' = 1 - 'Two' = 2 - 'Three' = 3 - 'Four' = 4 -} -"@ - - Test-Format -Expand 1 @" -[ordered]@{ - 'One' = 1 - 'Two' = 2 - 'Three.1' = ,3.1 - 'Four' = 4 -} -"@ - - Test-Format -Expand 1 @" -[ordered]@{ - 'One' = 1 - 'Two' = 2 - 'Three.12' = 3.1, 3.2 - 'Four' = 4 -} -"@ - - Test-Format -Expand 1 @" -[ordered]@{ - 'One' = 1 - 'Two' = 2 - 'Three' = @{'One' = 3.1} - 'Four' = 4 -} -"@ - - Test-Format -Expand 1 @" -[ordered]@{ - 'One' = 1 - 'Two' = 2 - 'Three' = [ordered]@{'One' = 3.1; 'Two' = 3.2} - 'Four' = 4 -} -"@ - Test-Format -Expand 1 @" -[ordered]@{ - 'String' = 'String' - 'HereString' = @' -Hello -World -'@ - 'Int' = 67 - 'Double' = 1.2 - 'Long' = 1234567890123456 - 'DateTime' = [datetime]'1963-10-07T17:56:53.8139055' - 'Version' = [version]'1.2.34567.890' - 'Guid' = [guid]'5f167621-6abe-4153-a26c-f643e1716720' - 'Script' = {2 * 3} - 'Array' = 'One', 'Two', 'Three', 'Four' - 'ByteArray' = 1, 2, 3 - 'StringArray' = 'One', 'Two', 'Three' - 'EmptyArray' = @() - 'SingleValueArray' = ,'one' - 'SubArray' = 'One', ('Two', 'Three'), 'Four' - 'HashTable' = @{'Name' = 'Value'} - 'Ordered' = [ordered]@{'One' = 1; 'Two' = 2; 'Three' = 3; 'Four' = 4} - 'Object' = [pscustomobject]@{'Name' = 'Value'} -} -"@ - } - - Context 'strong formatting -expand 1' { - Test-Format -Strong -Expand 1 '[int]1' - - Test-Format -Strong -Expand 1 "[string]'One'" - - # Test-Format -Strong -Expand 1 "[byte[]](1, 2, 3)" - - # Test-Format -Strong -Expand 1 @" - # [string[]]( - # 'One', - # 'Two', - # 'Three' - # ) - # "@ - - Test-Format -Strong -Expand 1 @" -[array]( - [string]'One', - [string]'Two', - [string]'Three', - [string]'Four' -) -"@ - - Test-Format -Strong -Expand 1 @" -[array]( - [string]'One', - [array][string]'Two', - [string]'Three', - [string]'Four' -) -"@ - - Test-Format -Strong -Expand 1 @" -[array]( - [string]'One', - [array]([string]'Two', [string]'Three'), - [string]'Four' -) -"@ - - Test-Format -Strong -Expand 1 @" -[array]( - [string]'One', - [hashtable]@{'Two' = [int]2}, - [string]'Three', - [string]'Four' -) -"@ - - Test-Format -Strong -Expand 1 @" -[array]( - [pscustomobject]@{'value' = [int]1}, - [pscustomobject]@{'value' = [int]2}, - [pscustomobject]@{'value' = [int]3} -) -"@ - - Test-Format -Strong -Expand 1 @" -[pscustomobject]@{ - 'One' = [int]1 - 'Two' = [int]2 - 'Three' = [int]3 - 'Four' = [int]4 -} -"@ - - Test-Format -Strong -Expand 1 @" -[array]( - [string]'One', - [ordered]@{'Two' = [int]2; 'Three' = [int]3}, - [string]'Four' -) -"@ - - Test-Format -Strong -Expand 1 "[hashtable]@{'One' = [int]1}" - - Test-Format -Strong -Expand 1 @" -[ordered]@{ - 'One' = [int]1 - 'Two' = [int]2 - 'Three' = [int]3 - 'Four' = [int]4 -} -"@ - - Test-Format -Strong -Expand 1 @" -[ordered]@{ - 'One' = [int]1 - 'Two' = [int]2 - 'Three.1' = [array][double]3.1 - 'Four' = [int]4 -} -"@ - - Test-Format -Strong -Expand 1 @" -[ordered]@{ - 'One' = [int]1 - 'Two' = [int]2 - 'Three.12' = [array]([double]3.1, [double]3.2) - 'Four' = [int]4 -} -"@ - - Test-Format -Strong -Expand 1 @" -[ordered]@{ - 'One' = [int]1 - 'Two' = [int]2 - 'Three' = [hashtable]@{'One' = [double]3.1} - 'Four' = [int]4 -} -"@ - - Test-Format -Strong -Expand 1 @" -[ordered]@{ - 'One' = [int]1 - 'Two' = [int]2 - 'Three' = [ordered]@{'One' = [double]3.1; 'Two' = [double]3.2} - 'Four' = [int]4 -} -"@ - - Test-Format -Strong -Expand 1 @" -[ordered]@{ - 'String' = [string]'String' - 'HereString' = [string]@' -Hello -World -'@ - 'Int' = [int]67 - 'Double' = [double]1.2 - 'Long' = [long]1234567890123456 - 'DateTime' = [datetime]'1963-10-07T17:56:53.8139055' - 'Version' = [version]'1.2.34567.890' - 'Guid' = [guid]'5f167621-6abe-4153-a26c-f643e1716720' - 'Script' = [scriptblock]{2 * 3} - 'Array' = [array]([string]'One', [string]'Two', [string]'Three', [string]'Four') - 'ByteArray' = [array]([int]1, [int]2, [int]3) - 'StringArray' = [array]([string]'One', [string]'Two', [string]'Three') - 'EmptyArray' = [array]@() - 'SingleValueArray' = [array][string]'one' - 'SubArray' = [array]([string]'One', [array]([string]'Two', [string]'Three'), [string]'Four') - 'HashTable' = [hashtable]@{'Name' = [string]'Value'} - 'Ordered' = [ordered]@{'One' = [int]1; 'Two' = [int]2; 'Three' = [int]3; 'Four' = [int]4} - 'Object' = [pscustomobject]@{'Name' = [string]'Value'} -} -"@ - } - - Context 'formatting -expand 0' { - Test-Format -Expand 0 '1' - - Test-Format -Expand 0 "'One'" - - Test-Format -Expand 0 '1, 2, 3' - - Test-Format -Expand 0 "'One', 'Two', 'Three'" - - Test-Format -Expand 0 "'One', 'Two', 'Three', 'Four'" - - Test-Format -Expand 0 "'One', (,'Two'), 'Three', 'Four'" - - Test-Format -Expand 0 "'One', ('Two', 'Three'), 'Four'" - - Test-Format -Expand 0 "'One', @{'Two' = 2}, 'Three', 'Four'" - - Test-Format -Expand 0 "[pscustomobject]@{'value' = 1}, [pscustomobject]@{'value' = 2}, [pscustomobject]@{'value' = 3}" - - Test-Format -Expand 0 "[pscustomobject]@{'One' = 1; 'Two' = 2; 'Three' = 3; 'Four' = 4}" - - Test-Format -Expand 0 "'One', [ordered]@{'Two' = 2; 'Three' = 3}, 'Four'" - - Test-Format -Expand 0 "@{'One' = 1}" - - Test-Format -Expand 0 "[ordered]@{'One' = 1; 'Two' = 2; 'Three' = 3; 'Four' = 4}" - - Test-Format -Expand 0 "[ordered]@{'One' = 1; 'Two' = 2; 'Three.1' = ,3.1; 'Four' = 4}" - - Test-Format -Expand 0 "[ordered]@{'One' = 1; 'Two' = 2; 'Three.12' = 3.1, 3.2; 'Four' = 4}" - - Test-Format -Expand 0 "[ordered]@{'One' = 1; 'Two' = 2; 'Three' = @{'One' = 3.1}; 'Four' = 4}" - - Test-Format -Expand 0 "[ordered]@{'One' = 1; 'Two' = 2; 'Three' = [ordered]@{'One' = 3.1; 'Two' = 3.2}; 'Four' = 4}" - - Test-Format -Expand 0 @" -[ordered]@{'String' = 'String'; 'HereString' = @' -Hello -World -'@ -; 'Int' = 67; 'Double' = 1.2; 'Long' = 1234567890123456; 'DateTime' = [datetime]'1963-10-07T17:56:53.8139055'; 'Version' = [version]'1.2.34567.890'; 'Guid' = [guid]'5f167621-6abe-4153-a26c-f643e1716720'; 'Script' = {2 * 3}; 'Array' = 'One', 'Two', 'Three', 'Four'; 'ByteArray' = 1, 2, 3; 'StringArray' = 'One', 'Two', 'Three'; 'EmptyArray' = @(); 'SingleValueArray' = ,'one'; 'SubArray' = 'One', ('Two', 'Three'), 'Four'; 'HashTable' = @{'Name' = 'Value'}; 'Ordered' = [ordered]@{'One' = 1; 'Two' = 2; 'Three' = 3; 'Four' = 4}; 'Object' = [pscustomobject]@{'Name' = 'Value'}} -"@ - } - - Context 'strong formatting -expand 0' { - Test-Format -Strong -Expand 0 '[int]1' - - Test-Format -Strong -Expand 0 "[string]'One'" - - # Test-Format -Strong -Expand 0 "[byte[]](1, 2, 3)" - - # Test-Format -Strong -Expand 0 "[string[]]('One', 'Two', 'Three')" - - Test-Format -Strong -Expand 0 "[array]([string]'One', [string]'Two', [string]'Three', [string]'Four')" - - Test-Format -Strong -Expand 0 "[array]([string]'One', [array][string]'Two', [string]'Three', [string]'Four')" - - Test-Format -Strong -Expand 0 "[array]([string]'One', [array]([string]'Two', [string]'Three'), [string]'Four')" - - Test-Format -Strong -Expand 0 "[array]([string]'One', [hashtable]@{'Two' = [int]2}, [string]'Three', [string]'Four')" - - Test-Format -Strong -Expand 0 "[array]([pscustomobject]@{'value' = [int]1}, [pscustomobject]@{'value' = [int]2}, [pscustomobject]@{'value' = [int]3})" - - Test-Format -Strong -Expand 0 "[pscustomobject]@{'One' = [int]1; 'Two' = [int]2; 'Three' = [int]3; 'Four' = [int]4}" - - Test-Format -Strong -Expand 0 "[array]([string]'One', [ordered]@{'Two' = [int]2; 'Three' = [int]3}, [string]'Four')" - - Test-Format -Strong -Expand 0 "[hashtable]@{'One' = [int]1}" - - Test-Format -Strong -Expand 0 "[ordered]@{'One' = [int]1; 'Two' = [int]2; 'Three' = [int]3; 'Four' = [int]4}" - - Test-Format -Strong -Expand 0 "[ordered]@{'One' = [int]1; 'Two' = [int]2; 'Three.1' = [array][double]3.1; 'Four' = [int]4}" - - Test-Format -Strong -Expand 0 "[ordered]@{'One' = [int]1; 'Two' = [int]2; 'Three.12' = [array]([double]3.1, [double]3.2); 'Four' = [int]4}" - - Test-Format -Strong -Expand 0 "[ordered]@{'One' = [int]1; 'Two' = [int]2; 'Three' = [hashtable]@{'One' = [double]3.1}; 'Four' = [int]4}" - - Test-Format -Strong -Expand 0 "[ordered]@{'One' = [int]1; 'Two' = [int]2; 'Three' = [ordered]@{'One' = [double]3.1; 'Two' = [double]3.2}; 'Four' = [int]4}" - - Test-Format -Strong -Expand 0 @" -[ordered]@{'String' = [string]'String'; 'HereString' = [string]@' -Hello -World -'@ -; 'Int' = [int]67; 'Double' = [double]1.2; 'Long' = [long]1234567890123456; 'DateTime' = [datetime]'1963-10-07T17:56:53.8139055'; 'Version' = [version]'1.2.34567.890'; 'Guid' = [guid]'5f167621-6abe-4153-a26c-f643e1716720'; 'Script' = [scriptblock]{2 * 3}; 'Array' = [array]([string]'One', [string]'Two', [string]'Three', [string]'Four'); 'ByteArray' = [array]([int]1, [int]2, [int]3); 'StringArray' = [array]([string]'One', [string]'Two', [string]'Three'); 'EmptyArray' = [array]@(); 'SingleValueArray' = [array][string]'one'; 'SubArray' = [array]([string]'One', [array]([string]'Two', [string]'Three'), [string]'Four'); 'HashTable' = [hashtable]@{'Name' = [string]'Value'}; 'Ordered' = [ordered]@{'One' = [int]1; 'Two' = [int]2; 'Three' = [int]3; 'Four' = [int]4}; 'Object' = [pscustomobject]@{'Name' = [string]'Value'}} -"@ - } - - Context 'formatting -expand -1 (compressed)' { - Test-Format -Expand -1 '1' - - Test-Format -Expand -1 "'One'" - - Test-Format -Expand -1 '1,2,3' - - Test-Format -Expand -1 "'One','Two','Three'" - - Test-Format -Expand -1 "'One','Two','Three','Four'" - - Test-Format -Expand -1 "'One',(,'Two'),'Three','Four'" - - Test-Format -Expand -1 "'One',('Two','Three'),'Four'" - - Test-Format -Expand -1 "'One',@{'Two'=2},'Three','Four'" - - Test-Format -Expand -1 "[pscustomobject]@{'value'=1},[pscustomobject]@{'value'=2},[pscustomobject]@{'value'=3}" - - Test-Format -Expand -1 "[pscustomobject]@{'One'=1;'Two'=2;'Three'=3;'Four'=4}" - - Test-Format -Expand -1 "'One',[ordered]@{'Two'=2;'Three'=3},'Four'" - - Test-Format -Expand -1 "@{'One'=1}" - - Test-Format -Expand -1 "[ordered]@{'One'=1;'Two'=2;'Three'=3;'Four'=4}" - - Test-Format -Expand -1 "[ordered]@{'One'=1;'Two'=2;'Three.1'=,3.1;'Four'=4}" - - Test-Format -Expand -1 "[ordered]@{'One'=1;'Two'=2;'Three.12'=3.1,3.2;'Four'=4}" - - Test-Format -Expand -1 "[ordered]@{'One'=1;'Two'=2;'Three'=@{'One'=3.1};'Four'=4}" - - Test-Format -Expand -1 "[ordered]@{'One'=1;'Two'=2;'Three'=[ordered]@{'One'=3.1;'Two'=3.2};'Four'=4}" - - Test-Format -Expand -1 @" -[ordered]@{'String'='String';'HereString'=@' -Hello -World -'@ -;'Int'=67;'Double'=1.2;'Long'=1234567890123456;'DateTime'=[datetime]'1963-10-07T17:56:53.8139055';'Version'=[version]'1.2.34567.890';'Guid'=[guid]'5f167621-6abe-4153-a26c-f643e1716720';'Script'={2 * 3};'Array'='One','Two','Three','Four';'ByteArray'=1,2,3;'StringArray'='One','Two','Three';'EmptyArray'=@();'SingleValueArray'=,'one';'SubArray'='One',('Two','Three'),'Four';'HashTable'=@{'Name'='Value'};'Ordered'=[ordered]@{'One'=1;'Two'=2;'Three'=3;'Four'=4};'Object'=[pscustomobject]@{'Name'='Value'}} -"@ - } - - Context 'strong formatting -expand -1 (compressed)' { - Test-Format -Strong -Expand -1 '[int]1' - - Test-Format -Strong -Expand -1 "[string]'One'" - - # Test-Format -Strong -Expand -1 "[byte[]](1,2,3)" - - # Test-Format -Strong -Expand -1 "[string[]]('One','Two','Three')" - - Test-Format -Strong -Expand -1 "[array]([string]'One',[string]'Two',[string]'Three',[string]'Four')" - - Test-Format -Strong -Expand -1 "[array]([string]'One',[array][string]'Two',[string]'Three',[string]'Four')" - - Test-Format -Strong -Expand -1 "[array]([string]'One',[array]([string]'Two',[string]'Three'),[string]'Four')" - - Test-Format -Strong -Expand -1 "[array]([string]'One',[hashtable]@{'Two'=[int]2},[string]'Three',[string]'Four')" - - Test-Format -Strong -Expand -1 "[array]([pscustomobject]@{'value'=[int]1},[pscustomobject]@{'value'=[int]2},[pscustomobject]@{'value'=[int]3})" - - Test-Format -Strong -Expand -1 "[pscustomobject]@{'One'=[int]1;'Two'=[int]2;'Three'=[int]3;'Four'=[int]4}" - - Test-Format -Strong -Expand -1 "[array]([string]'One',[ordered]@{'Two'=[int]2;'Three'=[int]3},[string]'Four')" - - Test-Format -Strong -Expand -1 "[hashtable]@{'One'=[int]1}" - - Test-Format -Strong -Expand -1 "[ordered]@{'One'=[int]1;'Two'=[int]2;'Three'=[int]3;'Four'=[int]4}" - - Test-Format -Strong -Expand -1 "[ordered]@{'One'=[int]1;'Two'=[int]2;'Three.1'=[array][double]3.1;'Four'=[int]4}" - - Test-Format -Strong -Expand -1 "[ordered]@{'One'=[int]1;'Two'=[int]2;'Three.12'=[array]([double]3.1,[double]3.2);'Four'=[int]4}" - - Test-Format -Strong -Expand -1 "[ordered]@{'One'=[int]1;'Two'=[int]2;'Three'=[hashtable]@{'One'=[double]3.1};'Four'=[int]4}" - - Test-Format -Strong -Expand -1 "[ordered]@{'One'=[int]1;'Two'=[int]2;'Three'=[ordered]@{'One'=[double]3.1;'Two'=[double]3.2};'Four'=[int]4}" - - Test-Format -Strong -Expand -1 @" -[ordered]@{'String'=[string]'String';'HereString'=[string]@' -Hello -World -'@ -;'Int'=[int]67;'Double'=[double]1.2;'Long'=[long]1234567890123456;'DateTime'=[datetime]'1963-10-07T17:56:53.8139055';'Version'=[version]'1.2.34567.890';'Guid'=[guid]'5f167621-6abe-4153-a26c-f643e1716720';'Script'=[scriptblock]{2 * 3};'Array'=[array]([string]'One',[string]'Two',[string]'Three',[string]'Four');'ByteArray'=[array]([int]1,[int]2,[int]3);'StringArray'=[array]([string]'One',[string]'Two',[string]'Three');'EmptyArray'=[array]@();'SingleValueArray'=[array][string]'one';'SubArray'=[array]([string]'One',[array]([string]'Two',[string]'Three'),[string]'Four');'HashTable'=[hashtable]@{'Name'=[string]'Value'};'Ordered'=[ordered]@{'One'=[int]1;'Two'=[int]2;'Three'=[int]3;'Four'=[int]4};'Object'=[pscustomobject]@{'Name'=[string]'Value'}} -"@ - } - - Context 'recursive references' { - It 'recursive hash table' { - $Object = @{ - Name = 'Tree' - Parent = @{ - Name = 'Parent' - Child = @{ - Name = 'Child' - } - } - } - $Object.Parent.Child.Parent = $Object.Parent - $Expression = $Object | ConvertTo-Expression - - $Actual = &([scriptblock]::Create($Expression)) - - $Actual.Parent.Child.Name | Should -Be $Object.Parent.Child.Name - } - - It 'recursive custom object' { - $Parent = [PSCustomObject]@{ - Name = 'Parent' - } - $Child = [PSCustomObject]@{ - Name = 'Child' - } - $Parent | Add-Member Child $Child - $Child | Add-Member Parent $Parent - - $Expression = $Parent | ConvertTo-Expression - - $Actual = &([scriptblock]::Create($Expression)) - - $Actual.Child.Parent.Name | Should -Be $Parent.Child.Parent.Name - } - } - - Context 'Credentials and SecureString' { - $Username = 'Username' - $Password = 'P@ssword1' - $SecureString = $Password | ConvertTo-SecureString -AsPlainText -Force - $Credential = New-Object -TypeName PSCredential -ArgumentList $Username, $SecureString - - It 'Default expression' { - $Expression = $Credential | ConvertTo-Expression - - $Actual = &([scriptblock]::Create($Expression)) - $Actual.UserName | Should -Be $Username - $Actual.GetNetworkCredential().password | Should -Be $Password - } - - It 'Strong expression' { - $Expression = $Credential | ConvertTo-Expression -Strong - - $Actual = &([scriptblock]::Create($Expression)) - $Actual.UserName | Should -Be $Username - $Actual.GetNetworkCredential().password | Should -Be $Password - } - } - - Context 'Bug #1 Single quote in Hashtable key' { - Test-Format "@{'ab' = 'a''b'}" - Test-Format "@{'a''b' = 'ab'}" - Test-Format "[pscustomobject]@{'ab' = 'a''b'}" - Test-Format "[pscustomobject]@{'a''b' = 'ab'}" - } - } -} From 76770f09f013bb10a224949826697e9b7391af1b Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Sat, 29 Apr 2023 17:37:23 +0200 Subject: [PATCH 04/16] Added task `InjectScriptCode` --- .build/InjectScriptCode.ps1 | 12 ++++++++++++ build.yaml | 3 +++ 2 files changed, 15 insertions(+) create mode 100644 .build/InjectScriptCode.ps1 diff --git a/.build/InjectScriptCode.ps1 b/.build/InjectScriptCode.ps1 new file mode 100644 index 0000000..12aa27e --- /dev/null +++ b/.build/InjectScriptCode.ps1 @@ -0,0 +1,12 @@ +task InjectScriptCode { + + $uri = 'https://raw.githubusercontent.com/iRon7/ConvertTo-Expression/master/ConvertTo-Expression.ps1' + $moduleFilePath = Join-Path -Path $SourcePath -ChildPath 'Modules\ConvertToExpression\ConvertToExpression.psm1' + + $functionContent = Invoke-WebRequest -Uri $uri -UseBasicParsing | Select-Object -ExpandProperty Content + $moduleFileContent = Get-Content -Path $moduleFilePath -Raw + $moduleFileContent = $moduleFileContent.Replace("'TOBEREPACED'", $functionContent) + + $moduleFileContent | Set-Content -Path $moduleFilePath -Encoding UTF8 + +} diff --git a/build.yaml b/build.yaml index f2af0cc..5cf04e3 100644 --- a/build.yaml +++ b/build.yaml @@ -30,6 +30,7 @@ BuildWorkflow: build: - Clean + - InjectScriptCode - Build_Module_ModuleBuilder - Build_NestedModules_ModuleBuilder - Create_changelog_release_output @@ -79,8 +80,10 @@ DscTest: Tag: ExcludeSourceFile: - output + - Modules/ConvertToExpression ExcludeModuleFile: - Modules/DscResource.Common + - Modules/ConvertToExpression ModuleBuildTasks: Sampler: From bdc62439cfe71591b3fe4d2f6300a12f03cc3cc6 Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Sat, 29 Apr 2023 19:05:51 +0200 Subject: [PATCH 05/16] Updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f2b069..d24c346 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ Based on [style guidelines](https://dsccommunity.org/styleguidelines/localizatio - Updated the README.md with new section and updated the links. - Renamed class files adding a prefix on each file so the task `Generate_Wiki_Content` works (reported issue https://github.com/dsccommunity/DscResource.DocGenerator/issues/132). +- Removed code of `ConvertTo-Expression` and injecting it from https://github.com/iRon7/ConvertTo-Expression. ### Removed From 83d6b6d14fe9422483fac3d94552a18388396a4c Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Sat, 29 Apr 2023 23:29:44 +0200 Subject: [PATCH 06/16] Fixing using statement --- .build/InjectScriptCode.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.build/InjectScriptCode.ps1 b/.build/InjectScriptCode.ps1 index 12aa27e..a31f3d1 100644 --- a/.build/InjectScriptCode.ps1 +++ b/.build/InjectScriptCode.ps1 @@ -4,6 +4,9 @@ task InjectScriptCode { $moduleFilePath = Join-Path -Path $SourcePath -ChildPath 'Modules\ConvertToExpression\ConvertToExpression.psm1' $functionContent = Invoke-WebRequest -Uri $uri -UseBasicParsing | Select-Object -ExpandProperty Content + $functionContent = $functionContent.Replace('using namespace System.Management.Automation', '') + $functionContent = $functionContent.Replace('PSMethod', 'System.Management.Automation.PSMethod') + $moduleFileContent = Get-Content -Path $moduleFilePath -Raw $moduleFileContent = $moduleFileContent.Replace("'TOBEREPACED'", $functionContent) From ec092143190c076f2127738c5bd9848a95b8985c Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Sat, 29 Apr 2023 23:29:55 +0200 Subject: [PATCH 07/16] Removed `FunctionsToExport` --- source/JeaDsc.psd1 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/JeaDsc.psd1 b/source/JeaDsc.psd1 index 2466bdf..861616d 100644 --- a/source/JeaDsc.psd1 +++ b/source/JeaDsc.psd1 @@ -18,9 +18,7 @@ NestedModules = @() - FunctionsToExport = @( - 'ConvertTo-Expression' - ) + FunctionsToExport = @() CmdletsToExport = @() From 9654516dc1c3f1c6f1cf3a524893c2ef3364636b Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Sat, 29 Apr 2023 23:30:07 +0200 Subject: [PATCH 08/16] Import was missing --- source/Classes/005.RoleCapabilitiesUtility.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/Classes/005.RoleCapabilitiesUtility.ps1 b/source/Classes/005.RoleCapabilitiesUtility.ps1 index f457a70..33911cb 100644 --- a/source/Classes/005.RoleCapabilitiesUtility.ps1 +++ b/source/Classes/005.RoleCapabilitiesUtility.ps1 @@ -8,6 +8,9 @@ $modulePath = Join-Path -Path $PSScriptRoot -ChildPath Modules Import-Module -Name (Join-Path -Path $modulePath -ChildPath DscResource.Common) Import-Module -Name (Join-Path -Path $modulePath -ChildPath (Join-Path -Path JeaDsc.Common -ChildPath JeaDsc.Common.psm1)) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath ConvertToExpression) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath (Join-Path -Path ConvertToExpression -ChildPath ConvertToExpression.psm1)) + $script:localizedDataRole = Get-LocalizedData -DefaultUICulture en-US -FileName 'JeaRoleCapabilities.strings.psd1' class RoleCapabilitiesUtility From d37491330a6cda52eb938455c4d56ba2d4891a4d Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Sat, 29 Apr 2023 23:35:27 +0200 Subject: [PATCH 09/16] Lowering CodeCoverageThreshold --- build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.yaml b/build.yaml index 5cf04e3..c42cd4c 100644 --- a/build.yaml +++ b/build.yaml @@ -68,7 +68,7 @@ Pester: - tests/Unit ExcludeTag: Tag: - CodeCoverageThreshold: 25 + CodeCoverageThreshold: 6 CodeCoverageOutputFile: JaCoCo_coverage.xml CodeCoverageOutputFileEncoding: ascii From 38e66cb9ceb36fad8c51a68d451fdf129e720ca0 Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Wed, 10 May 2023 15:42:48 +0200 Subject: [PATCH 10/16] Removed psm1 file and kept the folder with .gitkeep --- source/Modules/ConvertToExpression/.gitkeep | 1 + source/Modules/ConvertToExpression/ConvertToExpression.psm1 | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) create mode 100644 source/Modules/ConvertToExpression/.gitkeep delete mode 100644 source/Modules/ConvertToExpression/ConvertToExpression.psm1 diff --git a/source/Modules/ConvertToExpression/.gitkeep b/source/Modules/ConvertToExpression/.gitkeep new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/source/Modules/ConvertToExpression/.gitkeep @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source/Modules/ConvertToExpression/ConvertToExpression.psm1 b/source/Modules/ConvertToExpression/ConvertToExpression.psm1 deleted file mode 100644 index 00ac2d6..0000000 --- a/source/Modules/ConvertToExpression/ConvertToExpression.psm1 +++ /dev/null @@ -1,4 +0,0 @@ -function ConvertTo-Expression -{ - 'TOBEREPACED' -} From ad7b25db84e8c9e296e9d3febd1a2779e4b02a5f Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Wed, 10 May 2023 15:45:12 +0200 Subject: [PATCH 11/16] Added FileDownload dependency --- RequiredModules.psd1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/RequiredModules.psd1 b/RequiredModules.psd1 index b239cfb..11414f0 100644 --- a/RequiredModules.psd1 +++ b/RequiredModules.psd1 @@ -21,4 +21,10 @@ 'DscResource.AnalyzerRules' = 'latest' xDscResourceDesigner = 'latest' 'DscResource.DocGenerator' = 'latest' + + ConvertToExpression = @{ + DependencyType = 'FileDownload' + Source = 'https://raw.githubusercontent.com/iRon7/ConvertTo-Expression/93cd563fb9a1dd5b6fc9c73d6f3b95f6f2ebeca8/ConvertTo-Expression.ps1' + Target = 'source\Modules\ConvertToExpression\ConvertToExpression.psm1' + } } From 8efae21fc2ceb8322bf412878ade40fae45fc272 Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Wed, 10 May 2023 15:45:43 +0200 Subject: [PATCH 12/16] Renamed task and removed downloading code --- .build/FixConvertToExpressionContent.ps1 | 17 +++++++++++++++++ .build/InjectScriptCode.ps1 | 15 --------------- build.yaml | 2 +- 3 files changed, 18 insertions(+), 16 deletions(-) create mode 100644 .build/FixConvertToExpressionContent.ps1 delete mode 100644 .build/InjectScriptCode.ps1 diff --git a/.build/FixConvertToExpressionContent.ps1 b/.build/FixConvertToExpressionContent.ps1 new file mode 100644 index 0000000..2a93b20 --- /dev/null +++ b/.build/FixConvertToExpressionContent.ps1 @@ -0,0 +1,17 @@ +task FixConvertToExpressionContent { + + $filePath = Join-Path -Path $SourcePath -ChildPath 'Modules\ConvertToExpression\ConvertToExpression.psm1' + + $fileContent = Get-Content -Path $filePath -Raw + $fileContent = $fileContent.Replace('using namespace System.Management.Automation', '') + $fileContent = $fileContent.Replace('PSMethod', 'System.Management.Automation.PSMethod') + + if (-not $fileContent.StartsWith('function')) + { + $fileContent = $fileContent.Insert(0, "function ConvertTo-Expression {`n") + $fileContent += "'}'`n" + } + + $fileContent | Set-Content -Path $filePath -Encoding UTF8 + +} diff --git a/.build/InjectScriptCode.ps1 b/.build/InjectScriptCode.ps1 deleted file mode 100644 index a31f3d1..0000000 --- a/.build/InjectScriptCode.ps1 +++ /dev/null @@ -1,15 +0,0 @@ -task InjectScriptCode { - - $uri = 'https://raw.githubusercontent.com/iRon7/ConvertTo-Expression/master/ConvertTo-Expression.ps1' - $moduleFilePath = Join-Path -Path $SourcePath -ChildPath 'Modules\ConvertToExpression\ConvertToExpression.psm1' - - $functionContent = Invoke-WebRequest -Uri $uri -UseBasicParsing | Select-Object -ExpandProperty Content - $functionContent = $functionContent.Replace('using namespace System.Management.Automation', '') - $functionContent = $functionContent.Replace('PSMethod', 'System.Management.Automation.PSMethod') - - $moduleFileContent = Get-Content -Path $moduleFilePath -Raw - $moduleFileContent = $moduleFileContent.Replace("'TOBEREPACED'", $functionContent) - - $moduleFileContent | Set-Content -Path $moduleFilePath -Encoding UTF8 - -} diff --git a/build.yaml b/build.yaml index c42cd4c..849a94b 100644 --- a/build.yaml +++ b/build.yaml @@ -30,7 +30,7 @@ BuildWorkflow: build: - Clean - - InjectScriptCode + - FixConvertToExpressionContent - Build_Module_ModuleBuilder - Build_NestedModules_ModuleBuilder - Create_changelog_release_output From 40b37413f5b84b26237768992ce0f410292f9ffb Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Wed, 10 May 2023 16:54:22 +0200 Subject: [PATCH 13/16] PSDepend 'FileDownload' dependency only works on windows --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f8a5014..8251a5b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -25,7 +25,7 @@ stages: - job: Package_Module displayName: 'Package Module' pool: - vmImage: 'ubuntu-latest' + vmImage: 'windows-latest' steps: - pwsh: | dotnet tool install --global GitVersion.Tool From 914d2bccd74fbd8ad0e7c867f16f1660cd676284 Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Wed, 10 May 2023 17:03:56 +0200 Subject: [PATCH 14/16] PSDepend 'FileDownload' dependency does not work in PowerShell 7 --- azure-pipelines.yml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 8251a5b..9f7f80a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -27,6 +27,7 @@ stages: pool: vmImage: 'windows-latest' steps: + - pwsh: | dotnet tool install --global GitVersion.Tool $gitVersionObject = dotnet-gitversion | ConvertFrom-Json @@ -36,15 +37,17 @@ stages: } Write-Host -Object "##vso[build.updatebuildnumber]$($gitVersionObject.FullSemVer)" displayName: Calculate ModuleVersion (GitVersion) + - task: PowerShell@2 name: package displayName: 'Build & Package Module' inputs: filePath: './build.ps1' arguments: '-ResolveDependency -tasks pack' - pwsh: true + pwsh: false env: ModuleVersion: $(NuGetVersionV2) + - task: PublishPipelineArtifact@1 displayName: 'Publish Build Artifact' inputs: @@ -68,6 +71,7 @@ stages: buildType: 'current' artifactName: $(buildArtifactName) targetPath: '$(Build.SourcesDirectory)/$(buildFolderName)' + - task: PowerShell@2 name: test displayName: 'Run HQRM Test' @@ -75,6 +79,7 @@ stages: filePath: './build.ps1' arguments: '-Tasks hqrmtest' pwsh: false + - task: PublishTestResults@2 displayName: 'Publish Test Results' condition: succeededOrFailed() @@ -95,6 +100,7 @@ stages: buildType: 'current' artifactName: $(buildArtifactName) targetPath: '$(Build.SourcesDirectory)/$(buildFolderName)' + - task: PowerShell@2 name: test displayName: 'Run Unit Test' @@ -102,6 +108,7 @@ stages: filePath: './build.ps1' arguments: "-Tasks test -PesterScript 'tests/Unit'" pwsh: false + - task: PublishTestResults@2 displayName: 'Publish Test Results' condition: succeededOrFailed() @@ -109,6 +116,7 @@ stages: testResultsFormat: 'NUnit' testResultsFiles: '$(buildFolderName)/$(testResultFolderName)/NUnit*.xml' testRunTitle: 'Unit' + - task: PublishPipelineArtifact@1 displayName: 'Publish Test Artifact' inputs: @@ -128,6 +136,7 @@ stages: buildType: 'current' artifactName: $(buildArtifactName) targetPath: '$(Build.SourcesDirectory)/$(buildFolderName)' + - task: PowerShell@2 name: configureWinRM displayName: 'Configure WinRM' @@ -135,9 +144,11 @@ stages: targetType: 'inline' script: 'winrm quickconfig -quiet' pwsh: false + - powershell: | Set-Service -Name wuauserv -StartupType Manual -Verbose Start-Service -name wuauserv -Verbose + - task: PowerShell@2 name: test displayName: 'Run Integration Test' @@ -145,6 +156,7 @@ stages: filePath: './build.ps1' arguments: "-Tasks test -CodeCoverageThreshold 0 -PesterScript 'tests/Integration'" pwsh: false + - task: PublishTestResults@2 displayName: 'Publish Test Results' condition: succeededOrFailed() @@ -166,12 +178,14 @@ stages: buildType: 'current' artifactName: $(buildArtifactName) targetPath: '$(Build.SourcesDirectory)/$(buildFolderName)' + - task: DownloadPipelineArtifact@2 displayName: 'Download Test Artifact' inputs: buildType: 'current' artifactName: $(testArtifactName) targetPath: '$(Build.SourcesDirectory)/$(buildFolderName)/$(testResultFolderName)' + - task: PublishCodeCoverageResults@1 displayName: 'Publish Code Coverage to Azure DevOps' condition: succeededOrFailed() @@ -179,6 +193,7 @@ stages: codeCoverageTool: 'JaCoCo' summaryFileLocation: '$(Build.SourcesDirectory)/$(buildFolderName)/$(testResultFolderName)/JaCoCo_coverage.xml' pathToSources: '$(Build.SourcesDirectory)/$(sourceFolderName)/' + - script: | bash <(curl -s https://codecov.io/bash) -f "./$(buildFolderName)/$(testResultFolderName)/JaCoCo_coverage.xml" displayName: 'Publish Code Coverage to Codecov.io' @@ -206,6 +221,7 @@ stages: buildType: 'current' artifactName: $(buildArtifactName) targetPath: '$(Build.SourcesDirectory)/$(buildArtifactName)' + - task: PowerShell@2 name: publishRelease displayName: 'Publish Release' @@ -218,6 +234,7 @@ stages: GalleryApiToken: $(GalleryApiToken) ReleaseBranch: $(defaultBranch) MainGitBranch: $(defaultBranch) + - task: PowerShell@2 name: sendChangelogPR displayName: 'Send Changelog PR' From 23958d021fbdfa92dc447a3d29c8addb992ae56e Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Wed, 10 May 2023 17:31:49 +0200 Subject: [PATCH 15/16] Fix --- build.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.yaml b/build.yaml index 849a94b..af7a0e9 100644 --- a/build.yaml +++ b/build.yaml @@ -54,8 +54,6 @@ BuildWorkflow: - Publish_Release_To_GitHub - Publish_GitHub_Wiki_Content - - #################################################### # PESTER Configuration # #################################################### @@ -64,6 +62,7 @@ Pester: OutputFormat: NUnitXML ExcludeFromCodeCoverage: - Modules/DscResource.Common + - Modules/ConvertToExpression Script: - tests/Unit ExcludeTag: From 8ba3de7019f83c8aa4d77a963efe4728de26a7dd Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Wed, 10 May 2023 17:31:55 +0200 Subject: [PATCH 16/16] Fix --- .build/FixConvertToExpressionContent.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.build/FixConvertToExpressionContent.ps1 b/.build/FixConvertToExpressionContent.ps1 index 2a93b20..004f196 100644 --- a/.build/FixConvertToExpressionContent.ps1 +++ b/.build/FixConvertToExpressionContent.ps1 @@ -9,7 +9,7 @@ task FixConvertToExpressionContent { if (-not $fileContent.StartsWith('function')) { $fileContent = $fileContent.Insert(0, "function ConvertTo-Expression {`n") - $fileContent += "'}'`n" + $fileContent += "}`n" } $fileContent | Set-Content -Path $filePath -Encoding UTF8