PowerShell.PowerLibrary.Core.psm1
#region Get-UniqueId FUNCTION Get-UniqueId { <# .Synopsis Generates Guid from plain text. .DESCRIPTION Use this method to Generates GUID from any input value. The Guid is always unique per input value. .PARAMETER InputValue Any Non Null Value String .EXAMPLE $Id = Get-UniqueId 'Any Text Can Go Here! :)'; #> param ( [ValidateNotNullOrEmpty()] [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] [string] $InputValue ); $random = [System.Random]::new($InputValue.GetHashCode()); $guidBytes = New-Object byte[] 16; $random.NextBytes($guidBytes); return [Guid]::new($guidBytes).ToString(); } #endregion #region Write-Message FUNCTION Write-Message { <# .Synopsis Write Message with Silent Option. .DESCRIPTION Same as Write-Host except that you may set a switch (Silent) so message won't be sent to the Host. .PARAMETER Object Any Object .PARAMETER Separator Separator Object .PARAMETER NoNewline Switch not to go to a new Line .PARAMETER ForegroundColor As the name says :) Fore Color .PARAMETER BackgroundColor As the name says :) Background Color .PARAMETER Silent Switch to toggle whether to write the message or not. .EXAMPLE Write-Message "Test" -Silent:$true; #> #region Parameters [CmdletBinding()] param ( [Parameter(Mandatory = $false, ValueFromPipeline = $true)] [object] $Object, [Parameter(Mandatory = $false, ValueFromPipeline = $true)] [object] $Separator, [Parameter(Mandatory = $false, ValueFromPipeline = $true)] [switch] $NoNewline = $false, [ValidateSet('Black', 'DarkBlue', 'DarkGreen', 'DarkCyan', 'DarkRed', 'DarkMagenta', 'DarkYellow', 'Gray', 'DarkGray', 'Blue', 'Green', 'Cyan', 'Red', 'Magenta', 'Yellow', 'White')] [ConsoleColor] $ForegroundColor, [ValidateSet('Black', 'DarkBlue', 'DarkGreen', 'DarkCyan', 'DarkRed', 'DarkMagenta', 'DarkYellow', 'Gray', 'DarkGray', 'Blue', 'Green', 'Cyan', 'Red', 'Magenta', 'Yellow', 'White')] [ConsoleColor] $BackgroundColor, [Parameter(Mandatory = $false, ValueFromPipeline = $true)] [switch] $Silent = $false ) #endregion BEGIN { IF($ForegroundColor -eq $null) { $ForegroundColor = [ConsoleColor]::Green; } IF($BackgroundColor -eq $null) { $BackgroundColor = [ConsoleColor]::Black; } } PROCESS { IF(!$Silent) { Write-Host $Object -NoNewline:$NoNewline -Separator $Separator -ForegroundColor $ForegroundColor -BackgroundColor $BackgroundColor; } } END { } } #endregion #region Write-Line FUNCTION Write-Line { <# .Synopsis Write Line with Silent Option. .DESCRIPTION Same as Write-Host except that you may set a switch (Silent) so message won't be sent to the Host. This Method Draws a Line. .PARAMETER Object Any Object .PARAMETER Separator Separator Object .PARAMETER NoNewline Switch not to go to a new Line .PARAMETER ForegroundColor As the name says :) Fore Color .PARAMETER BackgroundColor As the name says :) Background Color .PARAMETER Silent Switch to toggle whether to write the message or not. .EXAMPLE Write-Line; #> #region Parameters [CmdletBinding()] param ( [Parameter(Mandatory = $false, ValueFromPipeline = $true)] [string] $Object = '*', [Parameter(Mandatory = $false, ValueFromPipeline = $true)] [string] $Separator, [ValidateSet('Black', 'DarkBlue', 'DarkGreen', 'DarkCyan', 'DarkRed', 'DarkMagenta', 'DarkYellow', 'Gray', 'DarkGray', 'Blue', 'Green', 'Cyan', 'Red', 'Magenta', 'Yellow', 'White')] [ConsoleColor] $ForegroundColor, [ValidateSet('Black', 'DarkBlue', 'DarkGreen', 'DarkCyan', 'DarkRed', 'DarkMagenta', 'DarkYellow', 'Gray', 'DarkGray', 'Blue', 'Green', 'Cyan', 'Red', 'Magenta', 'Yellow', 'White')] [ConsoleColor] $BackgroundColor, [Parameter(Mandatory = $false, ValueFromPipeline = $true)] [switch] $Silent = $false ) #endregion BEGIN { IF($ForegroundColor -eq $null) { $ForegroundColor = [ConsoleColor]::Green; } IF($BackgroundColor -eq $null) { $BackgroundColor = [ConsoleColor]::Black; } $Size = $(Get-Host).UI.RawUI.BufferSize.Width; IF([string]::IsNullOrEmpty($Object)) { $Object = '*'; } IF([string]::IsNullOrEmpty($Separator)) { $Separator = [string]::Empty; } } PROCESS { Write-Message ([string]::Join($Separator, [System.Linq.Enumerable]::Repeat($Object, $Size))) -NoNewline -ForegroundColor $ForegroundColor -BackgroundColor $BackgroundColor -Silent:$Silent; } END { Write-Message -Silent:$Silent;; } } #endregion #region Log-Error FUNCTION Trace-Error([string]$Message, [System.Exception]$Exception) { <# .Synopsis A wrapper to throw Exception to the Host. .DESCRIPTION A wrapper to throw Exception to the Host. .EXAMPLE $Id = Get-UniqueId 'Any Text Can Go Here! :)'; #> throw $Message; } Set-Alias -Name Log-Error -Value Trace-Error; #endregion #region Get-PartialFileFullName FUNCTION Get-PartialFileFullName { <# .Synopsis Returns the Full Path of a given Partial Script File Name. .DESCRIPTION Returns the Full Path of a given Partial Script File Name. .PARAMETER FullName FullName can be full qualified Url or partial Url Suffix. .EXAMPLE $Id = Get-UniqueId 'Any Text Can Go Here! :)'; #> param ( [Parameter(Mandatory = $true, ValueFromPipeline=$true)] [Alias('V')] [ValidateNotNullOrEmpty()] [string] $FullName ); IF(![System.IO.Path]::HasExtension($FullName)) { $FullName = [string]::Concat($FullName, '.ps1'); } IF([System.IO.File]::Exists($MyInvocation.ScriptName)) { $FileName = [System.IO.Path]::GetFileNameWithoutExtension($MyInvocation.ScriptName); $VariableDirectory = [System.IO.Path]::Combine($MyInvocation.PSScriptRoot, $FileName); IF([System.IO.Directory]::Exists($VariableDirectory)) { $FullName = [System.IO.Path]::Combine($VariableDirectory, $FullName); } } IF(![System.IO.File]::Exists($FullName)) { Log-Error "$FullName does not exist."; } return $FullName; } #endregion #region Invoke-PostWebRequest FUNCTION Invoke-PostWebRequest { <# .Synopsis Wrapper to Invoke Post Web Request with Option to Retry. .DESCRIPTION Wrapper to Invoke Post Web Request with Option to Retry. .PARAMETER Url Post Url. .PARAMETER Payload Post Payload Body Object .PARAMETER RetryOnException A switch to set whether to retry the post on exception. .PARAMETER MaximumRetries Defines a maximum number of Retries .PARAMETER Timeout Default Value is 180. Timeout is in Seconds #> param ( [Parameter(Mandatory = $true, ValueFromPipeline=$true)] [Alias('U')] [ValidateNotNullOrEmpty()] [string] $Url, [Parameter(Mandatory = $false, ValueFromPipeline=$true)] [Alias('P')] [ValidateNotNullOrEmpty()] [object] $Payload, [Parameter(Mandatory = $false, ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [switch] $RetryOnException, [Parameter(Mandatory = $false, ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [uint64] $MaximumRetries, [Parameter(Mandatory = $false, ValueFromPipeline=$true)] [Alias('T')] [uint64] $Timeout = 180 ); $Retry = $false; $Retries = 0; DO { $Retries++; TRY { IF($Retry) { Write-Host "Re-POSTing to $Url ..." -ForegroundColor Magenta; } ELSE { Write-Host "POSTing to $Url ..." -ForegroundColor Gray; } $Response = Invoke-WebRequest -Uri $Url -Method POST -TimeoutSec $Timeout -Body $Payload; $Retry = $false; } CATCH [System.Net.WebException] { Write-Host $_.Exception.Message; Write-Host $_.Exception.Status; $Retry = $true; } } WHILE($RetryOnException -and $Retry -and $Retries -le $MaximumRetries); if($Response.StatusCode -ge 300) { Write-Output $Response Log-Error "Error occurred." } return $Response; } #endregion #region Invoke-GetWebRequest FUNCTION Invoke-GetWebRequest { <# .Synopsis Wrapper to Invoke Get Web Request with Option to Retry. .DESCRIPTION Wrapper to Invoke Get Web Request with Option to Retry. .PARAMETER Url Get Url. .PARAMETER Payload Get Payload Body Object .PARAMETER RetryOnException A switch to set whether to retry the post on exception. .PARAMETER MaximumRetries Defines a maximum number of Retries .PARAMETER Timeout Default Value is 180. Timeout is in Seconds #> param ( [Parameter(Mandatory = $true, ValueFromPipeline=$true)] [Alias('U')] [ValidateNotNullOrEmpty()] [string] $Url, [Parameter(Mandatory = $false, ValueFromPipeline=$true)] [Alias('P')] [ValidateNotNullOrEmpty()] [object] $Payload, [Parameter(Mandatory = $false, ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [switch] $RetryOnException, [Parameter(Mandatory = $false, ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [uint64] $MaximumRetries, [Parameter(Mandatory = $false, ValueFromPipeline=$true)] [Alias('T')] [ValidateNotNullOrEmpty()] [uint64] $Timeout = 180 ); $Retry = $false; $Retries = 0; DO { $Retries++; TRY { IF($Retry) { Write-Host "Re-GETing from $Url ..." -ForegroundColor Magenta; } ELSE { Write-Host "GETing from $Url ..." -ForegroundColor Gray; } $Response = Invoke-WebRequest -Uri $Url -Method Get -TimeoutSec $Timeout -Body $Payload; $Retry = $false; } CATCH [System.Net.WebException] { Write-Host $_.Exception.Message; Write-Host $_.Exception.Status; $Retry = $true; } } WHILE($RetryOnException -and $Retry -and $Retries -le $MaximumRetries); if($Response.StatusCode -ge 300) { Write-Output $Response Log-Error "Error occurred." } return $Response; } #endregion #region New-ZipArchive FUNCTION New-ZipArchive { <# .Synopsis Wrapper to Package Files Through 7-Zip. .DESCRIPTION Wrapper to Package Files Through 7-Zip. .PARAMETER Output This is the Path where to Save the Archived Package File. .PARAMETER Path This is the Path of Where the Archiver will package Files from. .PARAMETER ArchiveName As the name states, it is the Archive file Name (Without Extension). .PARAMETER SFX Switch to state whether the archive will be executable (Exe) or normal 7-zip Archive (7z). .PARAMETER DeleteAfterCompression Switch to state whether to Delete the Original (Path) Files after the process completes Archiving. .PARAMETER Override Switch to state the write mode of the Archiver. .PARAMETER Help Switch to Plot 7-zip Help. .EXAMPLE New-ZipArchive ` -Override:$true ` -SFX:$true ` -DeleteAfterCompression:$true ` -Path D:\Backup\Solutions\FolderToPackage ` -Output D:\Backup\Solutions\ ` -ArchiveName ArchivedSolutions ` ; #> param ( [Parameter(Mandatory = $true, ValueFromPipeline=$true)] [Alias('W')] [ValidateNotNullOrEmpty()] [string] $Output, [Parameter(Mandatory = $true, ValueFromPipeline=$true)] [Alias('P')] [ValidateNotNullOrEmpty()] [string] $Path, [Parameter(Mandatory = $false, ValueFromPipeline=$true)] [Alias('N')] [ValidateNotNullOrEmpty()] [string] $ArchiveName, [Parameter(Mandatory = $false, ValueFromPipeline=$true)] [Alias('EXE')] [switch] $SFX, [Parameter(Mandatory = $false, ValueFromPipeline=$true)] [Alias('D')] [switch] $DeleteAfterCompression, [Parameter(Mandatory = $false, ValueFromPipeline=$true)] [Alias('O')] [switch] $Override, [Parameter(Mandatory = $false, ValueFromPipeline=$true)] [Alias('H')] [switch] $Help ); Write-Host "Archiving..." -ForegroundColor Cyan; $7Zip = "$env:ProgramFiles\7-Zip\7z.exe"; IF (-not (Test-Path $7Zip)) { Log-Error "$7Zip needed"; } Set-Alias zipper $7Zip; IF($Help) { zipper; } IF([string]::IsNullOrWhiteSpace($ArchiveName)) { $ArchiveName = [System.IO.Path]::GetFileNameWithoutExtension($Output); } ELSE { $ArchiveName = [System.IO.Path]::GetFileNameWithoutExtension($ArchiveName) } $ArchiveName = [System.IO.Path]::Combine($Output, $ArchiveName); $Command = "zipper a -t7z -bt -r -o'$Output'*"; IF($SFX.IsPresent) { $Command += " -sfx"; $Extension += ".exe"; } ELSE { $Extension += ".7z"; } IF($DeleteAfterCompression.IsPresent) { $Command += " -sdel"; } IF(![System.IO.Path]::HasExtension($ArchiveName)) { $ArchiveName += $Extension; } IF($Override -and [System.IO.File]::Exists($ArchiveName)) { Remove-Item -Path $ArchiveName -Confirm:$false -Force; } $Command += " '$ArchiveName' '$Path'"; Write-Host "Path: " -NoNewline -ForegroundColor Yellow; Write-Host $Path -ForegroundColor White; Write-Host "Archive Name: " -NoNewline -ForegroundColor Yellow; Write-Host $ArchiveName -ForegroundColor White; &([scriptblock]::create($Command)); } #endregion #region Get-ZipArchive FUNCTION Get-ZipArchive { <# .Synopsis Wrapper to Extract Package Files Through 7-Zip. .DESCRIPTION Wrapper to Extract Package Files Through 7-Zip. .PARAMETER Output This is the Path where to Extract the Archived Package File. .PARAMETER Path This is the Path of the Archive (FullName with Extension). .PARAMETER Override Switch to state the write mode of the Archiver. .PARAMETER Help Switch to Plot 7-zip Help. #> param ( [Parameter(Mandatory = $true, ValueFromPipeline=$true)] [Alias('W')] [ValidateNotNullOrEmpty()] [string] $Output, [Parameter(Mandatory = $false, ValueFromPipeline=$true)] [Alias('P')] [ValidateNotNullOrEmpty()] [string] $Path, [Parameter(Mandatory = $false, ValueFromPipeline=$true)] [Alias('O')] [ValidateNotNullOrEmpty()] [switch] $Override, [Parameter(Mandatory = $false, ValueFromPipeline=$true)] [Alias('H')] [ValidateNotNullOrEmpty()] [switch] $Help ); $7Zip = "$env:ProgramFiles\7-Zip\7z.exe"; IF (-not (Test-Path $7Zip)) { Log-Error "$7Zip needed"; } Set-Alias zipper $7Zip; IF($Help) { zipper; } $Command = "zipper x -bt -o'$Output'*"; IF($Override) { $Command += " -y"; } IF(![System.IO.Path]::HasExtension($Path)) { Log-Error "$Path is not a file or has no extension." } $Command += " '$Path'"; &([scriptblock]::create($Command)); } #endregion #region Confirm-Directory FUNCTION Confirm-Directory { <# .Synopsis Ensures directory Exists. .DESCRIPTION Ensures directory Exists. If NOT, it will be created... .PARAMETER Path This is the Directory Full Name. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] [Alias('P')] [ValidateNotNullOrEmpty()] [string] $Path ) IF(![System.IO.Directory]::Exists($Path)) { [System.IO.Directory]::CreateDirectory($Path); } RETURN $Path; } #endregion #region Join-Uri FUNCTION Join-Uri { <# .Synopsis Simply Builds a URL. .DESCRIPTION Simply Builds a URL .PARAMETER BaseUrl This is the URL Base Address. .PARAMETER UriParts This is the URL Parts to be amended. .EXAMPLE $PostUrl = Join-Uri -B "https://baseaddress" -A "/ApplicationName", "/api/Notification/CreateQueuesIfNotExist"; #> param ( [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position = 0, HelpMessage='This parameter represents the base URI')] [Alias('B')] [ValidateNotNullOrEmpty()] [string] $BaseUrl, [Parameter(Mandatory = $false, ValueFromPipeline = $true, Position = 1)] [Alias('A')] [string[]] $UriParts ); $uri = [System.Text.StringBuilder]::new($BaseUrl.TrimEnd("/")); IF($UriParts.Length -eq 0) { RETURN $uri.ToString(); } FOREACH ($part in $UriParts) { $uri.AppendFormat("/{0}", $part.TrimEnd("/").TrimStart("/")) | Out-Null; } RETURN $uri.ToString(); } #endregion #region Get Dynamic Parameters FUNCTION Get-DynamicParameters { <# .Synopsis Generate dynamic parameters .DESCRIPTION Returns the Common Parameters for all Public Functions. #> [CmdletBinding()]param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] [string] $CommandName, [Parameter(Mandatory = $false, ValueFromPipeline = $true, Position = 1)] [string[]] $ExcludedProperties, [Parameter(Mandatory = $false, ValueFromPipeline = $true)] [switch] $IncludeDefaultValue ); BEGIN { $DefaultParametersNames = [System.Runtime.Serialization.FormatterServices]::GetUninitializedObject([type][System.Management.Automation.Internal.CommonParameters]) | Get-Member -MemberType Properties | Select-Object -ExpandProperty Name; $Command = $(Get-Command $CommandName); $AST = $Command.ScriptBlock.Ast; $Parameters = $Command.Parameters.GetEnumerator(); $WritableParamAttributePropertyNames = [System.Management.Automation.ParameterAttribute]::new() | Get-Member -MemberType Property | Where-Object { $_.Definition -match "{.*set;.*}$" } | Select-Object -ExpandProperty Name; # Create the Runtime Param dictionary $DynamicParameterDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new(); } PROCESS { FOREACH ($Parameter in $Parameters) { IF(($DefaultParametersNames -contains $Parameter.Key) -or (@('WhatIf', 'Confirm') -contains $Parameter.Key) -or ($ExcludedProperties -contains $Parameter.Key)) { continue; } $AttributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new(); $ParameterType = $Parameter.Value.ParameterType; FOREACH ($CurrentAttribute in $Parameter.Value.Attributes) { $AttributeTypeName = $CurrentAttribute.TypeId.FullName; switch -wildcard ($AttributeTypeName) { System.Management.Automation.ArgumentTypeConverterAttribute { continue; # So blank param doesn't get added } System.Management.Automation.Validate*Attribute { $NewParameterAttribute = $CurrentAttribute; $AttributeCollection.Add($NewParameterAttribute); } System.Management.Automation.ParameterAttribute { $NewParameterAttribute = [System.Management.Automation.ParameterAttribute]::new(); FOREACH ($PropertyName in $WritableParamAttributePropertyNames) { IF ($NewParameterAttribute.$PropertyName -ne $CurrentAttribute.$PropertyName) { # nulls cause an error if you assign them to some of the properties $NewParameterAttribute.$PropertyName = $CurrentAttribute.$PropertyName; } } $NewParameterAttribute.ParameterSetName = $CurrentAttribute.ParameterSetName; $AttributeCollection.Add($NewParameterAttribute); } default { Write-Warning "Function doesn't handle dynamic param copying for $AttributeTypeName"; continue; } } } $DynamicParameter = [System.Management.Automation.RuntimeDefinedParameter]::new($Parameter.Key, $ParameterType, $AttributeCollection); $DynamicParameterDictionary.Add($Parameter.Key, $DynamicParameter); } IF($IncludeDefaultValue.IsPresent) { FOREACH ($Parameter in $AST.ParamBlock.Parameters.GetEnumerator()) { if(!$DynamicParameterDictionary.TryGetValue($Parameter.Name.VariablePath.UserPath, [ref]$DynamicParameter)){ continue; } if($null -eq $Parameter.DefaultValue) { continue; } $DynamicParameter.Value = $Parameter.DefaultValue.Value; } } # Return the dynamic parameters RETURN $DynamicParameterDictionary; } } #endregion |