functions/private/GenFuncs.ps1
#Requires -Version 5.0 using namespace System.Management.Automation Function Write-InformationColorized { <# .SYNOPSIS Writes messages to the information stream, optionally with color when written to the host. .DESCRIPTION An alternative to Write-Host which will write to the information stream and the host (optionally in colors specified) but will honor the $InformationPreference of the calling context. In PowerShell 5.0+ Write-Host calls through to Write-Information but will _always_ treats $InformationPreference as 'Continue', so the caller cannot use other options to the preference variable as intended. .LINK https://blog.kieranties.com/2018/03/26/write-information-with-colours #> [CmdletBinding()] param( [Parameter(Mandatory)] [Object]$MessageData, [ConsoleColor]$ForegroundColor = $Host.UI.RawUI.ForegroundColor, # Make sure we use the current colours by default [ConsoleColor]$BackgroundColor = $Host.UI.RawUI.BackgroundColor, [Switch]$NoNewline ) $msg = [HostInformationMessage]@{ Message = $MessageData ForegroundColor = $ForegroundColor BackgroundColor = $BackgroundColor NoNewline = $NoNewline.IsPresent } Write-Information $msg } function GetSQLFileContent { param ([string]$fileName) return Get-Content -Path ([System.IO.Path]::Combine($script:tcdbtools_SqlDir, $fileName)) -Raw } function InstallPackage { param ( [System.IO.DirectoryInfo]$path, [string]$packageName, [string]$packageSourceName, [string]$version, [switch]$SkipDependencies ) $packageArgs = @{ Name = $packageName ProviderName = "NuGet" Source = $packageSourceName } if ($version) { $packageArgs.Add("RequiredVersion", $version) } if (-not (Test-Path $path.FullName -PathType Container)) { New-Item $path.FullName -ErrorAction SilentlyContinue -Force -ItemType Directory } $package = Find-Package @packageArgs $packagePath = "$($path.FullName)\$($package.Name).$($package.Version)" if (-not (Test-Path $packagePath -PathType Container)) { # remove any older versions of the package Remove-Item "$($path.FullName)\$($package.Name)*" -Recurse -Force Write-Verbose "Installing Package: $($packageName)" $package = Install-Package @packageArgs -Scope CurrentUser -Destination $path.FullName -Force -SkipDependencies:$SkipDependencies.IsPresent } return $packagePath } function LoadAssembly { param ([System.IO.FileInfo]$path) # list loaded assemblies: # [System.AppDomain]::CurrentDomain.GetAssemblies() | Where-Object Location | Sort-Object -Property FullName | Select-Object -Property FullName, Location, GlobalAssemblyCache, IsFullyTrusted | Out-GridView # load the assembly bytes so as to not lock the file Write-Verbose "Loading assembly: $($path.FullName)" # Add-Type -Path $path.FullName # $bytes = [System.IO.File]::ReadAllBytes($path.FullName) # [System.Reflection.Assembly]::Load($bytes) | Out-Null [System.Reflection.Assembly]::LoadFrom($path.FullName) | Out-Null # Write-Host $ass | Format-List } function LoadAssemblies { param ([string]$path) $tmpPath = Get-Item $path $dllPaths = (Get-ChildItem -Path $tmpPath.FullName -Filter "*.dll") foreach ($dllPath in $dllPaths) { LoadAssembly -path $dllPath } } function ReplaceInvalidPathChars($str) { $str = $str.Split([IO.Path]::GetInvalidFileNameChars()) -join '_' $str = $str.Split([IO.Path]::GetInvalidPathChars()) -join '_' $str = $str -replace '\[|\]', '' return $str } function ConvertTo-Markdown { [CmdletBinding()] [OutputType([string])] Param ( [Parameter( Mandatory = $true, Position = 0, ValueFromPipeline = $true )] [PSObject[]]$InputObject ) begin { $sbMain = [System.Text.StringBuilder]::new() $sbDivider = [System.Text.StringBuilder]::new() $sbValues = [System.Text.StringBuilder]::new() } process { # test this in case the object was piped in, as we only want to do this once if ($sbMain.Length -eq 0) { ($InputObject | Select-Object -First 1).PSObject.Properties | ForEach-Object { $sbMain.Append("| $($_.Name) ") | Out-Null $sbDivider.Append("| $("-" * $_.Name.Length) ") | Out-Null } $sbMain.AppendLine("|") | Out-Null $sbDivider.Append("|") | Out-Null $sbMain.AppendLine($sbDivider.ToString()) | Out-Null } $InputObject | ForEach-Object { $_.PSObject.Properties | ForEach-Object { $sbValues.Append("| $($_.Value) ") | Out-Null } $sbValues.AppendLine("|") | Out-Null } } end { $sbMain.AppendLine($sbValues.ToString()) | Out-Null return $sbMain.ToString() } } function DataTableToCustomObject { <# .LINK https://www.stefanroth.net/2018/04/11/powershell-create-clean-customobjects-from-datatable-object/ #> [CmdletBinding()] [OutputType([object])] param ( [Parameter(Mandatory = $True)] [AllowNull()] [System.Data.DataTable]$DataTable ) if (-not $DataTable) { return $null } $Objects = @() foreach ($row in $DataTable.Rows) { $Properties = @{} foreach ($name in $DataTable.Columns.ColumnName) { $Properties.Add($name, $row[$name]) } $Objects += New-Object -TypeName PSObject -Property $Properties } # select the objects using the column name array so the properties will output in the same order return $Objects | Select-Object -Property $DataTable.Columns.ColumnName } function Get-AllUserDatabases { <# .DESCRIPTION If the first value in $Databases is "ALL_USER_DATABASES" then a list of all user databases is returned. Else the original list of databases is passed back. .PARAMETER Databases The list of databases. .PARAMETER SqlCmdArguments The sqlcmd arguments to use. Can be created using New-DBSqlCmdArguments. .EXAMPLE Get all user databases: PS> Get-AllUserDatabases -Databases "ALL_USER_DATABASES" -SqlCmdArguments (New-DBSqlCmdArguments -ServerInstance "ServerName") .EXAMPLE Just return the list of databases passed in PS> Get-AllUserDatabases -Databases "DBName1", "DBName2" -SqlCmdArguments (New-DBSqlCmdArguments -ServerInstance "ServerName") #> param ([string[]] $Databases, $SqlCmdArguments) if ($Databases[0] -ieq "ALL_USER_DATABASES") { $dbsQuery = GetSQLFileContent -fileName "AllUserDatabases.sql" $Databases = Invoke-Sqlcmd @SqlCmdArguments -Query $dbsQuery -OutputAs DataRows | Select-Object -ExpandProperty name -Unique Write-Information "ALL_USER_DATABASES specified. Databases found: `r`n$Databases" } return $Databases } function GetPercentComplete { [OutputType([int])] param( [Parameter(Mandatory = $true)] [int]$counter, [Parameter(Mandatory = $true)] [int]$total ) $pct = ([decimal]$counter / [decimal]$total) * 100.00 return [Convert]::ToInt32([Math]::Min(100, $pct)) } |