CommonScriptFunctions.psm1

# https://powershellexplained.com/2017-05-27-Powershell-module-building-basics/

function Clear-SessionData {
 Write-Verbose 'Clearing session data'
 Get-PSSession | Remove-PSSession -Confirm:$false
}

function Import-MyModules {
 process {
  Write-Verbose ('{0}: {1}' -f $MyInvocation.MyCommand.Name, $_)
  if (-not(Get-Module -Name $_ -ListAvailable)) {
   Install-Module -Name $_ -Scope CurrentUser -AllowClobber -Confirm:$false -Force
  }
  Import-Module -Name $_ -Force -ErrorAction Stop -Verbose:$false | Out-Null
  # Get-Module -Name $_
 }
}

function New-ADSession ($dc, $cmdlets, $myUser) {
 $msgVars = $MyInvocation.MyCommand.Name, $dc, ($cmdLets -join ',')
 Write-Verbose ('{0},{1}' -f $msgVars)
 $adSession = New-PSSession -ComputerName $dc -Credential $myUser
 $sessionParams = @{
  Session      = $adSession
  Module       = 'ActiveDirectory'
  CommandName  = $cmdLets
  AllowClobber = $true
  ErrorAction  = 'SilentlyContinue'
 }
 Import-Module (Import-PSSession @sessionParams | Out-Null) -Global
}

function New-RandomPassword {
 function Get-RandomCharacters($length, $characters) {
  $random = 1..$length | ForEach-Object { Get-Random -Maximum $characters.length }
  $private:ofs = ''
  return [String]$characters[$random]
 }
 $chars = 'ABCDEFGHKLMNOPRSTUVWXYZabcdefghiklmnoprstuvwxyz1234567890!$#%&*@'
 do { $pw = (Get-RandomCharacters -length 16 -characters $chars) }
 until ($pw -match '[A-Za-z\d!$#%&*@]') # Make sure minimum criteria met using regex p@ttern.
 $pw # Output random password
}

function New-SqlOperation {
 # https://dbatools.io/getting-started/
 # https://wp.larnu.uk/an-introduction-to-parametrised-queries-with-dbatools/
 [CmdletBinding()]
 param (
  [string]$Server,
  [string]$Database,
  [System.Management.Automation.PSCredential]$Credential,
  [string]$Query,
  $Parameters,
  # Used for INSERTS and UPDATES, but can be omitted for SELECT-based statements
  [switch]$WhatIf
 )
 process {
  # Check for Module
  if (!(Get-Module -ListAvailable -Name dbatools)) { Install-Module dbatools -Scope CurrentUser }
  if (!(Get-Module -ListAvailable -Name dbatools)) {
   Write-Error -Message'Error. Module dbatools not found'-Category InvalidOperation
   return
  }
  Import-Module -Name dbatools
  # Set cert rules
  Set-DbatoolsConfig -FullName sql.connection.trustcert -Value $true -Register
  Set-DbatoolsConfig -FullName sql.connection.encrypt -Value $false -Register

  $params = @{
   SqlInstance   = $Server
   Database      = $Database
   SqlCredential = $Credential
   Query         = $Query
   SqlParameter  = $Parameters
  }
  if ($WhatIf) {
   Write-Host $Query -f Green
   Write-Host ($Parameters.SqlValue.Value -join ',') -f Blue
   return
  }
  Invoke-DbaQuery @params
 }
}

function Select-DomainController ([string[]]$DomainControllers) {
 $dc = Get-Random $DomainControllers
 if ( Test-Connection -ComputerName $dc -Count 1 -ErrorAction SilentlyContinue ) {
  Write-Verbose ('{0},{1}' -f $MyInvocation.MyCommand.Name, $dc)
  return $dc
 }
 else {
  $msg = $MyInvocation.MyCommand.Name, $dc
  Write-Host ('{0},{1} Not responding. Trying random Domain Controller in 30 seconds...' -f $msg)
  Start-Sleep 30
  Select-DomainController $DomainControllers
 }
}

function Set-PSCred {
 [CmdletBinding()]
 param (
  # Username for credential object
  [Parameter(Mandatory = $true)]
  [string]$Username,
  # password string for credential object
  [Parameter(Mandatory = $true)]
  [string]$Password
 )
 $securePw = ConvertTo-SecureString $Password -AsPlainText -Force
 New-Object System.Management.Automation.PSCredential ($Username, $securePw )
}

function Show-TestRun {
 $str = "
           _______ ______ _____ _______ _____ _ _ _ _
  ______ |__ __| | ____| / ____| |__ __| | __ \ | | | | | \ | | ______
 |______| | | | |__ | (___ | | | |__) | | | | | | \| | |______|
  ______ | | | __| \___ \ | | | _ / | | | | | | ______
 |______| | | | |____ ____) | | | | | \ \ | |__| | | |\ | |______|
             |_| |______| |_____/ |_| |_| \_\ \____/ |_| \_|
 
"

 Write-Host $str -ForegroundColor Blue
}