Modules/Viscalyx.Common/0.2.0/Viscalyx.Common.psm1
#Region '.\prefix.ps1' -1 $script:dscResourceCommonModulePath = Join-Path -Path $PSScriptRoot -ChildPath 'Modules/DscResource.Common' Import-Module -Name $script:dscResourceCommonModulePath $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' #EndRegion '.\prefix.ps1' 5 #Region '.\Private\Get-DiffString.ps1' -1 <# .SYNOPSIS Returns the difference between two byte collections as a formatted string. .DESCRIPTION The Get-DiffString function takes two byte collections, a reference byte collection and a difference byte collection, and returns the difference between them as a formatted string. The formatted string represents the differences between the two byte collections in a human-readable format. .PARAMETER Reference Specifies the reference byte collection. This parameter is mandatory. .PARAMETER Difference Specifies the difference byte collection. This parameter is mandatory. .PARAMETER Ansi Specifies the ANSI color code to apply to the differences in the formatted string. .PARAMETER AnsiReset Specifies the ANSI color code to reset the color in the formatted string. .PARAMETER Column1Width Specifies the width of the first column in the formatted string. .PARAMETER ColumnSeparatorWidth Specifies the width of the separator between the columns in the formatted string. .OUTPUTS System.String The formatted string representing the differences between the reference and difference byte collections. .EXAMPLE $reference = [Microsoft.PowerShell.Commands.ByteCollection]::new() $difference = [Microsoft.PowerShell.Commands.ByteCollection]::new() $diffString = Get-DiffString -Reference $reference -Difference $difference Returns a formatted string representing the differences between the reference and difference byte collections. #> function Get-DiffString { [CmdletBinding()] [OutputType([System.String])] param ( [Parameter(Mandatory = $true)] [Microsoft.PowerShell.Commands.ByteCollection] $Reference, [Parameter(Mandatory = $true)] [AllowNull()] [Microsoft.PowerShell.Commands.ByteCollection] $Difference, [Parameter()] [System.String] $Ansi = '30;31m', [Parameter()] [System.String] $AnsiReset = '0m', [Parameter()] [System.Int32] $Column1Width, [Parameter()] [System.Int32] $ColumnSeparatorWidth ) if ($Column1Width -eq 0) { $Column1Width = $Reference.HexBytes.Length } if ($ColumnSeparatorWidth -eq 0) { $ColumnSeparatorWidth = 2 } $convertToDiffStringDefaultParameters = @{ Ansi = $Ansi AnsiReset = $AnsiReset } $diffIndex = 0..($Reference.Bytes.Length - 1) | Where-Object -FilterScript { $Reference.Bytes[$_] -ne @($Difference.Bytes)[$_] } $rowHexArray = -split $Reference.HexBytes $diffIndex | ForEach-Object -Process { $hexValue = $rowHexArray[$_] $rowHexArray[$_] = ConvertTo-DiffString -InputString $hexValue @convertToDiffStringDefaultParameters } $byteCollectionString = ($rowHexArray -join ' ') + (' ' * ($Column1Width - $Reference.HexBytes.Length)) $byteCollectionString += ' ' * $ColumnSeparatorWidth $byteCollectionString += $diffIndex | Get-NumericalSequence | ConvertTo-DiffString -InputString $Reference.Ascii @convertToDiffStringDefaultParameters return $byteCollectionString } #EndRegion '.\Private\Get-DiffString.ps1' 116 #Region '.\Public\ConvertTo-DiffString.ps1' -1 <# .SYNOPSIS Converts a specified portion of a string to a diff string with ANSI color codes. .DESCRIPTION The ConvertTo-DiffString function converts a specified portion of a string to a diff string with ANSI color codes. It can be used to highlight differences in text or display changes in a visually appealing way. .PARAMETER IndexObject Specifies the input object containing the start and end indices of the portion to convert. This parameter is mandatory when using pipeline input. .PARAMETER InputString Specifies the input string to convert. This parameter is mandatory when using start and end indices or when only the input string is provided. .PARAMETER StartIndex Specifies the start index of the portion to convert. This parameter is mandatory when using start and end indices. .PARAMETER EndIndex Specifies the end index of the portion to convert. This parameter is optional when using start and end indices. If not provided, only one character will be converted specified by the start index. .PARAMETER Ansi Specifies the ANSI color code to apply to the converted portion. The default value is '30;43m', which represents black text on a yellow background. .PARAMETER AnsiReset Specifies the ANSI color code to reset the color after the converted portion. The default value is '0m', which resets the color to the default. .EXAMPLE PS> ConvertTo-DiffString -InputString "Hello, world!" -StartIndex 7 -EndIndex 11 Converts the portion of the input string from index 7 to index 11 to a diff string with the default ANSI color codes. .EXAMPLE PS> @{Start = 7; End = 11 } | ConvertTo-DiffString -InputString "Hello, world!" Converts the portion of the input string from index 7 to index 11, provided through pipeline input, to a diff string with the default ANSI color codes. .NOTES This function uses ANSI escape sequences to apply color codes to the converted portion of the string. The resulting diff string can be displayed in a console or terminal that supports ANSI color codes. #> function ConvertTo-DiffString { [CmdletBinding()] param ( [Parameter(ParameterSetName = 'PipelineInput', Mandatory = $true, ValueFromPipeline = $true)] [PSCustomObject] $IndexObject, [Parameter(ParameterSetName = 'StartEndInput', Mandatory = $true)] [Parameter(ParameterSetName = 'PipelineInput', Mandatory = $true)] [Parameter(ParameterSetName = 'InputStringOnly', Mandatory = $true)] [System.String] $InputString, [Parameter(ParameterSetName = 'StartEndInput', Mandatory = $true)] [ValidateScript({ $_ -lt $InputString.Length })] [System.UInt32] $StartIndex, [Parameter(ParameterSetName = 'StartEndInput')] [ValidateScript({ $_ -lt $InputString.Length })] [Nullable[System.UInt32]] $EndIndex, [Parameter()] [System.String] $Ansi = '30;43m', [Parameter()] [System.String] $AnsiReset = '0m' ) begin { $result = @() $previousIndex = 0 $ansiSequence = "`e[$Ansi" $resetSequence = "`e[$AnsiReset" } process { switch ($PSCmdlet.ParameterSetName) { 'InputStringOnly' { $start = 0 $end = $InputString.Length - 1 } 'PipelineInput' { $start = $IndexObject.Start $end = $IndexObject.End } 'StartEndInput' { $start = $StartIndex $end = $EndIndex } } if ($null -eq $end) { $end = $start } if ($start -gt $previousIndex) { $result += $InputString.Substring($previousIndex, $start - $previousIndex) } $result += ($ansiSequence + $InputString.Substring($start, $end - $start + 1) + $resetSequence) $previousIndex = $end + 1 } end { if ($previousIndex -lt $InputString.Length) { $result += $InputString.Substring($previousIndex) } $result -join '' } } #EndRegion '.\Public\ConvertTo-DiffString.ps1' 145 #Region '.\Public\Get-NumericalSequence.ps1' -1 <# .SYNOPSIS Retrieves numerical sequences from a given set of numbers. .DESCRIPTION The Get-NumericalSequence command retrieves numerical sequences from a given set of numbers. It identifies consecutive numbers and groups them into ranges. .PARAMETER Number Specifies the number to be processed. This parameter is mandatory and can be provided via the pipeline. .OUTPUTS System.Object[] An array of PSCustomObject objects representing the numerical sequences. Each object contains the Start and End properties, indicating the start and end numbers of a sequence. .EXAMPLE Get-NumericalSequence -Number 1, 2, 3, 5, 6, 7, 10 Returns: Start End ----- --- 1 3 5 7 10 #> function Get-NumericalSequence { [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [System.Int32] $Number ) begin { $ranges = @() $start = $null $end = $null } process { if ($null -eq $start) { $start = $Number $end = $Number } elseif ($Number -eq $end + 1) { $end = $Number } else { if ($start -eq $end) { $end = $null } $ranges += [PSCustomObject] @{ Start = $start End = $end } $start = $Number $end = $Number } } end { if ($null -ne $start) { if ($start -eq $end) { $end = $null } $ranges += [PSCustomObject] @{ Start = $start End = $end } } $ranges } } #EndRegion '.\Public\Get-NumericalSequence.ps1' 93 #Region '.\Public\Out-Diff.ps1' -1 <# .SYNOPSIS Compares two sets of strings and highlights the differences in hexadecimal output. .DESCRIPTION The Out-Diff command compares two sets of strings, $Difference and $Reference. Outputs the result using hexadecimal output and highlights the differences between the two sets of strings in a side-by-side format, making it easier to spot discrepancies at a byte level. Its main intended use is in unit tests when comparing large text masses that can have small, normally invisible differences, such as an extra or missing line feed or new line character. The command supports ANSI escape sequences for coloring the differences between the actual and expected strings. The default color for differences is red. The command defaults to outputting the result as informational messages, but it also supports displaying the differences using the Write-Verbose cmdlet or returning the result as output. .PARAMETER Difference Specifies the set of strings to compare against the reference strings. This parameter is mandatory. .PARAMETER Reference Specifies the set of reference strings to compare against the difference strings. This parameter is mandatory. .PARAMETER DifferenceAnsi Specifies the ANSI escape sequence for controlling how the difference is highlighted. The default value is '30;31m' (red). .PARAMETER AnsiReset Specifies the ANSI escape sequence to reset the formatting. The default value is '0m'. .PARAMETER DiffIndicator Specifies the indicator to display when there is a differences between the strings. The default value is '!='. .PARAMETER EqualIndicator Specifies the indicator to display when there is equality between the strings. The default value is '!='. .PARAMETER AsVerbose Switch parameter. If specified, the differences are displayed using the Write-Verbose cmdlet. .PARAMETER NoHeader Switch parameter. If specified, the header message is not displayed. .PARAMETER ReferenceLabel Specifies the label for the reference strings. The default value is 'Expected:'. The label should be no longer than 65 characters. .PARAMETER DifferenceLabel Specifies the label for the difference strings. The default value is 'But was:'. The label should be no longer than 65 characters. .PARAMETER ReferenceLabelAnsi Specifies the ANSI escape sequence for controlling the look of the reference label. The default value is '4m' (underline). .PARAMETER DifferenceLabelAnsi Specifies the ANSI escape sequence for controlling the look of the difference label. The default value is '4m' (underline). .PARAMETER PassThru Switch parameter. If specified, the output is returned as an array of strings. .OUTPUTS If the PassThru parameter is specified, the function returns an array of strings representing the differences between the actual and expected strings. .EXAMPLE $actual = "Hello", "World" $expected = "Hello", "Universe" Out-Diff -Difference $actual -Reference $expected This example compares the actual strings "Hello" and "World" with the expected strings "Hello" and "Universe". The function displays the differences between the two sets of strings. #> function Out-Diff { # cSpell: ignore isnot [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [AllowEmptyCollection()] [AllowEmptyString()] [AllowNull()] [System.String[]] $Difference, [Parameter(Mandatory = $true)] [AllowEmptyCollection()] [AllowEmptyString()] [AllowNull()] [System.String[]] $Reference, [Parameter()] [System.String] $DifferenceAnsi = '30;31m', # '30;43m' or '38;5;(255);48;5;(124)m' [Parameter()] [System.String] $AnsiReset = '0m', [Parameter()] [System.String] $DiffIndicator = '!=', [Parameter()] [System.String] $EqualIndicator = '==', [Parameter()] [System.Management.Automation.SwitchParameter] $AsVerbose, [Parameter()] [System.Management.Automation.SwitchParameter] $NoHeader, [Parameter()] [ValidateScript({ $_.Length -le 65 })] [System.String] $ReferenceLabel = 'Expected:', [Parameter()] [ValidateScript({ $_.Length -le 65 })] [System.String] $DifferenceLabel = 'But was:', [Parameter()] [System.String] $ReferenceLabelAnsi = '4m', [Parameter()] [System.String] $DifferenceLabelAnsi = '4m', [Parameter()] [System.Management.Automation.SwitchParameter] $PassThru ) if ($PassThru.IsPresent) { $outDiffResult = @() } else { $outDiffResult = $null } if (-not $Difference) { $Difference = @() } if (-not $Reference) { $Reference = @() } # Using ForEach-Object to convert numerical values to string. $expectedHex = $Reference | ForEach-Object -Process { $_.ToString() } | Format-Hex $actualHex = $Difference | ForEach-Object -Process { $_.ToString() } | Format-Hex $maxLength = @($expectedHex.Length, $actualHex.Length) | Measure-Object -Maximum | Select-Object -ExpandProperty 'Maximum' $columnSeparatorWidth = 2 if ($expectedHex) { $expectedColumn1Width = ( $expectedHex.HexBytes | ForEach-Object -Process { $_.Length } | Measure-Object -Maximum ).Maximum $expectedColumn2Width = ( $expectedHex.Ascii | ForEach-Object -Process { $_.Length } | Measure-Object -Maximum ).Maximum } else { $expectedColumn1Width = 47 $expectedColumn2Width = 16 } if (@($actualHex)[0]) { $actualColumn1Width = ( $actualHex.HexBytes | ForEach-Object -Process { $_.Length } | Measure-Object -Maximum ).Maximum } else { $actualColumn1Width = 47 } if (-not $NoHeader.IsPresent) { $headerMessage = @( (ConvertTo-DiffString -InputString $ReferenceLabel -Ansi $ReferenceLabelAnsi -AnsiReset $AnsiReset) ''.PadRight((($expectedColumn1Width + $expectedColumn2Width - $ReferenceLabel.Length) + ($columnSeparatorWidth * 3) + $DiffIndicator.Length)) (ConvertTo-DiffString -InputString $DifferenceLabel -Ansi $DifferenceLabelAnsi -AnsiReset $AnsiReset) ) -join '' if ($PassThru.IsPresent) { $outDiffResult += $headerMessage } elseif ($AsVerbose.IsPresent) { Write-Verbose -Message $headerMessage -Verbose } else { Write-Information -MessageData $headerMessage -InformationAction 'Continue' } } # Remove one since we start at 0. $maxLength -= 1 foreach ($index in 0..$maxLength) { $expectedRowAscii = '' $actualRowAscii = '' if (@($expectedHex)[$index]) { $expectedRowAscii = $expectedHex[$index].Ascii } if (@($actualHex)[$index]) { $actualRowAscii = $actualHex[$index].Ascii } ## # Color mark the diff in the actual row. ## if ($actualRowAscii) { $getDiffStringParameters = @{ Reference = @($actualHex)[$index] Difference = @($expectedHex)[$index] Column1Width = $actualColumn1Width ColumnSeparatorWidth = $columnSeparatorWidth Ansi = $DifferenceAnsi AnsiReset = $AnsiReset } $actualRow = Get-DiffString @getDiffStringParameters } else { $actualRow = '' } ## # Color mark the diff in the expected row. ## if ($expectedRowAscii) { $getDiffStringParameters = @{ Reference = @($expectedHex)[$index] Difference = @($actualHex)[$index] Column1Width = $expectedColumn1Width ColumnSeparatorWidth = $columnSeparatorWidth Ansi = $DifferenceAnsi AnsiReset = $AnsiReset } $expectedRow = Get-DiffString @getDiffStringParameters } else { $expectedRow = '' } <# Calculate the difference in length between the expected row and calculated column width by removing all the ANSI escape sequences and subtracting the length from the column widths. #> $expectedRowLengthDiff = ($expectedColumn1Width + $expectedColumn2Width) - ($expectedRow -replace "`e\[[0-9;]*[a-zA-Z]").Length $expectedRow = $expectedRow.PadRight($expectedRow.Length + $expectedRowLengthDiff + $columnSeparatorWidth) if ($expectedRowAscii -cne $actualRowAscii) { $outputDiffIndicator = $DiffIndicator } else { if ($EqualIndicator) { $outputDiffIndicator = $EqualIndicator } else { $outputDiffIndicator = ' ' * $DiffIndicator.Length } } $diffRowMessage = @( $expectedRow (' ' * $columnSeparatorWidth) $outputDiffIndicator (' ' * $columnSeparatorWidth) $actualRow ) -join '' if ($PassThru.IsPresent) { $outDiffResult += $diffRowMessage } elseif ($AsVerbose.IsPresent) { Write-Verbose -Message $diffRowMessage -Verbose } else { Write-Information -MessageData $diffRowMessage -InformationAction 'Continue' } } return $outDiffResult } #EndRegion '.\Public\Out-Diff.ps1' 353 #Region '.\Public\Remove-History.ps1' -1 <# .SYNOPSIS Removes command history entries that match a specified pattern. .DESCRIPTION The Remove-History function removes command history entries that match a specified pattern. It removes both the history entries stored by the PSReadLine module and the history entries stored by the PowerShell session. .PARAMETER Pattern Specifies the pattern to match against the command history entries. Only the entries that match the pattern will be removed. .PARAMETER EscapeRegularExpression Indicates that the pattern should be treated as a literal string. If this switch parameter is specified, the pattern will not be treated as a regular expression. .INPUTS None. You cannot pipe input to this function. .OUTPUTS None. The function does not generate any output. .EXAMPLE Remove-History -Pattern ".*\.txt" This example removes all command history entries that end with the ".txt" extension, using a regular expression pattern. .EXAMPLE Remove-History -Pattern './build.ps1' -EscapeRegularExpression This example removes all command history entries that contain the string "./build.ps1". #> function Remove-History { [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '', Justification = 'Because ShouldProcess is handled in the commands it calls')] [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] param ( [Parameter(Mandatory = $true, Position = 0)] [System.String] $Pattern, [Parameter()] [System.Management.Automation.SwitchParameter] $EscapeRegularExpression ) Remove-PSReadLineHistory @PSBoundParameters Remove-PSHistory @PSBoundParameters } #EndRegion '.\Public\Remove-History.ps1' 55 #Region '.\Public\Remove-PSHistory.ps1' -1 <# .SYNOPSIS Removes PowerShell history content matching a specified pattern. .DESCRIPTION The Remove-PSHistory function removes PowerShell history content that matches a specified pattern. .PARAMETER Pattern Specifies the pattern to match against the command history entries. Only the entries that match the pattern will be removed. .PARAMETER EscapeRegularExpression Indicates that the pattern should be treated as a literal string. If this switch parameter is specified, the pattern will not be treated as a regular expression. .EXAMPLE Remove-PSHistory -Pattern ".*\.txt" This example removes all command history entries that end with the ".txt" extension, using a regular expression pattern. .EXAMPLE Remove-PSHistory -Pattern './build.ps1' -EscapeRegularExpression This example removes all command history entries that contain the string "./build.ps1". .INPUTS None. You cannot pipe input to this function. .OUTPUTS None. The function does not generate any output. #> function Remove-PSHistory { [CmdletBinding(SupportsShouldProcess = $true , ConfirmImpact = 'High')] param ( [Parameter(Mandatory = $true, Position = 0)] [System.String] $Pattern, [Parameter()] [System.Management.Automation.SwitchParameter] $EscapeRegularExpression ) if ($EscapeRegularExpression.IsPresent) { $Pattern = [System.Text.RegularExpressions.Regex]::Escape($Pattern) } $historyContent = Get-History $matchingLines = $historyContent | Where-Object -FilterScript { $_.CommandLine -match $Pattern } if ($matchingLines) { $matchingLines | Write-Verbose -Verbose $shouldProcessVerboseDescription = 'Removing content matching the pattern ''{0}''.' -f $Pattern $shouldProcessVerboseWarning = 'Are you sure you want to remove the content matching the pattern ''{0}'' from PowerShell history?' -f $Pattern # This string shall not end with full stop (.) since it is used as a title of ShouldProcess messages. $shouldProcessCaption = 'Remove content matching the pattern from PowerShell history' if ($PSCmdlet.ShouldProcess($shouldProcessVerboseDescription, $shouldProcessVerboseWarning, $shouldProcessCaption)) { $matchingLines | ForEach-Object -Process { Clear-History -Id $_.Id } Write-Information -MessageData 'Removed PowerShell history content matching the pattern.' -InformationAction Continue } } else { Write-Information -MessageData 'No PowerShell history content matching the pattern.' -InformationAction Continue } } #EndRegion '.\Public\Remove-PSHistory.ps1' 86 #Region '.\Public\Remove-PSReadLineHistory.ps1' -1 <# .SYNOPSIS Removes content from the PSReadLine history that matches a specified pattern. .DESCRIPTION The Remove-PSReadLineHistory function removes content from the PSReadLine history that matches a specified pattern. .PARAMETER Pattern Specifies the pattern to match against the command history entries. Only the entries that match the pattern will be removed. .PARAMETER EscapeRegularExpression Indicates that the pattern should be treated as a literal string. If this switch parameter is specified, the pattern will not be treated as a regular expression. .NOTES - This command requires the PSReadLine module to be installed. - The PSReadLine history is stored in a file specified by the HistorySavePath property of the PSReadLineOption object. .EXAMPLE Remove-PSReadLineHistory -Pattern ".*\.txt" This example removes all command history entries that end with the ".txt" extension, using a regular expression pattern. .EXAMPLE Remove-PSReadLineHistory -Pattern './build.ps1' -EscapeRegularExpression This example removes all command history entries that contain the string "./build.ps1". .INPUTS None. You cannot pipe input to this function. .OUTPUTS None. The function does not generate any output. #> function Remove-PSReadLineHistory { [CmdletBinding(SupportsShouldProcess = $true , ConfirmImpact = 'High')] param ( [Parameter(Mandatory = $true, Position = 0)] [System.String] $Pattern, [Parameter()] [System.Management.Automation.SwitchParameter] $EscapeRegularExpression ) if ($EscapeRegularExpression.IsPresent) { $Pattern = [System.Text.RegularExpressions.Regex]::Escape($Pattern) } $historyPath = (Get-PSReadLineOption).HistorySavePath $historyContent = Get-Content -Path $historyPath # Do not match the last line as it is the line that called the function. $matchingContent = $historyContent | Select-Object -SkipLast 1 | Select-String -Pattern $Pattern if ($matchingContent) { $matchingContent | Write-Verbose -Verbose $shouldProcessVerboseDescription = 'Removing content matching the pattern ''{0}''.' -f $Pattern $shouldProcessVerboseWarning = 'Are you sure you want to remove the content matching the pattern ''{0}'' from PSReadLine history?' -f $Pattern # This string shall not end with full stop (.) since it is used as a title of ShouldProcess messages. $shouldProcessCaption = 'Remove content matching the pattern from PSReadLine history' if ($PSCmdlet.ShouldProcess($shouldProcessVerboseDescription, $shouldProcessVerboseWarning, $shouldProcessCaption)) { Set-Content -Path $historyPath -Value ( $historyContent | Select-String -NotMatch $Pattern ).Line Write-Information -MessageData 'Removed PSReadLine history content matching the pattern.' -InformationAction Continue } } else { Write-Information -MessageData 'No PSReadLine history content matching the pattern.' -InformationAction Continue } } #EndRegion '.\Public\Remove-PSReadLineHistory.ps1' 94 #Region '.\Public\Split-StringAtIndex.ps1' -1 <# .SYNOPSIS Splits a string at a specified index or range of indices. .DESCRIPTION The Split-StringAtIndex function splits a given string at a specified index or range of indices. It can be used to extract substrings from a larger string based on the provided indices. .PARAMETER IndexObject Specifies the index object to split the string. This parameter is used when providing input via the pipeline. .PARAMETER InputString Specifies the input string to be split. .PARAMETER StartIndex Specifies the starting index of the substring to be extracted. The value must be less than the length of the input string. .PARAMETER EndIndex Specifies the ending index of the substring to be extracted. The value must be less than the length of the input string. .EXAMPLE PS> Split-StringAtIndex -InputString "Hello, World!" -StartIndex 0 -EndIndex 4 This example splits the input string "Hello, World!" at the index specified by StartIndex and then at the index specified by EndIndex and returns the resulting array of substrings. .EXAMPLE PS> @(@{Start = 0; End = 2}, @{Start = 7; End = 11 }) | Split-StringAtIndex -InputString "Hello, world!" This example splits the input string "Hello, World!" at the indices provided by the pipeline. It will split the string at each StartIndex and EndIndex and returns the resulting array of substrings. .EXAMPLE PS> @(0, 1, 2, 7, 8, 9, 10, 11) | Get-NumericalSequence | Split-StringAtIndex -InputString "Hello, world!" This example splits the input string "Hello, World!" at the indices provided by the pipeline. It will split the string at each StartIndex and EndIndex and returns the resulting array of substrings. .OUTPUTS System.String[] An array of substrings extracted from the input string. .NOTES The Split-StringAtIndex function is designed to split strings based on indices and can be used in various scenarios where string manipulation is required. To get the indices the function Get-NumericalSequence can be used. #> function Split-StringAtIndex { [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('UseSyntacticallyCorrectExamples', '', Justification = 'Because the examples are syntactically correct. The rule does not seem to understand that there is pipeline input.')] [CmdletBinding()] [OutputType([System.String])] param ( [Parameter(ParameterSetName = 'PipelineInput', Mandatory = $true, ValueFromPipeline = $true)] [PSCustomObject] $IndexObject, [Parameter(ParameterSetName = 'StartEndInput', Mandatory = $true)] [Parameter(ParameterSetName = 'PipelineInput', Mandatory = $true)] [System.String] $InputString, [Parameter(ParameterSetName = 'StartEndInput', Mandatory = $true)] [ValidateScript({ $_ -lt $InputString.Length })] [System.UInt32] $StartIndex, [Parameter(ParameterSetName = 'StartEndInput', Mandatory = $true)] [ValidateScript({ $_ -lt $InputString.Length })] [System.UInt32] $EndIndex ) begin { $result = @() $previousIndex = 0 } process { switch ($PSCmdlet.ParameterSetName) { 'PipelineInput' { $start = $IndexObject.Start $end = $IndexObject.End } 'StartEndInput' { $start = $StartIndex $end = $EndIndex } } if ($null -eq $end) { $end = $start } if ($start -gt $previousIndex) { $result += $InputString.Substring($previousIndex, $start - $previousIndex) } $result += $InputString.Substring($start, $end - $start + 1) $previousIndex = $end + 1 } end { if ($previousIndex -lt $InputString.Length) { $result += $InputString.Substring($previousIndex) } $result } } #EndRegion '.\Public\Split-StringAtIndex.ps1' 131 |