610 lines
19 KiB
PowerShell
610 lines
19 KiB
PowerShell
Function Test-CommandExists {
|
|
<#
|
|
.SYNOPSIS
|
|
Returns true if a command is present in PowerShell
|
|
|
|
.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
|
|
https://devblogs.microsoft.com/scripting/use-a-powershell-function-to-see-if-a-command-exists/
|
|
|
|
.NOTES
|
|
Detail on what the script does, if this is needed.
|
|
|
|
#>
|
|
Param (
|
|
[Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $Command
|
|
)
|
|
Try {
|
|
If (Get-Command $Command -ErrorAction Stop) { Return $true }
|
|
}
|
|
Catch { Return $false }
|
|
}
|
|
|
|
Function Add-LogEntry {
|
|
<#
|
|
.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()] [String] $Message,
|
|
[Parameter(Mandatory = $false)] [ValidateSet('Notify', 'Warning', 'Error', 'Debug')] [String] $As,
|
|
[Parameter(Mandatory = $false)] [Switch] $NewLine
|
|
)
|
|
Switch ($As) {
|
|
"Notify" { $FGC = "Cyan" }
|
|
"Warning" { $FGC = "Yellow" }
|
|
"Error" { $FGC = "Red" }
|
|
"Debug" { $FGC = "Magenta" }
|
|
Default { $FGC = "White" }
|
|
}
|
|
|
|
If ($Newline) { $Output += "`n" }
|
|
$Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
|
$Output += "[$Timestamp] $Message"
|
|
If ($As -eq "Debug") { If ($Dev) { Write-Host $Output -ForegroundColor $FGC } }
|
|
Else { Write-Host $Output -ForegroundColor $FGC }
|
|
}
|
|
|
|
Function Add-ListItem () {
|
|
<#
|
|
.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()] [String] $Message,
|
|
[Parameter(Mandatory = $false)] [Int16] $Indent = 0
|
|
)
|
|
|
|
For ($Counter = 0; $Counter -le $Indent; $Counter++) { $Output += " " }
|
|
$Output += "* $Message"
|
|
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
|
|
}
|
|
}
|
|
}
|
|
|
|
Import-Modules {
|
|
<#
|
|
.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)] $ModuleList
|
|
)
|
|
If ($ModuleList) {
|
|
Initialize-PSGallery
|
|
ForEach ($Module in $ModuleList) {
|
|
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
|
|
}
|
|
}
|
|
}
|
|
|
|
Function Import-JSONConfig () {
|
|
<#
|
|
.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()] [String] $ConfigFile
|
|
)
|
|
If (Test-Path -Path $ConfigFile) {
|
|
Try {
|
|
Return (Get-Content -Raw -Path $ConfigFile | ConvertFrom-Json)
|
|
}
|
|
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 "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-YAMLConfig () {
|
|
<#
|
|
.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()] [String] $ConfigFile
|
|
)
|
|
|
|
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
|
|
}
|
|
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 "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 Import-Config () {
|
|
<#
|
|
.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 {
|
|
Switch ((Get-Item -Path $ConfigFile).Extension.ToLower()) {
|
|
{ @( ".yml", ".yaml").Contains($_) } { Return (Import-YAMLConfig $ConfigFile) }
|
|
{ @( ".jsn", ".json").Contains($_) } { Return (Import-JSONConfig $ConfigFile) }
|
|
{ @( ".csv").Contains($_) } { Return (Import-CSVConfig $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 file" -As Error
|
|
Write-Host $_
|
|
Exit
|
|
}
|
|
}
|
|
|
|
Function Set-RegistryKey {
|
|
Param(
|
|
[Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] $TestPath,
|
|
[Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] $TestKey,
|
|
[Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] $TestValue,
|
|
[Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] $TestType
|
|
)
|
|
If (-Not (Test-Path -Path $TestPath)) {
|
|
Add-LogEntry "Registry path not found, creating..."
|
|
New-Item $TestPath -Force -ErrorAction SilentlyContinue | Out-Null
|
|
}
|
|
If ($null -ne (Get-Item -Path $TestPath).GetValue($TestKey)) {
|
|
If ((Get-ItemPropertyValue -Path $TestPath -Name $TestKey) -eq $TestValue) {
|
|
Add-LogEntry "Current key value is `"$((Get-Item -Path $TestPath).GetValue($TestKey))`", no action needed"
|
|
}
|
|
Else {
|
|
Add-LogEntry "Setting value of `"$($TestKey)`" to `"$($TestValue)`""
|
|
Set-ItemProperty -Path $TestPath -Name $TestKey -Value $TestValue
|
|
}
|
|
}
|
|
Else {
|
|
Add-LogEntry "Registry key does not exist, creating..."
|
|
New-ItemProperty -Path $TestPath -Name $TestKey -Value $TestValue -PropertyType $TestType -Force -ErrorAction SilentlyContinue | Out-Null
|
|
}
|
|
}
|
|
|
|
Function Save-Parameters {
|
|
Param ([hashtable]$NamedParameters)
|
|
Return ($NamedParameters.GetEnumerator() | ForEach-Object { "-$($_.Key) `"$($_.Value)`"" }) -join " "
|
|
}
|
|
|
|
Function Test-AsAdmin () {
|
|
<#
|
|
.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 = $false)] [String] $AdditionalFlags
|
|
)
|
|
Add-LogEntry "Checking to see if script has been run with administrative privileges"
|
|
if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
|
|
Add-LogEntry "Performing script elevation, please approve the admin prompt"
|
|
Start-Sleep -Seconds 3
|
|
if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
|
|
$CommandLine = "-ExecutionPolicy Bypass -File `"" + $MyInvocation.MyCommand.Path + "`" " + (Save-Parameters $MyInvocation.BoundParameters) + " " + $MyInvocation.UnboundArguments
|
|
Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine
|
|
Exit
|
|
}
|
|
}
|
|
Else {
|
|
Add-LogEntry "Script already running as admin"
|
|
}
|
|
}
|
|
|
|
# Origin: https://lucyllewy.com/powershell-clickable-hyperlinks/
|
|
Function Format-Hyperlink {
|
|
Param(
|
|
[Parameter(ValueFromPipeline = $true, Position = 0)][ValidateNotNullOrEmpty()] [Uri] $Uri,
|
|
[Parameter(Mandatory = $false, Position = 1)] [String] $Label
|
|
)
|
|
|
|
If (($PSVersionTable.PSVersion.Major -lt 6 -or $IsWindows) -and -not $Env:WT_SESSION) {
|
|
# Fallback for Windows users not inside Windows Terminal
|
|
If ($Label) {
|
|
Return "$Label ($Uri)"
|
|
}
|
|
Return "$Uri"
|
|
}
|
|
If ($Label) {
|
|
Return "`e]8;;$Uri`e\$Label`e]8;;`e\"
|
|
}
|
|
Return "$Uri"
|
|
} |