From 3a427ec32431f2517385f94abc28b4a9cca404be Mon Sep 17 00:00:00 2001 From: Mindfang Date: Wed, 14 May 2025 16:40:31 -0500 Subject: [PATCH] Update tools and template --- PSUtilities/ScriptTemplate.ps1 | 77 +++++---------- PSUtilities/ScriptTools.ps1 | 167 ++++++++++++++++++++++++++++++--- 2 files changed, 177 insertions(+), 67 deletions(-) diff --git a/PSUtilities/ScriptTemplate.ps1 b/PSUtilities/ScriptTemplate.ps1 index 5a3e809..81d8e24 100644 --- a/PSUtilities/ScriptTemplate.ps1 +++ b/PSUtilities/ScriptTemplate.ps1 @@ -22,10 +22,10 @@ Description of objects that are output by the script. .EXAMPLE - Example of how to run the script. + .\Script-Name.ps1 -Output "Example of how to run the script" .LINK - Links to further documentation. + https://example.com/docs .NOTES NAME: @@ -46,8 +46,10 @@ param ( [Parameter(DontShow = $true)] [ValidateSet('System', 'User', 'Custom')] [String] $ScriptType = "System", # Allows adding verbose logging and what-if command simulation to the script [Parameter(DontShow = $true)] [Switch] $Dev, + # .PARAMETER ScriptDir # Allows for the script logs to output to a nonstandard location. Overrides user/computer script paths [Parameter(Mandatory = $false)] [String] $ScriptDir, + # .PARAMETER NoLog # Flag to disable log file output [Parameter(Mandatory = $false)] [Switch] $NoLog #TODO: Add additional parameters, if appropriate @@ -100,55 +102,6 @@ ForEach ($Uri in $AddonUris) { Exit $UriStatusCode } } - -# Load any modules required by script -If ($ModuleNames) { - If ([Net.ServicePointManager]::SecurityProtocol -ne [Net.SecurityProtocolType]::SystemDefault) { - Add-LogEntry "Upgrading TLS security protocol to 1.2" - Try { [Net.ServicePointManager]::SecurityProtocol = @([Net.SecurityProtocolType]::Tls, [Net.SecurityProtocolType]::Tls11, [Net.SecurityProtocolType]::Tls12) } - Catch { - Add-LogEntry "TLS upgrade failed, script is exiting" -As Error - Exit - } - } - If ((Get-PackageProvider).Name -notcontains "NuGet") { - Add-LogEntry "Installing NuGet package provider" - Try { Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -ErrorAction Stop | Out-Null } - Catch { - Add-LogEntry "Installation failed, script is exiting" -As Error - Exit - } - } - If ((Get-PSRepository).Name -notcontains "PSGallery") { - Add-LogEntry "Registering PSGallery as script source" - Try { Register-PSRepository -Default -InstallationPolicy Trusted -ErrorAction Stop } - Catch { - Add-LogEntry "Unable to register PSGallery, script is exiting" -As Error - Exit - } - } - ElseIf (Get-PSRepository | Where-Object { $_.Name -eq "PSGallery" -and $_.InstallationPolicy -ne "Trusted" }) { - Add-LogEntry "Trusting packages from PSGallery" - Try { Set-PSRepository PSGallery -InstallationPolicy Trusted -ErrorAction Stop } - Catch { - Add-LogEntry "Unable to set PSGallery as trusted, script is exiting" -As Error - Exit - } - } - ForEach ($Module in $ModuleNames) { - If (-Not (Get-Module -ListAvailable -Name $Module)) { - Try { - Add-LogEntry "Module `"$Module`" not found, installing" - Install-Module -Name $Module -Scope CurrentUser -Force -AllowClobber - } - Catch { - Add-LogEntry "Module failed to install automatically! Manaully install the module, then re-run the script." -As Error - Exit - } - } - Import-Module $Module - } -} #endregion Imports #region Functions @@ -158,8 +111,8 @@ If ($ModuleNames) { # Set the working directory for logs and additional files $ThisScript = ([IO.FileInfo]$MyInvocation.MyCommand.Definition).BaseName Switch ($ScriptType) { - "System" { $AppDir = "$Env:AppData\Mindfang\$ThisScript" } - "User" { $AppDir = "$Env:ProgramData\Mindfang\$ThisScript" } + "System" { $AppDir = "$Env:ProgramData\Mindfang\$ThisScript" } + "User" { $AppDir = "$Env:AppData\Mindfang\$ThisScript" } "Custom" { If ($ScriptDir) { $AppDir = $ScriptDir } Else { $AppDir = ([IO.FileInfo]$MyInvocation.MyCommand.Definition).Directory } @@ -178,6 +131,24 @@ If (-Not $NoLog) { } Add-LogEntry (Start-Transcript "$AppDir\$ThisScript.log" -Append) } + +# Load any modules required by script +If ($ModuleNames) { + Initialize-PSGallery + ForEach ($Module in $ModuleNames) { + If (-Not (Get-Module -ListAvailable -Name $Module)) { + Try { + Add-LogEntry "Module `"$Module`" not found, installing" + Install-Module -Name $Module -Scope CurrentUser -Force -AllowClobber + } + Catch { + Add-LogEntry "Module failed to install automatically! Manaully install the module, then re-run the script." -As Error + Exit 1 + } + } + Import-Module $Module + } +} #endregion Prep #region Execution diff --git a/PSUtilities/ScriptTools.ps1 b/PSUtilities/ScriptTools.ps1 index f384465..2acd09e 100644 --- a/PSUtilities/ScriptTools.ps1 +++ b/PSUtilities/ScriptTools.ps1 @@ -139,6 +139,85 @@ Function Add-ListItem () { Write-Host $Output } +Function Initialize-PSGallery { + <# + .SYNOPSIS + A brief description of the function or script. + + .DESCRIPTION + A longer description. + + .PARAMETER FirstParameter + Description of each of the parameters. + Note: + To make it easier to keep the comments synchronized with changes to the parameters, + the preferred location for parameter documentation comments is not here, + but within the param block, directly above each parameter. + + .PARAMETER SecondParameter + Description of each of the parameters. + + .INPUTS + Description of objects that can be piped to the script. + + .OUTPUTS + Description of objects that are output by the script. + + .EXAMPLE + Example of how to run the script. + + .LINK + Links to further documentation. + + .NOTES + Detail on what the script does, if this is needed. + + #> + Add-LogEntry "Preparing system to download modules" + If ([Net.ServicePointManager]::SecurityProtocol -ne [Net.SecurityProtocolType]::SystemDefault) { + Add-LogEntry "Upgrading TLS security protocol to 1.2" + Try { + [Net.ServicePointManager]::SecurityProtocol = @([Net.SecurityProtocolType]::Tls, [Net.SecurityProtocolType]::Tls11, [Net.SecurityProtocolType]::Tls12) + } + Catch { + Add-LogEntry "Upgrade failed, script is exiting" -As Error + Exit 1 + } + } + + If ((Get-PackageProvider).Name -notcontains "NuGet") { + Add-LogEntry "Installing NuGet package provider" + Try { + Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -ErrorAction Stop + } + Catch { + Add-LogEntry "Installation failed, script is exiting" -As Error + Exit 1 + } + } + $PSRepos = Get-PSRepository + If ($PSRepos.Name -notcontains "PSGallery") { + Add-LogEntry "Registering PSGallery as script source" + Try { + Register-PSRepository -Default -InstallationPolicy Trusted -ErrorAction Stop + } + Catch { + Add-LogEntry "Change failed, script is exiting" -As Error + Exit 1 + } + } + ElseIf ($PSRepos | Where-Object { $_.Name -eq "PSGallery" -and $_.InstallationPolicy -ne "Trusted" }) { + Add-LogEntry "Trusting scripts from PSGallery" + Try { + Set-PSRepository PSGallery -InstallationPolicy Trusted -ErrorAction Stop + } + Catch { + Add-LogEntry "Change failed, script is exiting" -As Error + Exit 1 + } + } +} + Function Import-JSONConfig () { <# .SYNOPSIS @@ -230,28 +309,88 @@ Function Import-YAMLConfig () { Param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $ConfigFile ) - If (Test-CommandExists -Command "ConvertFrom-Yaml") { - If (Test-Path -Path $ConfigFile) { - Try { - Return (Get-Content -Raw -Path $ConfigFile | ConvertFrom-Yaml) - } - Catch { - Add-LogEntry "Error loading config file! Please make sure the correct path was provided, and that it is a properly formatted JSON file" -As Error - Write-Output $_ - Exit 1 - } + + If ( -Not (Get-Module -ListAvailable -Name "powershell-yaml")) { + Add-LogEntry "Module `"powershell-yaml`" not present, but needed for YAML imports. Adding..." + Try { + Initialize-PSGallery + Install-Module -Name "powershell-yaml" -Scope CurrentUser -Force -AllowClober } - Else { + Catch { + Add-LogEntry "Module failed to install automatically! Manaully install the module, then re-run the script." -As Error + Exit 1 + } + } + + If (Test-Path -Path $ConfigFile) { + Try { + Return (Get-Content -Raw -Path $ConfigFile | ConvertFrom-Yaml) + } + Catch { Add-LogEntry "Error loading config file! Please make sure the correct path was provided, and that it is a properly formatted JSON file" -As Error Write-Output $_ Exit 1 } } Else { - Add-LogEntry "Cannot import YAML config, module `"powershell-yaml`" is not installed" + Add-LogEntry "Error loading config file! Please make sure the correct path was provided, and that it is a properly formatted JSON file" -As Error + Write-Output $_ Exit 1 - } - + } +} + +Function Import-CSVConfig () { + <# + .SYNOPSIS + A brief description of the function or script. + + .DESCRIPTION + A longer description. + + .PARAMETER FirstParameter + Description of each of the parameters. + Note: + To make it easier to keep the comments synchronized with changes to the parameters, + the preferred location for parameter documentation comments is not here, + but within the param block, directly above each parameter. + + .PARAMETER SecondParameter + Description of each of the parameters. + + .INPUTS + Description of objects that can be piped to the script. + + .OUTPUTS + Description of objects that are output by the script. + + .EXAMPLE + Example of how to run the script. + + .LINK + Links to further documentation. + + .NOTES + Detail on what the script does, if this is needed. + + #> + Param ( + [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] $ConfigFile + ) + If (Test-Path -Path $ConfigFile) { + Try { + Return (Import-Csv $ConfigFile) + } + Catch { + Add-LogEntry "Error loading config file! Please make sure the correct path was provided, and that it is a properly formatted CSV file" -As Error + Write-Host $_ + Exit + } + } + Else { + Add-LogEntry "Error loading config file! Please make sure the correct path was provided, and that it is a properly formatted CSV file" -As Error + Write-Host $_ + Exit + } } Function Set-RegistryKey {