From 8eff58dfb662c5ed40b86191eeceb9b8cd833aab Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Fri, 14 Jan 2022 11:08:10 +0000 Subject: [PATCH 01/19] Add Show-EnvironmentVariables --- PSTK.psd1 | 20 +++++-------- Public/Show-EnvironmentVariables.ps1 | 42 ++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 Public/Show-EnvironmentVariables.ps1 diff --git a/PSTK.psd1 b/PSTK.psd1 index e18fa13..8a0b391 100644 --- a/PSTK.psd1 +++ b/PSTK.psd1 @@ -1,9 +1,9 @@ # -# Module manifest for module 'PSTK' +# Module manifest for module 'PSGet_PSTK' # # Generated by: Florian Carrier # -# Generated on: 21/11/2021 +# Generated on: 14/01/2022 # @{ @@ -24,7 +24,7 @@ GUID = '065d3e48-45c0-4b6b-9052-b92fe22b4e51' Author = 'Florian Carrier' # Company or vendor of this module -CompanyName = '' +CompanyName = 'Unknown' # Copyright statement for this module Copyright = '(c) 2019-2021 Florian Carrier. All rights reserved.' @@ -83,8 +83,8 @@ FunctionsToExport = 'Compare-Hashtable', 'Compare-Properties', 'Compare-Version' 'Remove-Object', 'Rename-NumberedFile', 'Resolve-Array', 'Resolve-Boolean', 'Resolve-Tags', 'Resolve-URI', 'Select-XMLNode', 'Set-EnvironmentVariable', 'Set-RelativePath', 'Set-Tags', - 'Start-Script', 'Stop-AllTranscripts', 'Stop-Script', - 'Sync-EnvironmentVariable', 'Test-EnvironmentVariable', + 'Show-EnvironmentVariables', 'Start-Script', 'Stop-AllTranscripts', + 'Stop-Script', 'Sync-EnvironmentVariable', 'Test-EnvironmentVariable', 'Test-HTTPStatus', 'Test-Object', 'Test-OracleConnection', 'Test-Service', 'Test-SQLConnection', 'Update-File', 'Wait-WebResource', 'Write-Checksum', 'Write-ErrorLog', 'Write-InsertOrUpdate', 'Write-Log' @@ -127,17 +127,11 @@ PrivateData = @{ # ReleaseNotes of this module ReleaseNotes = 'https://github.com/Akaizoku/PSAYX/blob/main/CHANGELOG.md' - # Prerelease string of this module - # Prerelease = '' - - # Flag to indicate whether the module requires explicit user acceptance for install/update/save - # RequireLicenseAcceptance = $false - # External dependent modules of this module - # ExternalModuleDependencies = @() + # ExternalModuleDependencies = '' } # End of PSData hashtable - + } # End of PrivateData hashtable # HelpInfo URI of this module diff --git a/Public/Show-EnvironmentVariables.ps1 b/Public/Show-EnvironmentVariables.ps1 new file mode 100644 index 0000000..c1005a7 --- /dev/null +++ b/Public/Show-EnvironmentVariables.ps1 @@ -0,0 +1,42 @@ +function Show-EnvironmentVariables { + <# + .SYNOPSIS + Show environment variables + + .DESCRIPTION + Lists all available environment variables in a specified scope + + .NOTES + File name: Show-EnvironmentVariables.ps1 + Author: Florian Carrier + Creation date: 2022-01-14 + Last modified: 2022-01-14 + #> + [CmdletBinding ()] + Param ( + [Parameter ( + Position = 1, + Mandatory = $false, + HelpMessage = "Scope" + )] + [ValidateSet( + "Machine", + "Process", + "User" + )] + [System.String] + $Scope + ) + Begin { + # Get global preference vrariables + Get-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState + } + Process { + if ($PSBoundParameters.ContainsKey("Scope")) { + $EnvironmentVariables = [System.Environment]::GetEnvironmentVariables($Scope) + } else { + $EnvironmentVariables = [System.Environment]::GetEnvironmentVariables() + } + return $EnvironmentVariables + } +} \ No newline at end of file From 2b29a68d020259cbe568396e56283516040a4840 Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Thu, 17 Feb 2022 17:47:15 +0000 Subject: [PATCH 02/19] Add Ping-Host --- CHANGELOG.md | 9 +++++ PSTK.psd1 | 6 +-- Public/Ping-Host.ps1 | 89 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 Public/Ping-Host.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 327388e..659f92c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ All notable changes to the [PSTK](https://github.com/Akaizoku/PSTK) project will The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.2.6](https://github.com/Akaizoku/PSTK/compare/1.2.5...develop) - Unreleased + +### Added + +The following functions have been added: + +- Ping-Host +- Show-EnvironmentVariables + ## [1.2.5](https://github.com/Akaizoku/PSTK/releases/1.2.5) - 2021-11-21 Maintenance automation and incremental update diff --git a/PSTK.psd1 b/PSTK.psd1 index 8a0b391..409727e 100644 --- a/PSTK.psd1 +++ b/PSTK.psd1 @@ -3,7 +3,7 @@ # # Generated by: Florian Carrier # -# Generated on: 14/01/2022 +# Generated on: 15/02/2022 # @{ @@ -12,7 +12,7 @@ RootModule = 'PSTK.psm1' # Version number of this module. -ModuleVersion = '1.2.5' +ModuleVersion = '1.2.6' # Supported PSEditions # CompatiblePSEditions = @() @@ -78,7 +78,7 @@ FunctionsToExport = 'Compare-Hashtable', 'Compare-Properties', 'Compare-Version' 'Get-KeyValue', 'Get-Object', 'Get-Path', 'Get-Properties', 'Get-URI', 'Import-CSVProperties', 'Import-Function', 'Import-Properties', 'Invoke-OracleCmd', 'New-DynamicParameter', 'New-RandomPassword', - 'New-SelfContainedPackage', 'Out-Hashtable', + 'New-SelfContainedPackage', 'Out-Hashtable', 'Ping-Host', 'Protect-WindowsCmdValue', 'Remove-EnvironmentVariable', 'Remove-Object', 'Rename-NumberedFile', 'Resolve-Array', 'Resolve-Boolean', 'Resolve-Tags', 'Resolve-URI', 'Select-XMLNode', diff --git a/Public/Ping-Host.ps1 b/Public/Ping-Host.ps1 new file mode 100644 index 0000000..c67c965 --- /dev/null +++ b/Public/Ping-Host.ps1 @@ -0,0 +1,89 @@ +function Ping-Host { + <# + .SYNOPSIS + Ping host + + .DESCRIPTION + Test the connection to a specified host + + .NOTES + File name: Ping-Host.ps1 + Author: Florian Carrier + Creation date: 2022-02-15 + Last modified: 2022-02-15 + + .LINK + https://docs.microsoft.com/en-us/previous-versions/windows/desktop/wmipicmp/win32-pingstatus + #> + [CmdletBinding ()] + Param ( + [Parameter ( + Position = 1, + Mandatory = $true, + HelpMessage = "Hostname or IP address" + )] + [ValidateNotNullOrEmpty ()] + [Alias ("Address")] + [System.String] + $Hostname, + [Parameter ( + Position = 2, + Mandatory = $false, + HelpMessage = "Timeout (in seconds)" + )] + [ValidateNotNullOrEmpty ()] + [System.Int32] + $TimeOut = 1, + [Parameter ( + HelpMessage = "Return detailed status" + )] + [Switch] + $Status + ) + Begin { + # Get global preference vrariables + Get-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState + # Status codes + $StatusCodes = [Ordered]@{ + [System.UInt32]0 = "Success" + [System.UInt32]11001 = "Buffer Too Small" + [System.UInt32]11002 = "Destination Net Unreachable" + [System.UInt32]11003 = "Destination Host Unreachable" + [System.UInt32]11004 = "Destination Protocol Unreachable" + [System.UInt32]11005 = "Destination Port Unreachable" + [System.UInt32]11006 = "No Resources" + [System.UInt32]11007 = "Bad Option" + [System.UInt32]11008 = "Hardware Error" + [System.UInt32]11009 = "Packet Too Big" + [System.UInt32]11010 = "Request Timed Out" + [System.UInt32]11011 = "Bad Request" + [System.UInt32]11012 = "Bad Route" + [System.UInt32]11013 = "TimeToLive Expired Transit" + [System.UInt32]11014 = "TimeToLive Expired Reassembly" + [System.UInt32]11015 = "Parameter Problem" + [System.UInt32]11016 = "Source Quench" + [System.UInt32]11017 = "Option Too Big" + [System.UInt32]11018 = "Bad Destination" + [System.UInt32]11032 = "Negotiating IPSEC" + [System.UInt32]11050 = "General Failure" + } + # Convert time-out to milliseconds + $TimeOut = $TimeOut * 1000 + } + Process { + # Ping host + $Ping = Get-CimInstance -ClassName "Win32_PingStatus" -Filter "Address='$Hostname' AND Timeout=$TimeOut" + if ($Status) { + # Return status label + if ($null -eq $Ping.StatusCode) { + $Output = "Failure" + } else { + $Output = $StatusCodes.$($Ping.StatusCode) + } + } else { + # Return boolean + $Output = ($Ping.StatusCode -eq 0) + } + return $Output + } +} \ No newline at end of file From a1a7f3dc31d351520bd4b22e220d189ba99998cd Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Tue, 19 Apr 2022 19:25:34 +0100 Subject: [PATCH 03/19] Update documentation --- PSTK.psd1 | 2 +- Public/Get-Object.ps1 | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/PSTK.psd1 b/PSTK.psd1 index 409727e..7ab6136 100644 --- a/PSTK.psd1 +++ b/PSTK.psd1 @@ -3,7 +3,7 @@ # # Generated by: Florian Carrier # -# Generated on: 15/02/2022 +# Generated on: 07/04/2022 # @{ diff --git a/Public/Get-Object.ps1 b/Public/Get-Object.ps1 index 7fc1657..7207cfc 100644 --- a/Public/Get-Object.ps1 +++ b/Public/Get-Object.ps1 @@ -32,29 +32,34 @@ function Get-Object { .EXAMPLE Get-Object -Path "\path\to\folder" + In this example, Get-Object will return the object "folder". + + .EXAMPLE + Get-Object -Path "\path\to\folder" -ChildItem + In this example, Get-Object will return all the objects (files and folders) listed in the "\path\to\folder" directory. .EXAMPLE - Get-Object -Path "\path\to\folder" -Type "File" + Get-Object -Path "\path\to\folder" -Type "File" -ChildItem In this example, Get-Object will return all the files listed in the "\path\to\folder" directory. .EXAMPLE - Get-Object -Path "\path\to\folder" -Type "Folder" + Get-Object -Path "\path\to\folder" -Type "Folder" -ChildItem In this example, Get-Object will return all the folders listed in the "\path\to\folder" directory. .EXAMPLE - Get-Object -Path "\path\to\folder" -Type "File" -Filter "*.txt" + Get-Object -Path "\path\to\folder" -Type "File" -Filter "*.txt" -ChildItem In this example, Get-Object will return all the text files listed in the "\path\to\folder" directory. .EXAMPLE - Get-Object -Path "\path\to\folder" -Type "File" -Exclude "*.txt" + Get-Object -Path "\path\to\folder" -Type "File" -Exclude "*.txt" -ChildItem In this example, Get-Object will return all the non-text files listed in the "\path\to\folder" directory. @@ -65,7 +70,7 @@ function Get-Object { File name: Get-Object.ps1 Author: Florian Carrier Creation date: 2019-06-14 - Last modified: 2021-07-06 + Last modified: 2022-04-19 #> [CmdletBinding ()] Param ( From 730f26af089ac795182a8d5695a18a66877e28a7 Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Tue, 2 Aug 2022 20:10:56 +0100 Subject: [PATCH 04/19] Add force parameter --- Public/Copy-Object.ps1 | 5 ++++- Public/Remove-Object.ps1 | 12 ++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Public/Copy-Object.ps1 b/Public/Copy-Object.ps1 index 5c9da65..1266146 100644 --- a/Public/Copy-Object.ps1 +++ b/Public/Copy-Object.ps1 @@ -19,11 +19,14 @@ function Copy-Object { .PARAMETER Exclude The exclude parameter corresponds to the filter to apply to the name of objects *not* to copy. + .PARAMETER Force + The force parameter enable the overwrite of the target object. + .NOTES File name: Copy-Object.ps1 Author: Florian Carrier Creation date: 2021-07-06 - Last modified: 2021-07-08 + Last modified: 2022-08-02 #> [CmdletBinding ( SupportsShouldProcess = $true diff --git a/Public/Remove-Object.ps1 b/Public/Remove-Object.ps1 index 836ddea..a88d4c3 100644 --- a/Public/Remove-Object.ps1 +++ b/Public/Remove-Object.ps1 @@ -18,11 +18,14 @@ function Remove-Object { .PARAMETER Exclude The exclude parameter corresponds to the filter to apply to the name of objects *not* to remove. + .PARAMETER Force + The force parameter enable the deletion of read-only or hidden files. + .NOTES File name: Remove-Object.ps1 Author: Florian Carrier Creation date: 2019-06-14 - Last modified: 2021-09-10 + Last modified: 2022-08-02 #> [CmdletBinding ()] Param ( @@ -62,6 +65,11 @@ function Remove-Object { [ValidateNotNullOrEmpty ()] [System.String[]] $Exclude = $null, + [Parameter ( + HelpMessage = "Switch to force copy" + )] + [Switch] + $Force, [Parameter ( HelpMessage = "Suppress debug messages" )] @@ -92,7 +100,7 @@ function Remove-Object { Write-Log -Type "DEBUG" -Object $Object.FullName } try { - Remove-Item -Path $Object.FullName -Recurse -Force -ErrorVariable "ErrorMessage" -ErrorAction "Stop" + Remove-Item -Path $Object.FullName -Recurse -Force:$Force -ErrorVariable "ErrorMessage" -ErrorAction "Stop" } catch { Write-Log -Type "ERROR" -Message $ErrorMessage } From 0b07fa4866a8a9d12ed5db996cee56f70b06f22c Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Tue, 3 Sep 2024 20:27:43 +0200 Subject: [PATCH 05/19] Update Get-Properties --- PSTK.psd1 | 26 +++++++++------ Public/Get-Properties.ps1 | 66 +++++++++++++++++++++++++++++---------- 2 files changed, 65 insertions(+), 27 deletions(-) diff --git a/PSTK.psd1 b/PSTK.psd1 index 7ab6136..a5d63bd 100644 --- a/PSTK.psd1 +++ b/PSTK.psd1 @@ -1,9 +1,9 @@ # -# Module manifest for module 'PSGet_PSTK' +# Module manifest for module 'PSTK' # # Generated by: Florian Carrier # -# Generated on: 07/04/2022 +# Generated on: 03/09/2024 # @{ @@ -27,25 +27,25 @@ Author = 'Florian Carrier' CompanyName = 'Unknown' # Copyright statement for this module -Copyright = '(c) 2019-2021 Florian Carrier. All rights reserved.' +Copyright = '(c) 2019-2024 Florian Carrier. All rights reserved.' # Description of the functionality provided by this module Description = 'Collection of useful functions and procedures for PowerShell scripting' -# Minimum version of the Windows PowerShell engine required by this module +# Minimum version of the PowerShell engine required by this module PowerShellVersion = '3.0' -# Name of the Windows PowerShell host required by this module +# Name of the PowerShell host required by this module # PowerShellHostName = '' -# Minimum version of the Windows PowerShell host required by this module +# Minimum version of the PowerShell host required by this module # PowerShellHostVersion = '' # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. # DotNetFrameworkVersion = '' # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. -# CLRVersion = '' +# ClrVersion = '' # Processor architecture (None, X86, Amd64) required by this module # ProcessorArchitecture = '' @@ -125,13 +125,19 @@ PrivateData = @{ # IconUri = '' # ReleaseNotes of this module - ReleaseNotes = 'https://github.com/Akaizoku/PSAYX/blob/main/CHANGELOG.md' + ReleaseNotes = 'https://github.com/Akaizoku/PSTK/blob/main/CHANGELOG.md' + + # Prerelease string of this module + # Prerelease = '' + + # Flag to indicate whether the module requires explicit user acceptance for install/update/save + # RequireLicenseAcceptance = $false # External dependent modules of this module - # ExternalModuleDependencies = '' + # ExternalModuleDependencies = @() } # End of PSData hashtable - + } # End of PrivateData hashtable # HelpInfo URI of this module diff --git a/Public/Get-Properties.ps1 b/Public/Get-Properties.ps1 index 174ffa0..6affc9c 100644 --- a/Public/Get-Properties.ps1 +++ b/Public/Get-Properties.ps1 @@ -1,6 +1,3 @@ -# ------------------------------------------------------------------------------ -# Properties setting function -# ------------------------------------------------------------------------------ function Get-Properties { <# .SYNOPSIS @@ -13,15 +10,19 @@ function Get-Properties { The File parameter should be the name of the property file. .PARAMETER Directory - The Directory parameter should be the path to the directory containing the - property file. + The Directory parameter should be the path to the directory containing the property file. .PARAMETER Custom The Custom parameter should be the name of the custom property file. .PARAMETER CustomDirectory - The CustomDirectory parameter should be the path to the directory containing - the custom property file. + The CustomDirectory parameter should be the path to the directory containing the custom property file. + + .PARAMETER Path + The path parameter corresponds to the path to the property file. + + .PARAMETER CustomPath + The custom path parameter corresponds to the path to the custom property file. .OUTPUTS System.Collections.Specialized.OrderedDictionary. Get-Properties returns an @@ -37,15 +38,19 @@ function Get-Properties { default ones with the custom ones. .NOTES - Get-Properties does not currently allow the use of sections to group proper- - ties in custom files + File name: Properties.ps1 + Author: Florian Carrier + Creation date: 2018-11-27 + Last modified: 2023-03-23 + Comment: Get-Properties does not currently allow the use of sections to group properties in custom files #> - [CmdletBinding ()] + [CmdletBinding (DefaultParameterSetName = "File")] Param ( [Parameter ( - Position = 1, - Mandatory = $true, - HelpMessage = "Property file name" + Position = 1, + Mandatory = $true, + ParameterSetName = "File", + HelpMessage = "Property file name" )] [ValidateNotNullOrEmpty ()] [String] @@ -53,6 +58,7 @@ function Get-Properties { [Parameter ( Position = 2, Mandatory = $true, + ParameterSetName = "File", HelpMessage = "Path to the directory containing the property files" )] [ValidateNotNullOrEmpty ()] @@ -61,6 +67,7 @@ function Get-Properties { [Parameter ( Position = 3, Mandatory = $false, + ParameterSetName = "File", HelpMessage = "Custom property file name" )] [String] @@ -68,10 +75,29 @@ function Get-Properties { [Parameter ( Position = 4, Mandatory = $false, + ParameterSetName = "File", HelpMessage = "Path to the directory containing the custom property file" )] [String] $CustomDirectory = $Directory, + [Parameter ( + Position = 1, + Mandatory = $true, + ParameterSetName = "Path", + HelpMessage = "Property file path" + )] + [ValidateNotNullOrEmpty ()] + [String] + $Path, + [Parameter ( + Position = 2, + Mandatory = $false, + ParameterSetName = "Path", + HelpMessage = "Custom property file path" + )] + [ValidateNotNullOrEmpty ()] + [String] + $CustomPath, [Parameter ( Position = 5, Mandatory = $false, @@ -90,15 +116,21 @@ function Get-Properties { Get-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState } Process { - # Check that specified file exists - $Path = Join-Path -Path $Directory -ChildPath $File + if ($PSCmdlet.ParameterSetName -eq "File") { + # Check that specified file exists + $Path = Join-Path -Path $Directory -ChildPath $File + # Check if a custom file is provided + if ($Custom) { + # Make sure said file does exists + $CustomPath = Join-Path -Path $CustomDirectory -ChildPath $Custom + } + } if (Test-Path -Path $Path) { # Parse properties with or without section split $Properties = Read-Properties -Path $Path -Section:$Section # Check if a custom file is provided - if ($Custom) { + if ($CustomPath) { # Make sure said file does exists - $CustomPath = Join-Path -Path $CustomDirectory -ChildPath $Custom if (Test-Path -Path $CustomPath) { # Override default properties with custom ones $Customs = Read-Properties -Path $CustomPath From 00a47a77825389fed168a64b243600b50daeec61 Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Wed, 4 Sep 2024 12:37:20 +0200 Subject: [PATCH 06/19] Fix parameter position Fix parameter position and use explicit references --- PSTK.psd1 | 2 +- Public/Compare-Version.ps1 | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/PSTK.psd1 b/PSTK.psd1 index a5d63bd..dee14d2 100644 --- a/PSTK.psd1 +++ b/PSTK.psd1 @@ -3,7 +3,7 @@ # # Generated by: Florian Carrier # -# Generated on: 03/09/2024 +# Generated on: 04/09/2024 # @{ diff --git a/Public/Compare-Version.ps1 b/Public/Compare-Version.ps1 index 55206b3..e40f138 100644 --- a/Public/Compare-Version.ps1 +++ b/Public/Compare-Version.ps1 @@ -22,7 +22,7 @@ function Compare-Version { File name: Compare-Version.ps1 Author: Florian Carrier Creation date: 2019-10-19 - Last modified: 2020-02-10 + Last modified: 2024-09-04 WARNING In case of modified formatting, Compare-Version only checks the semantic versionned part #> [CmdletBinding ( @@ -35,10 +35,10 @@ function Compare-Version { HelpMessage = "Version number to test" )] [ValidateNotNullOrEmpty()] - [String] + [System.String] $Version, [Parameter ( - Position = 1, + Position = 2, Mandatory = $true, HelpMessage = "Comparison operator" )] @@ -50,7 +50,7 @@ function Compare-Version { "lt", # Less than "le" # Less than or equal )] - [String] + [System.String] $Operator, [Parameter ( Position = 3, @@ -58,7 +58,7 @@ function Compare-Version { HelpMessage = "Reference version number to check against" )] [ValidateNotNullOrEmpty()] - [String] + [System.String] $Reference, [Parameter ( Position = 4, @@ -69,7 +69,7 @@ function Compare-Version { "modified", "semantic" )] - [String] + [System.String] $Format = "semantic" ) Begin { @@ -107,14 +107,14 @@ function Compare-Version { $ReferenceNumber = $Reference } else { # Parse version numbers - $SemanticVersion = Select-String -InputObject $Version -Pattern '(\d+.\d+.\d+)(?=\D*)' | ForEach-Object { $_.Matches.Value } + $SemanticVersion = Select-String -InputObject $Version -Pattern '(\d+.\d+.\d+)(?=\D*)' | ForEach-Object { $PSItem.Matches.Value } try { $VersionNumber = [System.Version]::Parse($SemanticVersion) } catch [FormatException] { Write-Log -Type "ERROR" -Object "The version number ""$Version"" does not match semantic numbering" return $false } - $SemanticReference = Select-String -InputObject $Reference -Pattern '(\d+.\d+.\d+)(?=\D*)' | ForEach-Object { $_.Matches.Value } + $SemanticReference = Select-String -InputObject $Reference -Pattern '(\d+.\d+.\d+)(?=\D*)' | ForEach-Object { $PSItem.Matches.Value } try { $ReferenceNumber = [System.Version]::Parse($SemanticReference) } catch [FormatException] { From 7ca9db88059be9e053fe9ecd848018c813128994 Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Fri, 6 Sep 2024 13:02:30 +0200 Subject: [PATCH 07/19] Fix semantic version comparison Use built-in version CompareTo method for semantic versions --- PSTK.psd1 | 2 +- Public/Compare-Version.ps1 | 31 +++++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/PSTK.psd1 b/PSTK.psd1 index dee14d2..eb3ebff 100644 --- a/PSTK.psd1 +++ b/PSTK.psd1 @@ -3,7 +3,7 @@ # # Generated by: Florian Carrier # -# Generated on: 04/09/2024 +# Generated on: 06/09/2024 # @{ diff --git a/Public/Compare-Version.ps1 b/Public/Compare-Version.ps1 index e40f138..7a59050 100644 --- a/Public/Compare-Version.ps1 +++ b/Public/Compare-Version.ps1 @@ -22,8 +22,17 @@ function Compare-Version { File name: Compare-Version.ps1 Author: Florian Carrier Creation date: 2019-10-19 - Last modified: 2024-09-04 + Last modified: 2024-09-06 WARNING In case of modified formatting, Compare-Version only checks the semantic versionned part + + .LINK + https://semver.org/ + + .LINK + https://learn.microsoft.com/en-us/dotnet/api/system.version + + .LINK + https://learn.microsoft.com/en-us/dotnet/api/system.version.compareto #> [CmdletBinding ( SupportsShouldProcess = $true @@ -79,6 +88,7 @@ function Compare-Version { Process { switch ($Format) { "semantic" { + Write-Log -Type "DEBUG" -Message "Semantic version comparison" # Prepare version numbers for comparison try { $VersionNumber = [System.Version]::Parse($Version) @@ -92,15 +102,20 @@ function Compare-Version { Write-Log -Type "ERROR" -Object "The version number ""$Reference"" does not match $Format numbering" return $false } - # Build comparison command - $Command = """$VersionNumber"" -$Operator ""$ReferenceNumber""" - Write-Log -Type "DEBUG" -Object $Command - # Execute comparison - $Result = Invoke-Expression -Command $Command - # Return comparison result - return $Result + # Compare versions + $Compare = $VersionNumber.CompareTo($ReferenceNumber) + if (($Operator -in ("eq", "ge", "le")) -And ($Compare -eq 0)) { + return $True + } elseif (($Operator -in ("ne", "gt")) -And ($Compare -eq 1)) { + return $True + } elseif (($Operator -in ("ne", "lt")) -And ($Compare -eq -1)) { + return $True + } else { + return $False + } } "modified" { + Write-Log -Type "DEBUG" -Message "String version comparison" if ($Operator -in ("eq", "ne")) { # Compare strings as-is $VersionNumber = $Version From f878a940d840280721c498e69f6e495ea86d7bba Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Tue, 10 Sep 2024 19:39:49 +0200 Subject: [PATCH 08/19] Add process management functions Add new functions to monitor (sub)processes --- PSTK.psd1 | 13 ++--- Public/New-ProcessObject.ps1 | 46 ++++++++++++++++ Public/Update-ProcessObject.ps1 | 93 +++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 6 deletions(-) create mode 100644 Public/New-ProcessObject.ps1 create mode 100644 Public/Update-ProcessObject.ps1 diff --git a/PSTK.psd1 b/PSTK.psd1 index eb3ebff..32a3c55 100644 --- a/PSTK.psd1 +++ b/PSTK.psd1 @@ -3,7 +3,7 @@ # # Generated by: Florian Carrier # -# Generated on: 06/09/2024 +# Generated on: 10/09/2024 # @{ @@ -77,17 +77,18 @@ FunctionsToExport = 'Compare-Hashtable', 'Compare-Properties', 'Compare-Version' 'Get-CallerPreference', 'Get-EnvironmentVariable', 'Get-HTTPStatus', 'Get-KeyValue', 'Get-Object', 'Get-Path', 'Get-Properties', 'Get-URI', 'Import-CSVProperties', 'Import-Function', 'Import-Properties', - 'Invoke-OracleCmd', 'New-DynamicParameter', 'New-RandomPassword', - 'New-SelfContainedPackage', 'Out-Hashtable', 'Ping-Host', - 'Protect-WindowsCmdValue', 'Remove-EnvironmentVariable', + 'Invoke-OracleCmd', 'New-DynamicParameter', 'New-ProcessObject', + 'New-RandomPassword', 'New-SelfContainedPackage', 'Out-Hashtable', + 'Ping-Host', 'Protect-WindowsCmdValue', 'Remove-EnvironmentVariable', 'Remove-Object', 'Rename-NumberedFile', 'Resolve-Array', 'Resolve-Boolean', 'Resolve-Tags', 'Resolve-URI', 'Select-XMLNode', 'Set-EnvironmentVariable', 'Set-RelativePath', 'Set-Tags', 'Show-EnvironmentVariables', 'Start-Script', 'Stop-AllTranscripts', 'Stop-Script', 'Sync-EnvironmentVariable', 'Test-EnvironmentVariable', 'Test-HTTPStatus', 'Test-Object', 'Test-OracleConnection', - 'Test-Service', 'Test-SQLConnection', 'Update-File', 'Wait-WebResource', - 'Write-Checksum', 'Write-ErrorLog', 'Write-InsertOrUpdate', 'Write-Log' + 'Test-Service', 'Test-SQLConnection', 'Update-File', + 'Update-ProcessObject', 'Wait-WebResource', 'Write-Checksum', + 'Write-ErrorLog', 'Write-InsertOrUpdate', 'Write-Log' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() diff --git a/Public/New-ProcessObject.ps1 b/Public/New-ProcessObject.ps1 new file mode 100644 index 0000000..c6bf4bb --- /dev/null +++ b/Public/New-ProcessObject.ps1 @@ -0,0 +1,46 @@ +function New-ProcessObject { + <# + .SYNOPSIS + Create new process custom object + + .DESCRIPTION + Create a new PSCustomObject to store all information about a process + + .NOTES + File name: New-ProcessObject.ps1 + Author: Florian Carrier + Creation date: 2024-09-10 + Last modified: 2024-09-10 + #> + [CmdletBinding ()] + Param ( + [Parameter ( + Position = 1, + Mandatory = $true, + HelpMessage = "Name of the process" + )] + [ValidateNotNullOrEmpty ()] + [Alias ("ProcessName")] + [System.String] + $Name + ) + Begin { + # Get global preference vrariables + Get-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState + # Log function call + Write-Log -Type "DEBUG" -Message $MyInvocation.MyCommand.Name + } + Process { + $Process = [PSCustomObject]@{ + Status = "Started" + Success = $false + ExitCode = 0 + ErrorCount = 0 + ProcessID = $PID + ProcessName = $Name + } + } + End { + return $Process + } +} \ No newline at end of file diff --git a/Public/Update-ProcessObject.ps1 b/Public/Update-ProcessObject.ps1 new file mode 100644 index 0000000..96660f5 --- /dev/null +++ b/Public/Update-ProcessObject.ps1 @@ -0,0 +1,93 @@ +function Update-ProcessObject { + <# + .SYNOPSIS + Update a process object + + .DESCRIPTION + Update the properties of a specified PSCustomObject holding the information of a process + + .NOTES + File name: Update-ProcessObject.ps1 + Author: Florian Carrier + Creation date: 2024-09-10 + Last modified: 2024-09-10 + #> + [CmdletBinding ()] + Param ( + [Parameter ( + Position = 1, + Mandatory = $true, + HelpMessage = "Process object to update" + )] + [ValidateNotNullOrEmpty ()] + [Alias ("Process")] + [PSCustomObject] + $ProcessObject, + [Parameter ( + Position = 2, + Mandatory = $false, + HelpMessage = "Process status" + )] + [ValidateSet ( + "Cancelled", + "Completed", + "Failed", + "Running", + "Started", + "Stopped" + )] + [System.String] + $Status, + [Parameter ( + Position = 2, + Mandatory = $false, + HelpMessage = "Status of the process" + )] + [ValidateNotNullOrEmpty ()] + [System.Boolean] + $Success, + [Parameter ( + Position = 3, + Mandatory = $false, + HelpMessage = "Exit code of the process" + )] + [ValidateNotNullOrEmpty ()] + [System.Int32] + $ExitCode, + [Parameter ( + Position = 4, + Mandatory = $false, + HelpMessage = "Exit code of the process" + )] + [ValidateNotNullOrEmpty ()] + [System.Int32] + $ErrorCount + ) + Begin { + # Get global preference vrariables + Get-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState + # Log function call + Write-Log -Type "DEBUG" -Message $MyInvocation.MyCommand.Name + } + Process { + # Update status + if ($PSBoundParameters.ContainsKey("Status")) { + $ProcessObject.Status = $Status + } + # Update success flag + if ($PSBoundParameters.ContainsKey("Success")) { + $ProcessObject.Success = $Success + } + # Update exit code + if ($PSBoundParameters.ContainsKey("ExitCode")) { + $ProcessObject.ExitCode = $ExitCode + } + # Update error count + if ($PSBoundParameters.ContainsKey("ErrorCount")) { + $ProcessObject.ErrorCount += $ErrorCount + } + } + End { + return $ProcessObject + } +} \ No newline at end of file From 46ebd3764caada0ada91dd150f156a0797701a87 Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Wed, 11 Sep 2024 15:09:27 +0200 Subject: [PATCH 09/19] Fix Compare-Version Fix missing test cases for operators ge and le --- PSTK.psd1 | 2 +- Public/Compare-Version.ps1 | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/PSTK.psd1 b/PSTK.psd1 index 32a3c55..d0af731 100644 --- a/PSTK.psd1 +++ b/PSTK.psd1 @@ -3,7 +3,7 @@ # # Generated by: Florian Carrier # -# Generated on: 10/09/2024 +# Generated on: 11/09/2024 # @{ diff --git a/Public/Compare-Version.ps1 b/Public/Compare-Version.ps1 index 7a59050..f30aca4 100644 --- a/Public/Compare-Version.ps1 +++ b/Public/Compare-Version.ps1 @@ -22,7 +22,7 @@ function Compare-Version { File name: Compare-Version.ps1 Author: Florian Carrier Creation date: 2019-10-19 - Last modified: 2024-09-06 + Last modified: 2024-09-11 WARNING In case of modified formatting, Compare-Version only checks the semantic versionned part .LINK @@ -106,9 +106,9 @@ function Compare-Version { $Compare = $VersionNumber.CompareTo($ReferenceNumber) if (($Operator -in ("eq", "ge", "le")) -And ($Compare -eq 0)) { return $True - } elseif (($Operator -in ("ne", "gt")) -And ($Compare -eq 1)) { + } elseif (($Operator -in ("ne", "ge", "gt")) -And ($Compare -eq 1)) { return $True - } elseif (($Operator -in ("ne", "lt")) -And ($Compare -eq -1)) { + } elseif (($Operator -in ("ne", "le", "lt")) -And ($Compare -eq -1)) { return $True } else { return $False From 1bdd9d8551efa3c00d5009c57d7596e9b26d65dd Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Wed, 11 Sep 2024 15:52:35 +0200 Subject: [PATCH 10/19] Add notice log type Add new log message type to highlight important notice --- Public/Write-Log.ps1 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Public/Write-Log.ps1 b/Public/Write-Log.ps1 index 3d65358..c136738 100644 --- a/Public/Write-Log.ps1 +++ b/Public/Write-Log.ps1 @@ -19,6 +19,7 @@ function Write-Log { - DEBUG: debug message, used to debug scripts; - ERROR: error message, used to provide detail on an issue; - INFO: information, used to convey a message; + - NOTICE: important information, used to highlight key details; - WARN: warning, used to highlight a non-blocking issue. .PARAMETER Object @@ -80,7 +81,7 @@ function Write-Log { File name: Write-Log.ps1 Author: Florian Carrier Creation date: 2018-10-15 - Last modified: 2021-09-02 + Last modified: 2024-09-11 TODO Add locale variable .LINK @@ -98,6 +99,7 @@ function Write-Log { "DEBUG", "ERROR", "INFO", + "NOTICE", "WARN" )] [System.String] @@ -149,6 +151,7 @@ function Write-Log { "CHECK" = "Green" "ERROR" = "Red" "INFO" = "White" + "NOTICE"= "Blue" "WARN" = "Yellow" } # Message object check @@ -184,9 +187,12 @@ function Write-Log { Write-Log -Type "DEBUG" -Object $FilePath $Message | Out-File -FilePath $FilePath -Append -Force } + + } + End { # Stop script if exit code is specified if ($PSBoundParameters.ContainsKey("ExitCode")) { - Stop-Script -ExitCode $ExitCode + Stop-Script -ExitCode $ExitCode } } } From 5ba3a1da38f45c8305d819ed130c45c7370a71d3 Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Thu, 12 Sep 2024 10:26:37 +0200 Subject: [PATCH 11/19] Add debug message Output process object to debug --- Public/New-ProcessObject.ps1 | 3 ++- Public/Update-ProcessObject.ps1 | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Public/New-ProcessObject.ps1 b/Public/New-ProcessObject.ps1 index c6bf4bb..ab04627 100644 --- a/Public/New-ProcessObject.ps1 +++ b/Public/New-ProcessObject.ps1 @@ -10,7 +10,7 @@ function New-ProcessObject { File name: New-ProcessObject.ps1 Author: Florian Carrier Creation date: 2024-09-10 - Last modified: 2024-09-10 + Last modified: 2024-09-12 #> [CmdletBinding ()] Param ( @@ -41,6 +41,7 @@ function New-ProcessObject { } } End { + Write-Log -Type "DEBUG" -Message $Process return $Process } } \ No newline at end of file diff --git a/Public/Update-ProcessObject.ps1 b/Public/Update-ProcessObject.ps1 index 96660f5..df36b7f 100644 --- a/Public/Update-ProcessObject.ps1 +++ b/Public/Update-ProcessObject.ps1 @@ -10,7 +10,7 @@ function Update-ProcessObject { File name: Update-ProcessObject.ps1 Author: Florian Carrier Creation date: 2024-09-10 - Last modified: 2024-09-10 + Last modified: 2024-09-12 #> [CmdletBinding ()] Param ( @@ -88,6 +88,7 @@ function Update-ProcessObject { } } End { + Write-Log -Type "DEBUG" -Message $Process return $ProcessObject } } \ No newline at end of file From 76a9ea9098552180df2afec25a8ba12dde385148 Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Thu, 12 Sep 2024 18:05:11 +0200 Subject: [PATCH 12/19] Remove comment --- Private/Read-Property.ps1 | 3 --- 1 file changed, 3 deletions(-) diff --git a/Private/Read-Property.ps1 b/Private/Read-Property.ps1 index 476c848..ad39b92 100644 --- a/Private/Read-Property.ps1 +++ b/Private/Read-Property.ps1 @@ -1,6 +1,3 @@ -# ------------------------------------------------------------------------------ -# Property parsing function -# ------------------------------------------------------------------------------ function Read-Property { <# .SYNOPSIS From 0f557d52afd7d262af708a40a115d061ba69c23c Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Thu, 12 Sep 2024 18:05:28 +0200 Subject: [PATCH 13/19] Update debug message format --- Public/New-ProcessObject.ps1 | 2 +- Public/Update-ProcessObject.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Public/New-ProcessObject.ps1 b/Public/New-ProcessObject.ps1 index ab04627..a7ee2a7 100644 --- a/Public/New-ProcessObject.ps1 +++ b/Public/New-ProcessObject.ps1 @@ -41,7 +41,7 @@ function New-ProcessObject { } } End { - Write-Log -Type "DEBUG" -Message $Process + Write-Log -Type "DEBUG" -Message ($Process | Format-Table) return $Process } } \ No newline at end of file diff --git a/Public/Update-ProcessObject.ps1 b/Public/Update-ProcessObject.ps1 index df36b7f..4712230 100644 --- a/Public/Update-ProcessObject.ps1 +++ b/Public/Update-ProcessObject.ps1 @@ -88,7 +88,7 @@ function Update-ProcessObject { } } End { - Write-Log -Type "DEBUG" -Message $Process + Write-Log -Type "DEBUG" -Message ($ProcessObject | Format-Table) return $ProcessObject } } \ No newline at end of file From 9daacb4913f941d4f69c13dd2f970e22aa6609a0 Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Mon, 16 Sep 2024 12:04:01 +0200 Subject: [PATCH 14/19] Add metadata Add function help documentation and reformat tabulations --- Public/Confirm-Prompt.ps1 | 63 +++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/Public/Confirm-Prompt.ps1 b/Public/Confirm-Prompt.ps1 index 071fdfe..deb91b1 100644 --- a/Public/Confirm-Prompt.ps1 +++ b/Public/Confirm-Prompt.ps1 @@ -1,27 +1,40 @@ function Confirm-Prompt { - [CmdletBinding ()] - Param ( - [Parameter ( - Position = 1, - Mandatory = $true, - HelpMessage = "Prompt message" - )] - [String] - $Prompt - ) - Begin { - $ConfirmPrompt = $Prompt + " ([Y] Yes | [N] No)" - } - Process { - $Answer = Read-Host -Prompt $ConfirmPrompt - switch -RegEx ($Answer) { - # Switch is case insensitive - '\Ayes\Z|\Ay\Z|\A1\Z|\Atrue\Z|\At\Z' { return $true } - '\Ano\Z|\An\Z|\A0\Z|\Afalse\Z|\Af\Z' { return $false } - default { - Write-Log -Type "ERROR" -Object "Unable to process answer. Please enter either [Y] Yes or [N] No" - Confirm-Prompt -Prompt $Prompt - } - } - } + <# + .SYNOPSIS + Prompt user for confirmation + + .DESCRIPTION + Prompt user to confirm agreement to a specified statement + + .NOTES + File name: Confirm-Prompt.ps1 + Author: Florian Carrier + Creation date: 2019-06-14 + Last modified: 2024-09-13 + #> + [CmdletBinding ()] + Param ( + [Parameter ( + Position = 1, + Mandatory = $true, + HelpMessage = "Prompt message" + )] + [String] + $Prompt + ) + Begin { + $ConfirmPrompt = $Prompt + " ([Y] Yes | [N] No)" + } + Process { + $Answer = Read-Host -Prompt $ConfirmPrompt + switch -RegEx ($Answer) { + # Switch is case insensitive + '\Ayes\Z|\Ay\Z|\A1\Z|\Atrue\Z|\At\Z' { return $true } + '\Ano\Z|\An\Z|\A0\Z|\Afalse\Z|\Af\Z' { return $false } + default { + Write-Log -Type "ERROR" -Object "Unable to process answer. Please enter either [Y] Yes or [N] No" + Confirm-Prompt -Prompt $Prompt + } + } + } } From e626bf201fd5ff1eba0479c6c62dd9b2be5598e7 Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Mon, 16 Sep 2024 12:05:17 +0200 Subject: [PATCH 15/19] Disable WhatIf Disable the inheritence of the WhatIf parameters in case of ShouldProcess to avoid orphan transcripts --- Public/Stop-Script.ps1 | 97 +++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/Public/Stop-Script.ps1 b/Public/Stop-Script.ps1 index b682ecd..46c4746 100644 --- a/Public/Stop-Script.ps1 +++ b/Public/Stop-Script.ps1 @@ -1,57 +1,58 @@ function Stop-Script { - <# - .SYNOPSIS - Stop script + <# + .SYNOPSIS + Stop script - .DESCRIPTION - Exit script, set exit code, disable stric-mode, and stop transcript if any. + .DESCRIPTION + Exit script, set exit code, disable stric-mode, and stop transcript if any. - .PARAMETER ExitCode - The exit code parameter corresponds to the error code thrown after exiting - the script. Default is 0 (i.e. no errors). + .PARAMETER ExitCode + The exit code parameter corresponds to the error code thrown after exiting + the script. Default is 0 (i.e. no errors). - .EXAMPLE - Stop-Script + .EXAMPLE + Stop-Script - In this example, Stop-Script will set strict mode off, stop the transcript - if any is currently active, and exit the script with error code 0. + In this example, Stop-Script will set strict mode off, stop the transcript + if any is currently active, and exit the script with error code 0. - .EXAMPLE - Stop-Script -ExitCode 1 + .EXAMPLE + Stop-Script -ExitCode 1 - In this example, Stop-Script will set strict mode off, stop the transcript - if any is currently active, and exit the script with error code 1. + In this example, Stop-Script will set strict mode off, stop the transcript + if any is currently active, and exit the script with error code 1. - .NOTES - File name: Stop-Script.ps1 - Author: Florian Carrier - Creation date: 2018-10-15 - Last modified: 2019-12-17 - #> - [CmdletBinding ()] - Param ( - [Parameter ( - Position = 1, - Mandatory = $false, - HelpMessage = "Script exit code" - )] - [Alias ( - "Code", - "ErrorCode", - "ReturnCode" - )] - [Int] - $ExitCode = 0 - ) - Begin { - Set-StrictMode -Off - try { - Stop-Transcript - } catch { - Write-Log -Type "WARN" -Message "No transcript is being produced" - } - } - Process { - exit $ExitCode - } + .NOTES + File name: Stop-Script.ps1 + Author: Florian Carrier + Creation date: 2018-10-15 + Last modified: 2024-09-16 + #> + [CmdletBinding ()] + Param ( + [Parameter ( + Position = 1, + Mandatory = $false, + HelpMessage = "Script exit code" + )] + [Alias ( + "Code", + "ErrorCode", + "ReturnCode" + )] + [Int] + $ExitCode = 0 + ) + Begin { + Set-StrictMode -Off + try { + # Disable WhatIf to ensure transcripts are always stopped + Stop-Transcript -WhatIf:$false + } catch { + Write-Log -Type "WARN" -Message "No transcript is being produced" + } + } + Process { + exit $ExitCode + } } From 883dda57f57f90eb9851f526a0fa467f3dee26c6 Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Mon, 16 Sep 2024 12:06:13 +0200 Subject: [PATCH 16/19] Add metadata parsing Add new parameter to parse and include metadata in returned properties object --- PSTK.psd1 | 2 +- Private/Read-Properties.ps1 | 263 ++++++++++++++++++++---------------- Public/Get-Properties.ps1 | 24 +++- 3 files changed, 168 insertions(+), 121 deletions(-) diff --git a/PSTK.psd1 b/PSTK.psd1 index d0af731..4e9a3e5 100644 --- a/PSTK.psd1 +++ b/PSTK.psd1 @@ -3,7 +3,7 @@ # # Generated by: Florian Carrier # -# Generated on: 11/09/2024 +# Generated on: 16/09/2024 # @{ diff --git a/Private/Read-Properties.ps1 b/Private/Read-Properties.ps1 index 870c01c..89600da 100644 --- a/Private/Read-Properties.ps1 +++ b/Private/Read-Properties.ps1 @@ -1,122 +1,157 @@ -# ------------------------------------------------------------------------------ -# Properties parsing function -# ------------------------------------------------------------------------------ function Read-Properties { - <# - .SYNOPSIS - Parse properties file + <# + .SYNOPSIS + Parse properties file - .DESCRIPTION - Parse properties file to generate configuration variables + .DESCRIPTION + Parse properties file to generate configuration variables - .PARAMETER Path - The patch parameter corresponds to the path to the property file to read. + .PARAMETER Path + [String] The patch parameter corresponds to the path to the property file to read. - .PARAMETER Section - [Switch] The Section parameter indicates if properties should be grouped depending on - existing sections in the file. + .PARAMETER Section + [Switch] The Section parameter indicates if properties should be grouped depending on existing sections in the file. - .OUTPUTS - [System.Collections.Specialized.OrderedDictionary] Read-Properties returns an - ordered hash table containing the content of the property file. + .PARAMETER Metadata + [Switch] The metadata parameter indicates that the value (data) as well as the description and section (metadata) should be returned. This does not apply is the section switch is enabled. - .EXAMPLE - Read-Properties -Path ".\conf\default.ini" -Section + .OUTPUTS + [System.Collections.Specialized.OrderedDictionary] Read-Properties returns an ordered hash table containing the content of the property file. - In this example, Read-Properties will parse the default.ini file contained - in the .\conf directory and generate an ordered hashtable containing the - key-values pairs. - #> - [CmdletBinding ()] - Param ( - [Parameter ( - Position = 1, - Mandatory = $true, - HelpMessage = "Path to the property file" - )] - [ValidateNotNullOrEmpty ()] - [String] - $Path, - [Parameter ( - Position = 3, - Mandatory = $false, - HelpMessage = "Define if section headers should be used to group properties or be ignored" - )] - [Switch] - $Section - ) - Begin { - # Get global preference variables - Get-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState - # Instantiate variables - $Properties = New-Object -TypeName "System.Collections.Specialized.OrderedDictionary" - $Sections = New-Object -TypeName "System.Collections.Specialized.OrderedDictionary" - $Header = $null - $errors = 0 - } - Process { - # Check that the file exists - if (Test-Path -Path $Path) { - $ListOfProperties = Get-Content -Path $Path - $LineNumber = 0 - # Read the property file line by line - foreach ($Property in $ListOfProperties) { - $LineNumber += 1 - # If properties have to be grouped by section - if ($Section) { - # If end of file and section is open - if ($LineNumber -eq $ListOfProperties.Count -And $Header) { - if ($Property[0] -ne "#" -And $Property[0] -ne ";" -And $Property -ne "") { - $Property = Read-Property -Property $Property - if ($Property.Count -gt 0) { - $Sections.Add($Property.Key, $Property.Value) - } else { - Write-Log -Type "WARN" -Message "Unable to process line $LineNumber from $Path" - } - } - $Clone = Copy-OrderedHashtable -Hashtable $Sections -Deep - $Properties.Add($Header, $Clone) - } elseif ($Property[0] -eq "[") { - # If previous section exists add it to the property list - if ($Header) { - $Clone = Copy-OrderedHashtable -Hashtable $Sections -Deep - $Properties.Add($Header, $Clone) - } - # Create new property group - $Header = $Property.Substring(1, $Property.Length - 2) - $Sections.Clear() - } elseif ($Header -And $Property[0] -ne "#" -And $Property[0] -ne ";" -And $Property -ne "") { - $Property = Read-Property -Property $Property - if ($Property.Count -gt 0) { - $Sections.Add($Property.Key, $Property.Value) - } else { - Write-Log -Type "WARN" -Message "Unable to process line $LineNumber from $Path" - } - } - } else { - # Ignore comments, sections, and blank lines - if ($Property[0] -ne "#" -And $Property[0] -ne ";" -And $Property[0] -ne "[" -And $Property -ne "") { - $Property = Read-Property -Property $Property - if ($Property.Count -gt 0) { - try { - $Properties.Add($Property.Key, $Property.Value) - } catch { - Write-Log -Type "WARN" -Object "Two distinct definitions of the property $($Property.Key) have been found in the configuration file" - $Errors += 1 - } - } else { - Write-Log -Type "WARN" -Message "Unable to process line $LineNumber from $Path" - } - } - } - } - } else { - # Alert that configuration file does not exist at specified location - Write-Log -Type "ERROR" -Message "Path not found $Path" -ExitCode 1 - } - if ($Errors -gt 0) { - Write-Log -Type "ERROR" -Object "Unable to proceed. Resolve the issues in $Path" -ExitCode 1 - } - return $Properties - } + .EXAMPLE + Read-Properties -Path ".\conf\default.ini" -Section + + In this example, Read-Properties will parse the default.ini file contained in the .\conf directory and generate an ordered hashtable containing the key-values pairs. + + .NOTES + File name: Read-Properties.ps1 + Author: Florian Carrier + Creation date: 2018-11-27 + Last modified: 2024-09-13 + #> + [CmdletBinding ()] + Param ( + [Parameter ( + Position = 1, + Mandatory = $true, + HelpMessage = "Path to the property file" + )] + [ValidateNotNullOrEmpty ()] + [String] + $Path, + [Parameter ( + Position = 3, + Mandatory = $false, + HelpMessage = "Define if section headers should be used to group properties or be ignored" + )] + [Switch] + $Section, + [Parameter ( + HelpMessage = "Switch to retrieve metadata about properties" + )] + [Switch] + $Metadata + ) + Begin { + # Get global preference variables + Get-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState + } + Process { + # Check that the file exists + if (Test-Path -Path $Path) { + # Load property file content + $Content = Get-Content -Path $Path + # Instantiate variables + $Properties = New-Object -TypeName "System.Collections.Specialized.OrderedDictionary" + $Sections = New-Object -TypeName "System.Collections.Specialized.OrderedDictionary" + $Errors = 0 + $LineNumber = 0 + $Header = $null + $PreviousLine = $null + # Read content line by line + foreach ($Line in $Content) { + $LineNumber += 1 + # If properties have to be grouped by section + if ($Section) { + # If end of file and section is open + if ($LineNumber -eq $Content.Count -And $Header) { + if ($Line[0] -ne "#" -And $Line[0] -ne ";" -And $Line -ne "") { + $Property = Read-Property -Property $Line + if ($Property.Count -gt 0) { + $Sections.Add($Property.Key, $Property.Value) + } else { + Write-Log -Type "WARN" -Message "Unable to process line $LineNumber from $Path" + } + } + $Clone = Copy-OrderedHashtable -Hashtable $Sections -Deep + $Properties.Add($Header, $Clone) + } elseif ($Line[0] -eq "[") { + # If previous section exists add it to the property list + if ($Header) { + $Clone = Copy-OrderedHashtable -Hashtable $Sections -Deep + $Properties.Add($Header, $Clone) + } + # Create new property group + $Header = $Line.Substring(1, $Line.Length - 2) + $Sections.Clear() + } elseif ($Header -And $Line[0] -ne "#" -And $Line[0] -ne ";" -And $Line -ne "") { + $Property = Read-Property -Property $Line + if ($Property.Count -gt 0) { + $Sections.Add($Property.Key, $Property.Value) + } else { + Write-Log -Type "WARN" -Message "Unable to process line $LineNumber from $Path" + } + } + } else { + # Parse rows + if ($null -eq $Line -or $Line -eq "") { + # Ignore empty lines + } elseif ($Line[0] -eq "[") { + # Parse sections + $Header = $Line.Substring(1, $Line.Length - 2).Trim() + } elseif ($Line[0] -eq "#" -Or $Line[0] -eq ";" ) { + # Parse comments + $PreviousLine = $Line.Substring(1, $Line.Length - 1).Trim() + } else { + # Parse properties + $Property = Read-Property -Property $Line + if ($Property.Count -gt 0) { + if ($Metadata -eq $true) { + # Create custom object including metadata + $Value = [Ordered]@{ + "Value" = $Property.Value + "Description" = $PreviousLine + "Section" = $Header + } + } else { + # Return raw value + $Value = $Property.Value + } + try { + # Assign property + $Properties.Add($Property.Key, $Value) + } catch { + Write-Log -Type "WARN" -Object "Two distinct definitions of the property $($Property.Key) have been found in the configuration file" + $Errors += 1 + } + # Reset metadata + $PreviousLine = $null + } else { + Write-Log -Type "WARN" -Message "Unable to process line $LineNumber from $Path" + } + } + } + } + } else { + # Alert that configuration file does not exist at specified location + Write-Log -Type "ERROR" -Message "Path not found $Path" -ExitCode 1 + } + if ($Errors -gt 0) { + Write-Log -Type "ERROR" -Object "Unable to proceed. Resolve the issues in $Path" -ExitCode 1 + } + } + End { + # Return list of properties + return $Properties + } } diff --git a/Public/Get-Properties.ps1 b/Public/Get-Properties.ps1 index 6affc9c..5aecfca 100644 --- a/Public/Get-Properties.ps1 +++ b/Public/Get-Properties.ps1 @@ -38,10 +38,10 @@ function Get-Properties { default ones with the custom ones. .NOTES - File name: Properties.ps1 + File name: Get-Properties.ps1 Author: Florian Carrier Creation date: 2018-11-27 - Last modified: 2023-03-23 + Last modified: 2024-09-13 Comment: Get-Properties does not currently allow the use of sections to group properties in custom files #> [CmdletBinding (DefaultParameterSetName = "File")] @@ -109,13 +109,19 @@ function Get-Properties { HelpMessage = "Define if section headers should be used to group properties or be ignored" )] [Switch] - $Section + $Section, + [Parameter ( + HelpMessage = "Switch to retrieve metadata about properties" + )] + [Switch] + $Metadata ) Begin { # Get global preference variables Get-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState } Process { + # Build paths if ($PSCmdlet.ParameterSetName -eq "File") { # Check that specified file exists $Path = Join-Path -Path $Directory -ChildPath $File @@ -125,19 +131,25 @@ function Get-Properties { $CustomPath = Join-Path -Path $CustomDirectory -ChildPath $Custom } } + # Check path if (Test-Path -Path $Path) { # Parse properties with or without section split - $Properties = Read-Properties -Path $Path -Section:$Section + $Properties = Read-Properties -Path $Path -Section:$Section -Metadata:$Metadata # Check if a custom file is provided if ($CustomPath) { # Make sure said file does exists if (Test-Path -Path $CustomPath) { # Override default properties with custom ones - $Customs = Read-Properties -Path $CustomPath + $Customs = Read-Properties -Path $CustomPath -Metadata:$Metadata foreach ($Property in $Customs.Keys) { # Override default with custom if (Find-Key -Hashtable $Properties -Key $Property) { - $Properties.$Property = $Customs.$Property + if ($Metadata -eq $true) { + # Update value but retain metadata + $Properties.$Property.Value = $Customs.$Property.Value + } else { + $Properties.$Property = $Customs.$Property + } } else { Write-Log -Type "WARN" -Object "The ""$Property"" property defined in $Custom is unknown" } From 131250fd4460f183ddb71b1f78a2fb9f0ca2d097 Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Wed, 18 Sep 2024 17:33:21 +0200 Subject: [PATCH 17/19] Revert "Disable WhatIf" This reverts commit e626bf201fd5ff1eba0479c6c62dd9b2be5598e7. --- Public/Stop-Script.ps1 | 97 +++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/Public/Stop-Script.ps1 b/Public/Stop-Script.ps1 index 46c4746..b682ecd 100644 --- a/Public/Stop-Script.ps1 +++ b/Public/Stop-Script.ps1 @@ -1,58 +1,57 @@ function Stop-Script { - <# - .SYNOPSIS - Stop script + <# + .SYNOPSIS + Stop script - .DESCRIPTION - Exit script, set exit code, disable stric-mode, and stop transcript if any. + .DESCRIPTION + Exit script, set exit code, disable stric-mode, and stop transcript if any. - .PARAMETER ExitCode - The exit code parameter corresponds to the error code thrown after exiting - the script. Default is 0 (i.e. no errors). + .PARAMETER ExitCode + The exit code parameter corresponds to the error code thrown after exiting + the script. Default is 0 (i.e. no errors). - .EXAMPLE - Stop-Script + .EXAMPLE + Stop-Script - In this example, Stop-Script will set strict mode off, stop the transcript - if any is currently active, and exit the script with error code 0. + In this example, Stop-Script will set strict mode off, stop the transcript + if any is currently active, and exit the script with error code 0. - .EXAMPLE - Stop-Script -ExitCode 1 + .EXAMPLE + Stop-Script -ExitCode 1 - In this example, Stop-Script will set strict mode off, stop the transcript - if any is currently active, and exit the script with error code 1. + In this example, Stop-Script will set strict mode off, stop the transcript + if any is currently active, and exit the script with error code 1. - .NOTES - File name: Stop-Script.ps1 - Author: Florian Carrier - Creation date: 2018-10-15 - Last modified: 2024-09-16 - #> - [CmdletBinding ()] - Param ( - [Parameter ( - Position = 1, - Mandatory = $false, - HelpMessage = "Script exit code" - )] - [Alias ( - "Code", - "ErrorCode", - "ReturnCode" - )] - [Int] - $ExitCode = 0 - ) - Begin { - Set-StrictMode -Off - try { - # Disable WhatIf to ensure transcripts are always stopped - Stop-Transcript -WhatIf:$false - } catch { - Write-Log -Type "WARN" -Message "No transcript is being produced" - } - } - Process { - exit $ExitCode - } + .NOTES + File name: Stop-Script.ps1 + Author: Florian Carrier + Creation date: 2018-10-15 + Last modified: 2019-12-17 + #> + [CmdletBinding ()] + Param ( + [Parameter ( + Position = 1, + Mandatory = $false, + HelpMessage = "Script exit code" + )] + [Alias ( + "Code", + "ErrorCode", + "ReturnCode" + )] + [Int] + $ExitCode = 0 + ) + Begin { + Set-StrictMode -Off + try { + Stop-Transcript + } catch { + Write-Log -Type "WARN" -Message "No transcript is being produced" + } + } + Process { + exit $ExitCode + } } From e680ffc15e8374348fd5596d0200b61ee116d55a Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Mon, 23 Sep 2024 18:29:42 +0200 Subject: [PATCH 18/19] Add Get-PowerShellError --- PSTK.psd1 | 30 +++++++-------- Public/Get-PowerShellError.ps1 | 68 ++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 15 deletions(-) create mode 100644 Public/Get-PowerShellError.ps1 diff --git a/PSTK.psd1 b/PSTK.psd1 index 4e9a3e5..33e4dfb 100644 --- a/PSTK.psd1 +++ b/PSTK.psd1 @@ -3,7 +3,7 @@ # # Generated by: Florian Carrier # -# Generated on: 16/09/2024 +# Generated on: 23/09/2024 # @{ @@ -75,20 +75,20 @@ FunctionsToExport = 'Compare-Hashtable', 'Compare-Properties', 'Compare-Version' 'ConvertTo-RegularExpression', 'Copy-Object', 'Copy-OrderedHashtable', 'Expand-CompressedFile', 'Find-Key', 'Format-String', 'Get-CallerPreference', 'Get-EnvironmentVariable', 'Get-HTTPStatus', - 'Get-KeyValue', 'Get-Object', 'Get-Path', 'Get-Properties', 'Get-URI', - 'Import-CSVProperties', 'Import-Function', 'Import-Properties', - 'Invoke-OracleCmd', 'New-DynamicParameter', 'New-ProcessObject', - 'New-RandomPassword', 'New-SelfContainedPackage', 'Out-Hashtable', - 'Ping-Host', 'Protect-WindowsCmdValue', 'Remove-EnvironmentVariable', - 'Remove-Object', 'Rename-NumberedFile', 'Resolve-Array', - 'Resolve-Boolean', 'Resolve-Tags', 'Resolve-URI', 'Select-XMLNode', - 'Set-EnvironmentVariable', 'Set-RelativePath', 'Set-Tags', - 'Show-EnvironmentVariables', 'Start-Script', 'Stop-AllTranscripts', - 'Stop-Script', 'Sync-EnvironmentVariable', 'Test-EnvironmentVariable', - 'Test-HTTPStatus', 'Test-Object', 'Test-OracleConnection', - 'Test-Service', 'Test-SQLConnection', 'Update-File', - 'Update-ProcessObject', 'Wait-WebResource', 'Write-Checksum', - 'Write-ErrorLog', 'Write-InsertOrUpdate', 'Write-Log' + 'Get-KeyValue', 'Get-Object', 'Get-Path', 'Get-PowerShellError', + 'Get-Properties', 'Get-URI', 'Import-CSVProperties', 'Import-Function', + 'Import-Properties', 'Invoke-OracleCmd', 'New-DynamicParameter', + 'New-ProcessObject', 'New-RandomPassword', 'New-SelfContainedPackage', + 'Out-Hashtable', 'Ping-Host', 'Protect-WindowsCmdValue', + 'Remove-EnvironmentVariable', 'Remove-Object', 'Rename-NumberedFile', + 'Resolve-Array', 'Resolve-Boolean', 'Resolve-Tags', 'Resolve-URI', + 'Select-XMLNode', 'Set-EnvironmentVariable', 'Set-RelativePath', + 'Set-Tags', 'Show-EnvironmentVariables', 'Start-Script', + 'Stop-AllTranscripts', 'Stop-Script', 'Sync-EnvironmentVariable', + 'Test-EnvironmentVariable', 'Test-HTTPStatus', 'Test-Object', + 'Test-OracleConnection', 'Test-Service', 'Test-SQLConnection', + 'Update-File', 'Update-ProcessObject', 'Wait-WebResource', + 'Write-Checksum', 'Write-ErrorLog', 'Write-InsertOrUpdate', 'Write-Log' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() diff --git a/Public/Get-PowerShellError.ps1 b/Public/Get-PowerShellError.ps1 new file mode 100644 index 0000000..f53586e --- /dev/null +++ b/Public/Get-PowerShellError.ps1 @@ -0,0 +1,68 @@ +function Get-PowerShellError { + <# + .SYNOPSIS + Get latest error + + .DESCRIPTION + Retrieve latest PowerShell error to occur similar to Get-Help in version 7 + + .NOTES + File name: Get-PowerShellError.ps1 + Author: Florian Carrier + Creation date: 2024-09-23 + Last modified: 2024-09-23 + #> + [CmdletBinding ()] + Param () + Begin { + # Get global preference vrariables + Get-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState + # Log function call + Write-Log -Type "DEBUG" -Message $MyInvocation.MyCommand.Name + } + Process { + # Fetch latest error + $PSError = $PSCmdlet.GetVariableValue('Error') + $LatestErrorRecord = $PSError[0] + # Build error object + $LatestError = [PSCustomObject]@{ + Exception = if ($LatestErrorRecord.Exception) { $LatestErrorRecord.Exception.GetType().FullName } else { "N/A" } + Message = if ($LatestErrorRecord.Exception) { $LatestErrorRecord.Exception.Message } else { $LatestErrorRecord.ToString() } + Data = if ($LatestErrorRecord.Exception) { $LatestErrorRecord.Exception.Data } else { "N/A" } + InnerException = if ($LatestErrorRecord.Exception -and $LatestErrorRecord.Exception.InnerException) { $LatestErrorRecord.Exception.InnerException.Message } else { "N/A" } + TargetSite = if ($LatestErrorRecord.Exception) { $LatestErrorRecord.Exception.TargetSite } else { "N/A" } + StackTrace = if ($LatestErrorRecord.Exception) { $LatestErrorRecord.Exception.StackTrace } else { "N/A" } + HelpLink = if ($LatestErrorRecord.Exception) { $LatestErrorRecord.Exception.HelpLink } else { "N/A" } + Source = if ($LatestErrorRecord.Exception) { $LatestErrorRecord.Exception.Source } else { "N/A" } + HResult = if ($LatestErrorRecord.Exception) { $LatestErrorRecord.Exception.HResult } else { "N/A" } + CategoryInfo = $LatestErrorRecord.CategoryInfo + FullyQualifiedErrorId = $LatestErrorRecord.FullyQualifiedErrorId + ScriptStackTrace = $LatestErrorRecord.ScriptStackTrace + } + # Add invocation information + $InvocationInfo = $LatestErrorRecord.InvocationInfo + if ($InvocationInfo) { + $LatestError | Add-Member -MemberType "NoteProperty" -Name "InvocationInfo" -Value ([PSCustomObject]@{ + MyCommand = $InvocationInfo.MyCommand + BoundParameters = $InvocationInfo.BoundParameters + UnboundArguments = $InvocationInfo.UnboundArguments + ScriptLineNumber = $InvocationInfo.ScriptLineNumber + OffsetInLine = $InvocationInfo.OffsetInLine + HistoryId = $InvocationInfo.HistoryId + ScriptName = $InvocationInfo.ScriptName + Line = $InvocationInfo.Line + PositionMessage = $InvocationInfo.PositionMessage + PSScriptRoot = $InvocationInfo.PSScriptRoot + PSCommandPath = $InvocationInfo.PSCommandPath + InvocationName = $InvocationInfo.InvocationName + PipelineLength = $InvocationInfo.PipelineLength + PipelinePosition = $InvocationInfo.PipelinePosition + ExpectingInput = $InvocationInfo.ExpectingInput + CommandOrigin = $InvocationInfo.CommandOrigin + }) + } + } + End { + return $LatestError + } +} \ No newline at end of file From f72cefa52c78d43d8d08c55910cf3a5d7bd44fdb Mon Sep 17 00:00:00 2001 From: Florian Carrier Date: Mon, 7 Oct 2024 10:54:27 +0200 Subject: [PATCH 19/19] Update documentation --- CHANGELOG.md | 23 +++++++-- PSTK.psd1 | 2 +- README.md | 129 ++++++++++++++++++++++++++------------------------- 3 files changed, 88 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 659f92c..8e94509 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,14 +5,31 @@ All notable changes to the [PSTK](https://github.com/Akaizoku/PSTK) project will The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [1.2.6](https://github.com/Akaizoku/PSTK/compare/1.2.5...develop) - Unreleased +## [1.2.6](https://github.com/Akaizoku/PSTK/releases/1.2.6) - 2024-10-07 + +Quality of life ### Added The following functions have been added: -- Ping-Host -- Show-EnvironmentVariables +- Ping-Host: Check connectivity to a specified host +- Show-EnvironmentVariables: Fetch environment variables +- Get-PowerShellError: Returns the latest error +- New-ProcessObject: Create standardised process object to monitor custom processes +- Update-ProcessObject: Update standardised process object to monitor custom processes + +### Changed + +The following functions have been updated: + +- Get-Properties: Now provides an option to pull metadata such as section and description +- Read-Properties: Now provides an option to pull metadata such as section and description +- Write-Log: Added notice message option + +### Fixed + +- Compare-Version: Fixed version comparison issues by using built-in version compare function when applciable ## [1.2.5](https://github.com/Akaizoku/PSTK/releases/1.2.5) - 2021-11-21 diff --git a/PSTK.psd1 b/PSTK.psd1 index 33e4dfb..e12f06c 100644 --- a/PSTK.psd1 +++ b/PSTK.psd1 @@ -3,7 +3,7 @@ # # Generated by: Florian Carrier # -# Generated on: 23/09/2024 +# Generated on: 24/09/2024 # @{ diff --git a/README.md b/README.md index 4f1fb09..3fe3d49 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ PowerShell Tool Kit (PSTK) is a library containing a collection of useful PowerS There are two methods of setting up the PowerShell Tool Kit module on your system: -1. Download the PSTK module from the [GitHub repository](https://github.com/Akaizoku/PSTK); -1. Install the PSTK module from the [PowerShell Gallery](https://www.powershellgallery.com/packages/PSTK). +1. Download the PSTK module from the [GitHub repository](https://github.com/Akaizoku/PSTK) and extract it in the `PSModulePath` environment variable location; +2. Install the PSTK module from the [PowerShell Gallery](https://www.powershellgallery.com/packages/PSTK). ```powershell Install-Module -Name "PSTK" -Repository "PSGallery" @@ -30,66 +30,71 @@ Get-Command -Module "PSTK" ``` | CommandType | Name | Version | Source | -| ----------- | --------------------------- | ------: | ------ | -| Function | Compare-Hashtable | 1.2.5 | PSTK | -| Function | Compare-Properties | 1.2.5 | PSTK | -| Function | Compare-Version | 1.2.5 | PSTK | -| Function | Complete-RelativePath | 1.2.5 | PSTK | -| Function | Confirm-Prompt | 1.2.5 | PSTK | -| Function | Convert-FileEncoding | 1.2.5 | PSTK | -| Function | ConvertTo-JavaProperty | 1.2.5 | PSTK | -| Function | ConvertTo-NaturalSort | 1.2.5 | PSTK | -| Function | ConvertTo-PDF | 1.2.5 | PSTK | -| Function | ConvertTo-RegularExpression | 1.2.5 | PSTK | -| Function | Copy-Object | 1.2.5 | PSTK | -| Function | Copy-OrderedHashtable | 1.2.5 | PSTK | -| Function | Expand-CompressedFile | 1.2.5 | PSTK | -| Function | Find-Key | 1.2.5 | PSTK | -| Function | Format-String | 1.2.5 | PSTK | -| Function | Get-CallerPreference | 1.2.5 | PSTK | -| Function | Get-EnvironmentVariable | 1.2.5 | PSTK | -| Function | Get-HTTPStatus | 1.2.5 | PSTK | -| Function | Get-KeyValue | 1.2.5 | PSTK | -| Function | Get-Object | 1.2.5 | PSTK | -| Function | Get-Path | 1.2.5 | PSTK | -| Function | Get-Properties | 1.2.5 | PSTK | -| Function | Get-URI | 1.2.5 | PSTK | -| Function | Import-CSVProperties | 1.2.5 | PSTK | -| Function | Import-Function | 1.2.5 | PSTK | -| Function | Import-Properties | 1.2.5 | PSTK | -| Function | Invoke-OracleCmd | 1.2.5 | PSTK | -| Function | New-DynamicParameter | 1.2.5 | PSTK | -| Function | New-RandomPassword | 1.2.5 | PSTK | -| Function | New-SelfContainedPackage | 1.2.5 | PSTK | -| Function | Out-Hashtable | 1.2.5 | PSTK | -| Function | Protect-WindowsCmdValue | 1.2.5 | PSTK | -| Function | Remove-EnvironmentVariable | 1.2.5 | PSTK | -| Function | Remove-Object | 1.2.5 | PSTK | -| Function | Rename-NumberedFile | 1.2.5 | PSTK | -| Function | Resolve-Array | 1.2.5 | PSTK | -| Function | Resolve-Boolean | 1.2.5 | PSTK | -| Function | Resolve-Tags | 1.2.5 | PSTK | -| Function | Resolve-URI | 1.2.5 | PSTK | -| Function | Select-XMLNode | 1.2.5 | PSTK | -| Function | Set-EnvironmentVariable | 1.2.5 | PSTK | -| Function | Set-RelativePath | 1.2.5 | PSTK | -| Function | Set-Tags | 1.2.5 | PSTK | -| Function | Start-Script | 1.2.5 | PSTK | -| Function | Stop-AllTranscripts | 1.2.5 | PSTK | -| Function | Stop-Script | 1.2.5 | PSTK | -| Function | Sync-EnvironmentVariable | 1.2.5 | PSTK | -| Function | Test-EnvironmentVariable | 1.2.5 | PSTK | -| Function | Test-HTTPStatus | 1.2.5 | PSTK | -| Function | Test-Object | 1.2.5 | PSTK | -| Function | Test-OracleConnection | 1.2.5 | PSTK | -| Function | Test-Service | 1.2.5 | PSTK | -| Function | Test-SQLConnection | 1.2.5 | PSTK | -| Function | Update-File | 1.2.5 | PSTK | -| Function | Wait-WebResource | 1.2.5 | PSTK | -| Function | Write-Checksum | 1.2.5 | PSTK | -| Function | Write-ErrorLog | 1.2.5 | PSTK | -| Function | Write-InsertOrUpdate | 1.2.5 | PSTK | -| Function | Write-Log | 1.2.5 | PSTK | +| :---------- | :-------------------------- | ------: | :----- | +| Function | Compare-Hashtable | 1.2.6 | PSTK | +| Function | Compare-Properties | 1.2.6 | PSTK | +| Function | Compare-Version | 1.2.6 | PSTK | +| Function | Complete-RelativePath | 1.2.6 | PSTK | +| Function | Confirm-Prompt | 1.2.6 | PSTK | +| Function | Convert-FileEncoding | 1.2.6 | PSTK | +| Function | ConvertTo-JavaProperty | 1.2.6 | PSTK | +| Function | ConvertTo-NaturalSort | 1.2.6 | PSTK | +| Function | ConvertTo-PDF | 1.2.6 | PSTK | +| Function | ConvertTo-RegularExpression | 1.2.6 | PSTK | +| Function | Copy-Object | 1.2.6 | PSTK | +| Function | Copy-OrderedHashtable | 1.2.6 | PSTK | +| Function | Expand-CompressedFile | 1.2.6 | PSTK | +| Function | Find-Key | 1.2.6 | PSTK | +| Function | Format-String | 1.2.6 | PSTK | +| Function | Get-CallerPreference | 1.2.6 | PSTK | +| Function | Get-EnvironmentVariable | 1.2.6 | PSTK | +| Function | Get-HTTPStatus | 1.2.6 | PSTK | +| Function | Get-KeyValue | 1.2.6 | PSTK | +| Function | Get-Object | 1.2.6 | PSTK | +| Function | Get-Path | 1.2.6 | PSTK | +| Function | Get-PowerShellError | 1.2.6 | PSTK | +| Function | Get-Properties | 1.2.6 | PSTK | +| Function | Get-URI | 1.2.6 | PSTK | +| Function | Import-CSVProperties | 1.2.6 | PSTK | +| Function | Import-Function | 1.2.6 | PSTK | +| Function | Import-Properties | 1.2.6 | PSTK | +| Function | Invoke-OracleCmd | 1.2.6 | PSTK | +| Function | New-DynamicParameter | 1.2.6 | PSTK | +| Function | New-ProcessObject | 1.2.6 | PSTK | +| Function | New-RandomPassword | 1.2.6 | PSTK | +| Function | New-SelfContainedPackage | 1.2.6 | PSTK | +| Function | Out-Hashtable | 1.2.6 | PSTK | +| Function | Ping-Host | 1.2.6 | PSTK | +| Function | Protect-WindowsCmdValue | 1.2.6 | PSTK | +| Function | Remove-EnvironmentVariable | 1.2.6 | PSTK | +| Function | Remove-Object | 1.2.6 | PSTK | +| Function | Rename-NumberedFile | 1.2.6 | PSTK | +| Function | Resolve-Array | 1.2.6 | PSTK | +| Function | Resolve-Boolean | 1.2.6 | PSTK | +| Function | Resolve-Tags | 1.2.6 | PSTK | +| Function | Resolve-URI | 1.2.6 | PSTK | +| Function | Select-XMLNode | 1.2.6 | PSTK | +| Function | Set-EnvironmentVariable | 1.2.6 | PSTK | +| Function | Set-RelativePath | 1.2.6 | PSTK | +| Function | Set-Tags | 1.2.6 | PSTK | +| Function | Show-EnvironmentVariables | 1.2.6 | PSTK | +| Function | Start-Script | 1.2.6 | PSTK | +| Function | Stop-AllTranscripts | 1.2.6 | PSTK | +| Function | Stop-Script | 1.2.6 | PSTK | +| Function | Sync-EnvironmentVariable | 1.2.6 | PSTK | +| Function | Test-EnvironmentVariable | 1.2.6 | PSTK | +| Function | Test-HTTPStatus | 1.2.6 | PSTK | +| Function | Test-Object | 1.2.6 | PSTK | +| Function | Test-OracleConnection | 1.2.6 | PSTK | +| Function | Test-Service | 1.2.6 | PSTK | +| Function | Test-SQLConnection | 1.2.6 | PSTK | +| Function | Update-File | 1.2.6 | PSTK | +| Function | Update-ProcessObject | 1.2.6 | PSTK | +| Function | Wait-WebResource | 1.2.6 | PSTK | +| Function | Write-Checksum | 1.2.6 | PSTK | +| Function | Write-ErrorLog | 1.2.6 | PSTK | +| Function | Write-InsertOrUpdate | 1.2.6 | PSTK | +| Function | Write-Log | 1.2.6 | PSTK | ## Dependencies