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 '.\Public\ConvertTo-AnsiSequence.ps1' -1 <# .SYNOPSIS Converts a string value to an ANSI escape sequence. .DESCRIPTION The ConvertTo-AnsiSequence command converts a string value to an ANSI escape sequence. It is used to format text with ANSI escape codes for color and formatting in console output. .PARAMETER Value The string value to be converted to an ANSI escape sequence. .INPUTS System.String .OUTPUTS System.String .EXAMPLE ConvertTo-AnsiSequence -Value "31" This example converts the string value "31" to its ANSI escape sequence. .NOTES This function supports ANSI escape codes for color and formatting. It checks if the input string matches the pattern of an ANSI escape sequence and converts it accordingly. If the input string does not match the pattern, it is returned as is. #> function ConvertTo-AnsiSequence { [CmdletBinding()] [OutputType([System.String])] param ( [Parameter(Mandatory = $true, Position = 0)] [AllowEmptyString()] [AllowNull()] [System.String] $Value ) if ($Value) { if ($Value -match "^(?:`e)?\[?([0-9;]+)m?$") { $Value = "`e[" + $Matches[1] + 'm' } } return $Value } #EndRegion '.\Public\ConvertTo-AnsiSequence.ps1' 53 #Region '.\Public\ConvertTo-DifferenceString.ps1' -1 <# .SYNOPSIS Converts two strings into a difference string, highlighting the differences between them. .DESCRIPTION The ConvertTo-DifferenceString command takes two strings, a reference string and a difference string, and converts them into a difference string that highlights the differences between the two strings. The function compares the byte values of each character in the strings and outputs the differences in a formatted manner. It supports customizing the indicators, labels, colors, and encoding type. .PARAMETER ReferenceString Specifies the reference string to compare against. .PARAMETER DifferenceString Specifies the difference string to compare. .PARAMETER EqualIndicator Specifies the indicator to use for equal bytes. Default is '=='. .PARAMETER NotEqualIndicator Specifies the indicator to use for not equal bytes. Default is '!='. .PARAMETER HighlightStart Specifies the ANSI escape sequence to start highlighting. Default is "[31m" (red color). .PARAMETER HighlightEnd Specifies the ANSI escape sequence to end highlighting. Default is "[0m" (reset color). .PARAMETER ReferenceLabel Specifies the label for the reference string. Default is 'Expected:'. .PARAMETER DifferenceLabel Specifies the label for the difference string. Default is 'But was:'. .PARAMETER NoColumnHeader Specifies whether to exclude the column header from the output. .PARAMETER NoLabels Specifies whether to exclude the labels from the output. .PARAMETER ReferenceLabelAnsi Specifies the ANSI escape sequence to apply to the reference label. .PARAMETER DifferenceLabelAnsi Specifies the ANSI escape sequence to apply to the difference label. .PARAMETER ColumnHeaderAnsi Specifies the ANSI escape sequence to apply to the column header. .PARAMETER ColumnHeaderResetAnsi Specifies the ANSI escape sequence to reset the column header. .PARAMETER EncodingType Specifies the encoding type to use for converting the strings to byte arrays. Default is 'UTF8'. .EXAMPLE PS> ConvertTo-DifferenceString -ReferenceString 'Hello' -DifferenceString 'Hallo' Expected: But was: ---------------------------------------------------------------- -------------------------------------------------------- Bytes Ascii Bytes Ascii ----- ----- ----- ----- 48 65 6C 6C 6F Hello == 48 61 6C 6C 6F Hallo Converts the reference string 'Hello' and the difference string 'Hallo' into a difference string, highlighting the differences. .INPUTS None. .OUTPUTS System.String. #> function ConvertTo-DifferenceString { [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseBOMForUnicodeEncodedFile', '', Justification = 'This file is not intended to be saved as a Unicode-encoded file even though it has unicode characters, if that is a problem that can be re-evaluated.')] [CmdletBinding()] [OutputType([System.String])] param ( [Parameter(Mandatory = $true)] [AllowEmptyString()] [System.String] $ReferenceString, [Parameter(Mandatory = $true)] [AllowEmptyString()] [System.String] $DifferenceString, [Parameter()] [ValidateLength(0, 2)] [System.String] $EqualIndicator = '==', [Parameter()] [ValidateLength(0, 2)] [System.String] $NotEqualIndicator = '!=', [Parameter()] [System.String] $HighlightStart = '[31m', # Default to red color [Parameter()] [System.String] $HighlightEnd = '[0m', # Default to reset color [Parameter()] [System.String] $ReferenceLabel = 'Expected:', [Parameter()] [System.String] $DifferenceLabel = 'But was:', [Parameter()] [System.Management.Automation.SwitchParameter] $NoColumnHeader, [Parameter()] [System.Management.Automation.SwitchParameter] $NoLabels, [Parameter()] [System.String] $ReferenceLabelAnsi = '', [Parameter()] [System.String] $DifferenceLabelAnsi = '', [Parameter()] [System.String] $ColumnHeaderAnsi = '', [Parameter()] [System.String] $ColumnHeaderResetAnsi = '', [Parameter()] [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7', 'UTF8')] [System.String] $EncodingType = 'UTF8' ) $HighlightStart = ConvertTo-AnsiSequence -Value $HighlightStart $HighlightEnd = ConvertTo-AnsiSequence -Value $HighlightEnd $ReferenceLabelAnsi = ConvertTo-AnsiSequence -Value $ReferenceLabelAnsi $DifferenceLabelAnsi = ConvertTo-AnsiSequence -Value $DifferenceLabelAnsi $ColumnHeaderAnsi = ConvertTo-AnsiSequence -Value $ColumnHeaderAnsi $ColumnHeaderResetAnsi = ConvertTo-AnsiSequence -Value $ColumnHeaderResetAnsi # Handle empty string or single character indicator $NotEqualIndicator = $NotEqualIndicator.PadRight(2) $EqualIndicator = $EqualIndicator.PadRight(2) # Convert the strings to byte arrays using the specified encoding $referenceBytes = ([System.Text.Encoding]::$EncodingType).GetBytes($ReferenceString) $differenceBytes = ([System.Text.Encoding]::$EncodingType).GetBytes($DifferenceString) # Determine the maximum length of the two byte arrays $maxLength = [Math]::Max($referenceBytes.Length, $differenceBytes.Length) # Initialize arrays to hold hex values and characters $refHexArray = @() $refCharArray = @() $diffHexArray = @() $diffCharArray = @() # Escape $HighlightStart and $HighlightEnd for regex matching $escapedHighlightStart = [regex]::Escape($HighlightStart) $escapedHighlightEnd = [regex]::Escape($HighlightEnd) # Output the labels if NoLabels is not specified if (-not $NoLabels) { "$($ReferenceLabelAnsi)$($ReferenceLabel)$($HighlightEnd) $($DifferenceLabelAnsi)$($DifferenceLabel)$($HighlightEnd)" ('-' * 64) + (' ' * 8) + ('-' * 64) # Output a line of dashes under the labels } # Output the column header once with dashes underline if NoColumnHeader is not specified if (-not $NoColumnHeader) { "$($ColumnHeaderAnsi)Bytes Ascii Bytes Ascii$($ColumnHeaderResetAnsi)" "$($ColumnHeaderAnsi)----- ----- ----- -----$($ColumnHeaderResetAnsi)" } # Loop through each byte in the arrays up to the maximum length for ($i = 0; $i -lt $maxLength; $i++) { # Get the byte and character for the reference string if ($i -lt $referenceBytes.Length) { $refByte = $referenceBytes[$i] $refHex = '{0:X2}' -f $refByte $refChar = [char]$refByte } else { $refHex = ' ' $refChar = ' ' } # Get the byte and character for the difference string if ($i -lt $differenceBytes.Length) { $diffByte = $differenceBytes[$i] $diffHex = '{0:X2}' -f $diffByte $diffChar = [char]$diffByte } else { $diffHex = ' ' $diffChar = ' ' } # Highlight differences if ($refHex -ne $diffHex) { $refHex = "$($HighlightStart)$refHex$($HighlightEnd)" $refChar = "$($HighlightStart)$refChar$($HighlightEnd)" $diffHex = "$($HighlightStart)$diffHex$($HighlightEnd)" $diffChar = "$($HighlightStart)$diffChar$($HighlightEnd)" } # Replace control characters with their Unicode representations in the output $refChar = $refChar` -replace "`0", '␀' ` -replace "`a", '␇' ` -replace "`b", '␈' ` -replace "`t", '␉' ` -replace "`f", '␌' ` -replace "`r", '␍' ` -replace "`n", '␊' ` -replace "(?!$($escapedHighlightStart))(?!$($escapedHighlightEnd))`e", '␛' $diffChar = $diffChar ` -replace "`0", '␀' ` -replace "`a", '␇' ` -replace "`b", '␈' ` -replace "`t", '␉' ` -replace "`f", '␌' ` -replace "`r", '␍' ` -replace "`n", '␊' ` -replace "(?!$($escapedHighlightStart))(?!$($escapedHighlightEnd))`e", '␛' # Add to arrays $refHexArray += $refHex $refCharArray += $refChar $diffHexArray += $diffHex $diffCharArray += $diffChar # Output the results in groups of 16 if (($i + 1) % 16 -eq 0 -or $i -eq $maxLength - 1) { # Pad arrays to ensure they have 16 elements while ($refHexArray.Count -lt 16) { $refHexArray += ' ' } while ($refCharArray.Count -lt 16) { $refCharArray += ' ' } while ($diffHexArray.Count -lt 16) { $diffHexArray += ' ' } while ($diffCharArray.Count -lt 16) { $diffCharArray += ' ' } $refHexLine = ($refHexArray -join ' ') $refCharLine = ($refCharArray -join '') $diffHexLine = ($diffHexArray -join ' ') $diffCharLine = ($diffCharArray -join '') # Determine if the line was highlighted $indicator = if ($refHexLine -match $escapedHighlightStart -or $diffHexLine -match $escapedHighlightStart) { $NotEqualIndicator } else { $EqualIndicator } # Output the results in the specified format '{0} {1} {2} {3} {4}' -f $refHexLine, $refCharLine, $indicator, $diffHexLine, $diffCharLine # Clear arrays for the next group of 16 $refHexArray = @() $refCharArray = @() $diffHexArray = @() $diffCharArray = @() } } } #EndRegion '.\Public\ConvertTo-DifferenceString.ps1' 307 #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\Get-PSReadLineHistory.ps1' -1 <# .SYNOPSIS Retrieves the PSReadLine history content. .DESCRIPTION The Get-PSReadLineHistory function retrieves the content of the PSReadLine history file. By default, it returns the entire history content, but you can specify a pattern to filter the results. .PARAMETER Pattern Specifies a pattern to filter the history content. Only lines matching the pattern will be returned. .EXAMPLE Get-PSReadLineHistory Returns the entire content of the PSReadLine history file. .EXAMPLE Get-PSReadLineHistory -Pattern "git" Returns only the lines from the PSReadLine history file that contain the word "git". .INPUTS None .OUTPUTS System.String .NOTES This function requires the PSReadLine module to be installed. .LINK https://docs.microsoft.com/en-us/powershell/module/psreadline/ #> function Get-PSReadLineHistory { [CmdletBinding()] param ( [Parameter(Position = 0)] [System.String] $Pattern ) $historyPath = (Get-PSReadLineOption).HistorySavePath $historyContent = Get-Content -Path $historyPath if ($Pattern) { $historyContent = $historyContent | Select-Object -SkipLast 1 | Select-String -Pattern $Pattern -Raw } $historyContent } #EndRegion '.\Public\Get-PSReadLineHistory.ps1' 59 #Region '.\Public\New-SamplerGitHubReleaseTag.ps1' -1 <# .SYNOPSIS Creates a new GitHub release tag for the Sampler project. .DESCRIPTION The New-SamplerGitHubReleaseTag function creates a new release tag for the Sampler project on GitHub. It performs the following steps: 1. Checks if the remote specified in $UpstreamRemoteName exists locally and throws an error if it doesn't. 2. Fetches the $DefaultBranchName branch from the $UpstreamRemoteName remote and throws an error if it doesn't exist. 3. Checks out the $DefaultBranchName branch. 4. Fetches the $DefaultBranchName branch from the $UpstreamRemoteName remote. 5. Rebases the local $DefaultBranchName branch with the $UpstreamRemoteName/$DefaultBranchName branch. 6. Gets the last commit ID of the $DefaultBranchName branch. 7. Fetches tags from the $UpstreamRemoteName remote. 8. If no release tag is specified, it checks if there are any tags in the local repository and selects the latest preview tag. 9. Creates a new tag with the specified release tag or based on the latest preview tag. 10. Optionally pushes the tag to the $UpstreamRemoteName remote. 11. Switches back to the previous branch if requested. .PARAMETER DefaultBranchName Specifies the name of the default branch. Default value is 'main'. .PARAMETER UpstreamRemoteName Specifies the name of the upstream remote. Default value is 'origin'. .PARAMETER ReleaseTag Specifies the release tag to create. Must be in the format 'vX.X.X'. If not specified, the latest preview tag will be used. .PARAMETER SwitchBackToPreviousBranch Specifies that the command should switches back to the previous branch after creating the release tag. .PARAMETER Force Specifies that the command should run without prompting for confirmation. .PARAMETER PushTag Specifies that the tag should also be pushed to the upstream remote after creating it. This will always ask for confirmation before pushing the tag, unless Force is also specified. .EXAMPLE New-SamplerGitHubReleaseTag -ReleaseTag 'v1.0.0' -PushTag Creates a new release tag with the specified tag 'v1.0.0' and pushes it to the 'origin' remote. .EXAMPLE New-SamplerGitHubReleaseTag -SwitchBackToPreviousBranch Creates a new release tag and switches back to the previous branch. .NOTES This function requires Git to be installed and accessible from the command line. #> function New-SamplerGitHubReleaseTag { [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] param ( [Parameter()] [System.String] $DefaultBranchName = 'main', [Parameter()] [System.String] $UpstreamRemoteName = 'origin', [Parameter()] [System.String] [ValidatePattern('^v\d+\.\d+\.\d+$')] $ReleaseTag, [Parameter()] [System.Management.Automation.SwitchParameter] $SwitchBackToPreviousBranch, [Parameter()] [System.Management.Automation.SwitchParameter] $Force, [Parameter()] [System.Management.Automation.SwitchParameter] $PushTag ) if ($Force.IsPresent -and -not $Confirm) { $ConfirmPreference = 'None' } # Check if the remote specified in $UpstreamRemoteName exists locally and throw an error if it doesn't. $remoteExists = git remote | Where-Object -FilterScript { $_ -eq $UpstreamRemoteName } if (-not $remoteExists) { $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( ($script:localizedData.New_SamplerGitHubReleaseTag_RemoteMissing -f $UpstreamRemoteName), 'NSGRT0001', # cspell: disable-line [System.Management.Automation.ErrorCategory]::ObjectNotFound, $DatabaseName ) ) } $verboseDescriptionMessage = $script:localizedData.New_SamplerGitHubReleaseTag_FetchUpstream_ShouldProcessVerboseDescription -f $DefaultBranchName, $UpstreamRemoteName $verboseWarningMessage = $script:localizedData.New_SamplerGitHubReleaseTag_FetchUpstream_ShouldProcessVerboseWarning -f $DefaultBranchName, $UpstreamRemoteName $captionMessage = $script:localizedData.New_SamplerGitHubReleaseTag_FetchUpstream_ShouldProcessCaption if ($PSCmdlet.ShouldProcess($verboseDescriptionMessage, $verboseWarningMessage, $captionMessage)) { # Fetch $DefaultBranchName from upstream and throw an error if it doesn't exist. git fetch $UpstreamRemoteName $DefaultBranchName if ($LASTEXITCODE -ne 0) # cSpell: ignore LASTEXITCODE { $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( ($script:localizedData.New_SamplerGitHubReleaseTag_FailedFetchBranchFromRemote -f $DefaultBranchName, $UpstreamRemoteName), 'NSGRT0002', # cspell: disable-line [System.Management.Automation.ErrorCategory]::InvalidOperation, $DatabaseName ) ) } } if ($SwitchBackToPreviousBranch.IsPresent) { $currentLocalBranchName = git rev-parse --abbrev-ref HEAD if ($LASTEXITCODE -ne 0) { $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( $script:localizedData.New_SamplerGitHubReleaseTag_FailedGetLocalBranchName, 'NSGRT0003', # cspell: disable-line [System.Management.Automation.ErrorCategory]::InvalidOperation, $DatabaseName ) ) } } $continueProcessing = $true $errorMessage = $null $verboseDescriptionMessage = $script:localizedData.New_SamplerGitHubReleaseTag_Rebase_ShouldProcessVerboseDescription -f $DefaultBranchName, $UpstreamRemoteName $verboseWarningMessage = $script:localizedData.New_SamplerGitHubReleaseTag_Rebase_ShouldProcessVerboseWarning -f $DefaultBranchName $captionMessage = $script:localizedData.New_SamplerGitHubReleaseTag_Rebase_ShouldProcessCaption if ($PSCmdlet.ShouldProcess($verboseDescriptionMessage, $verboseWarningMessage, $captionMessage)) { git checkout $DefaultBranchName if ($LASTEXITCODE -ne 0) { $continueProcessing = $false $errorMessage = $script:localizedData.New_SamplerGitHubReleaseTag_FailedCheckoutLocalBranch -f $DefaultBranchName $errorCode = 'NSGRT0004' # cspell: disable-line } $switchedToDefaultBranch = $true if ($continueProcessing) { git rebase $UpstreamRemoteName/$DefaultBranchName if ($LASTEXITCODE -ne 0) { $continueProcessing = $false $errorMessage = $script:localizedData.New_SamplerGitHubReleaseTag_FailedRebaseLocalDefaultBranch -f $DefaultBranchName, $UpstreamRemoteName $errorCode = 'NSGRT0005' # cspell: disable-line } if ($continueProcessing) { $headCommitId = git rev-parse HEAD if ($LASTEXITCODE -ne 0) { $continueProcessing = $false $errorMessage = $script:localizedData.New_SamplerGitHubReleaseTag_FailedGetLastCommitId -f $DefaultBranchName $errorCode = 'NSGRT0006' # cspell: disable-line } } } if (-not $continueProcessing) { # If something failed, revert back to the previous branch if requested. if ($SwitchBackToPreviousBranch.IsPresent -and $switchedToDefaultBranch) { git checkout $currentLocalBranchName } $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( $errorMessage, $errorCode, # cspell: disable-line [System.Management.Automation.ErrorCategory]::InvalidOperation, $DatabaseName ) ) } } $verboseDescriptionMessage = $script:localizedData.New_SamplerGitHubReleaseTag_UpstreamTags_ShouldProcessVerboseDescription -f $UpstreamRemoteName $verboseWarningMessage = $script:localizedData.New_SamplerGitHubReleaseTag_UpstreamTags_ShouldProcessVerboseWarning -f $UpstreamRemoteName $captionMessage = $script:localizedData.New_SamplerGitHubReleaseTag_UpstreamTags_ShouldProcessCaption if ($PSCmdlet.ShouldProcess($verboseDescriptionMessage, $verboseWarningMessage, $captionMessage)) { git fetch $UpstreamRemoteName --tags if ($LASTEXITCODE -ne 0) { if ($SwitchBackToPreviousBranch.IsPresent -and $switchedToDefaultBranch) { git checkout $currentLocalBranchName } $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( ($script:localizedData.New_SamplerGitHubReleaseTag_FailedFetchTagsFromUpstreamRemote -f $UpstreamRemoteName), 'NSGRT0007', # cspell: disable-line [System.Management.Automation.ErrorCategory]::InvalidOperation, $DatabaseName ) ) } } if (-not $ReleaseTag) { $tagExist = git tag | Select-Object -First 1 if ($LASTEXITCODE -ne 0 -or -not $tagExist) { $continueProcessing = $false $errorMessage = $script:localizedData.New_SamplerGitHubReleaseTag_FailedGetTagsOrMissingTagsInLocalRepository $errorCode = 'NSGRT0008' # cspell: disable-line } if ($continueProcessing) { $latestPreviewTag = git describe --tags --abbrev=0 if ($LASTEXITCODE -ne 0) { $continueProcessing = $false $errorMessage = $script:localizedData.New_SamplerGitHubReleaseTag_FailedDescribeTags $errorCode = 'NSGRT0009' # cspell: disable-line } if ($continueProcessing) { $isCorrectlyFormattedPreviewTag = $latestPreviewTag -match '^(v\d+\.\d+\.\d+)-.*' if ($isCorrectlyFormattedPreviewTag) { $ReleaseTag = $matches[1] } else { $continueProcessing = $false $errorMessage = $script:localizedData.New_SamplerGitHubReleaseTag_LatestTagIsNotPreview -f $latestPreviewTag $errorCode = 'NSGRT0010' # cspell: disable-line } } } if (-not $continueProcessing) { if ($SwitchBackToPreviousBranch.IsPresent -and $switchedToDefaultBranch) { git checkout $currentLocalBranchName } $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( $errorMessage, $errorCode, # cspell: disable-line [System.Management.Automation.ErrorCategory]::InvalidOperation, $DatabaseName ) ) } } if ($WhatIfPreference) { $messageShouldProcess = $script:localizedData.New_SamplerGitHubReleaseTag_NewTagWhatIf_ShouldProcessVerboseDescription } else { $messageShouldProcess = $script:localizedData.New_SamplerGitHubReleaseTag_NewTag_ShouldProcessVerboseDescription } $verboseDescriptionMessage = $messageShouldProcess -f $ReleaseTag, $DefaultBranchName, $headCommitId $verboseWarningMessage = $script:localizedData.New_SamplerGitHubReleaseTag_NewTag_ShouldProcessVerboseWarning -f $ReleaseTag $captionMessage = $script:localizedData.New_SamplerGitHubReleaseTag_NewTag_ShouldProcessCaption if ($PSCmdlet.ShouldProcess($verboseDescriptionMessage, $verboseWarningMessage, $captionMessage)) { git tag $ReleaseTag if ($PushTag -and ($Force -or $PSCmdlet.ShouldContinue(('Do you want to push the tags to the upstream ''{0}''?' -f $UpstreamRemoteName), 'Confirm'))) { git push origin --tags Write-Information -MessageData ("`e[32mTag `e[1;37;44m{0}`e[0m`e[32m was created and pushed to upstream '{1}'`e[0m" -f $ReleaseTag, $UpstreamRemoteName) -InformationAction Continue } else { # cSpell: disable-next-line Write-Information -MessageData ("`e[32mTag `e[1;37;44m{0}`e[0m`e[32m was created. To push the tag to upstream, run `e[1;37;44mgit push {1} --tags`e[0m`e[32m.`e[0m" -f $ReleaseTag, $UpstreamRemoteName) -InformationAction Continue } } if ($SwitchBackToPreviousBranch.IsPresent) { $verboseDescriptionMessage = $script:localizedData.New_SamplerGitHubReleaseTag_SwitchBack_ShouldProcessVerboseDescription -f $currentLocalBranchName $verboseWarningMessage = $script:localizedData.New_SamplerGitHubReleaseTag_SwitchBack_ShouldProcessVerboseWarning -f $currentLocalBranchName $captionMessage = $script:localizedData.New_SamplerGitHubReleaseTag_SwitchBack_ShouldProcessCaption if ($PSCmdlet.ShouldProcess($verboseDescriptionMessage, $verboseWarningMessage, $captionMessage)) { git checkout $currentLocalBranchName if ($LASTEXITCODE -ne 0) { $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( ($script:localizedData.New_SamplerGitHubReleaseTag_FailedCheckoutPreviousBranch -f $currentLocalBranchName), 'NSGRT0011', # cspell: disable-line [System.Management.Automation.ErrorCategory]::InvalidOperation, $DatabaseName ) ) } } } } #EndRegion '.\Public\New-SamplerGitHubReleaseTag.ps1' 348 #Region '.\Public\Out-Difference.ps1' -1 <# .SYNOPSIS Compares two sets of strings and converts them into a difference string. .DESCRIPTION The Out-Difference function compares two sets of strings, Reference and Difference, and converts them into a difference string. It provides options to customize the indicators, labels, and formatting of the output. .PARAMETER Reference Specifies the reference set of strings to compare. .PARAMETER Difference Specifies the difference set of strings to compare. .PARAMETER EqualIndicator Specifies the indicator to use for equal strings. .PARAMETER NotEqualIndicator Specifies the indicator to use for unequal strings. .PARAMETER HighlightStart Specifies the starting indicator for highlighting differences. .PARAMETER HighlightEnd Specifies the ending indicator for highlighting differences. .PARAMETER ReferenceLabel Specifies the label for the reference set. .PARAMETER DifferenceLabel Specifies the label for the difference set. .PARAMETER NoColumnHeader Indicates whether to exclude the column header from the output. .PARAMETER NoLabels Indicates whether to exclude the labels from the output. .PARAMETER ReferenceLabelAnsi Specifies the ANSI escape sequence for the reference label. .PARAMETER DifferenceLabelAnsi Specifies the ANSI escape sequence for the difference label. .PARAMETER ColumnHeaderAnsi Specifies the ANSI escape sequence for the column header. .PARAMETER ColumnHeaderResetAnsi Specifies the ANSI escape sequence to reset the column header formatting. .PARAMETER EncodingType Specifies the encoding type to use for converting the strings to byte arrays. .PARAMETER ConcatenateArray Indicates whether to concatenate the arrays of strings into a single string. .PARAMETER ConcatenateChar Specifies the character used to concatenate the strings. Default is a new line character. .EXAMPLE $reference = "apple", "banana", "cherry" $difference = "apple", "orange", "cherry" Out-Difference -Reference $reference -Difference $difference -EqualIndicator '' -ReferenceLabel 'Reference:' -DifferenceLabel 'Difference:' -ConcatenateArray -ConcatenateChar '' .INPUTS None. You cannot pipe input to this function. .OUTPUTS System.String. The difference string representing the comparison between the reference and difference sets. .NOTES This command is using the default parameters values from the ConvertTo-DifferenceString command. #> function Out-Difference { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [AllowEmptyString()] [AllowNull()] [AllowEmptyCollection()] [System.String[]] $Reference, [Parameter(Mandatory = $true)] [AllowEmptyString()] [AllowNull()] [AllowEmptyCollection()] [System.String[]] $Difference, [Parameter()] [ValidateLength(0, 2)] [System.String] $EqualIndicator, [Parameter()] [ValidateLength(0, 2)] [System.String] $NotEqualIndicator, [Parameter()] [System.String] $HighlightStart, [Parameter()] [System.String] $HighlightEnd, [Parameter()] [System.String] $ReferenceLabel, [Parameter()] [System.String] $DifferenceLabel, [Parameter()] [System.Management.Automation.SwitchParameter] $NoColumnHeader, [Parameter()] [System.Management.Automation.SwitchParameter] $NoLabels, [Parameter()] [System.String] $ReferenceLabelAnsi, [Parameter()] [System.String] $DifferenceLabelAnsi, [Parameter()] [System.String] $ColumnHeaderAnsi, [Parameter()] [System.String] $ColumnHeaderResetAnsi, [Parameter()] [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7', 'UTF8')] [System.String] $EncodingType, [Parameter()] [System.Management.Automation.SwitchParameter] $ConcatenateArray, [Parameter()] [System.String] $ConcatenateChar = [System.Environment]::NewLine ) if ($null -eq $ConcatenateChar) { $ConcatenateChar = '' } $behaviorParameters = @{} + $PSBoundParameters $behaviorParameters.Remove('Reference') $behaviorParameters.Remove('Difference') $behaviorParameters.Remove('ConcatenateArray') $behaviorParameters.Remove('ConcatenateChar') if ($ConcatenateArray.IsPresent) { # Handle null values by converting them to empty strings if ($null -eq $Reference) { $refString = '' } else { $refString = $Reference -join $ConcatenateChar } if ($null -eq $Difference) { $diffString = '' } else { $diffString = $Difference -join $ConcatenateChar } ConvertTo-DifferenceString -ReferenceString $refString -DifferenceString $diffString @behaviorParameters } else { for ($i = 0; $i -lt [Math]::Max($Reference.Length, $Difference.Length); $i++) { $refString = if ($i -lt $Reference.Length) { $Reference[$i] } else { '' } $diffString = if ($i -lt $Difference.Length) { $Difference[$i] } else { '' } ConvertTo-DifferenceString -ReferenceString $refString -DifferenceString $diffString @behaviorParameters } } } #EndRegion '.\Public\Out-Difference.ps1' 220 #Region '.\Public\Pop-VMLatestSnapshot.ps1' -1 <# .SYNOPSIS Sets the latest snapshot of a virtual machine and starts it. .DESCRIPTION The Pop-VMLatestSnapShot command sets the latest snapshot of a virtual machine specified by the $ServerName parameter and starts it. .PARAMETER ServerName Specifies the name of the server for which to set the latest snapshot. .EXAMPLE Pop-VMLatestSnapShot -ServerName 'VM1' Sets the latest snapshot of the virtual machine named "VM1" and starts it. #> function Pop-VMLatestSnapShot { param ( [Parameter(Mandatory = $true)] [System.String] $ServerName ) Get-VM -Name $ServerName | Get-Snapshot | # TODO: Should this not be Get-VMSnapshot? Where-Object -FilterScript { $_.IsCurrent -eq $true } | Set-VM -VM $ServerName | # TODO: Is -VM necessary? Start-VM } #EndRegion '.\Public\Pop-VMLatestSnapshot.ps1' 34 #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 |