PwSh.Fw.Core.psm1
<#
.SYNOPSIS Resource file to export useful functions to prettify output .DESCRIPTION .NOTES Author: Charles-Antoine Degennes <cadegenn@gmail.com> New-ModuleManifest api.psd1 -RootModule api.psm1 -ModuleVersion "0.0.1" -Author "Charles-Antoine Degennes <cadegenn@gmail.com>" #> $Script:NS = (get-item $PSCommandPath).basename # # Error codes enum # Enum pwshfwERROR { # OK = 0 # FAILED = 1 # RUNNING = 2 # MISSED = 3 # SKIPPED = 4 # UNUSED = 5 # UNKNOWN = 6 # DEAD = 7 # NOTFOUND = 8 # } $Script:PWSHFW_VERSION = (Get-Content $PSScriptRoot/VERSION) # $Script:ErrorPreference = "Continue"; $Script:indent = "" $Script:prepend = " * " $Script:titleChar = "*" $Script:lineBreakChar = "-" <# .SYNOPSIS Template function .DESCRIPTION Skeleton of a typical function .PARAMETER $string a string .EXAMPLE New-TemplateFunction -string "a string" #> function New-TemplateFunction { [CmdletBinding()] [OutputType([System.String])] Param ( [Parameter(Mandatory,ValueFromPipeLine = $true)][string]$string ) Begin { # eenter($MyInvocation.MyCommand) } Process { return $string } End { # eleave($MyInvocation.MyCommand) } } # function Get-PwShFwModuleInfos { # [CmdletBinding()][OutputType([String])]Param ( # # [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][string]$string # ) # Begin { # # eenter($Script:NS + '\' + $MyInvocation.MyCommand) # } # Process { # Write-Output "PSCommandPath = $PSCommandPath" # Write-Output "PSScriptRoot = $PSScriptRoot" # } # End { # # eleave($Script:NS + '\' + $MyInvocation.MyCommand) # } # } <# .SYNOPSIS Indent further calls to e*() functions .DESCRIPTION Indent with 2 spaces .NOTES TODO: . add parameter to override indent size #> function Write-Indent() { [CmdletBinding()]param( [switch]$PassThru ) $Script:indent += " " if ($PassThru) { return $Script:indent } } <# .SYNOPSIS Outdent further calls to e*() functions .DESCRIPTION un-indent for 2 spaces .NOTES TODO: . add parameter to override indent size #> function Write-Outdent() { [CmdletBinding()]param( [switch]$PassThru ) if ($Script:indent.Length -gt 3) { $Script:indent = $Script:indent.Substring(0,$Script:indent.Length - 3) } else { $Script:indent = "" } if ($PassThru) { return $Script:indent } } <# .SYNOPSIS Print a title .DESCRIPTION Print a title in green #> function Write-Title() { [CmdletBinding()]param( [string]$message, [switch]$PassThru ) $hr = "*" * ($message.Length + $indent.length + 6) $message = "** " + $indent + $message + " **" Write-ToLogFile -Message $hr Write-ToLogFile -Message $message if ($PassThru) { return $message } else { Write-Host -ForegroundColor Green "`n`n$hr" Write-Host -NoNewline -ForegroundColor Green $message } } <# .SYNOPSIS Print a message without new line .DESCRIPTION Print a message without new line .PARAMETER $message Text to display on screen .PARAMETER $width Optional. Used to pad text to the left. #> function Write-Begin() { [CmdletBinding()]param( [string]$message, [int32]$width = $Host.UI.RawUI.WindowSize.Width ) $fullMessage = $prepend + $indent + $message + "... " #$ht = "." * ($Host.UI.RawUI.WindowSize.Width - $message.Length) $width = $width - 16 Write-Host -NoNewline -ForegroundColor DarkGreen $("`n{0,-$width}" -f $fullMessage) Write-ToLogFile -NoNewline -Message $fullMessage } <# .SYNOPSIS Add message to current line. .DESCRIPTION Add text to current line of text. No new line at the beginning, no new line at the end. #> function Write-Add() { [CmdletBinding()]param( [string]$message ) Write-Host -NoNewline $Message Write-ToLogFile -NoNewline -Message $message } <# .SYNOPSIS Print a message depending on return code .DESCRIPTION Print a message of status code. All status MUST have the same length. It is used to properly align all messages #> function Write-End() { [CmdletBinding()]param( $errorCode ) if (-not($errorCode)) { $errorCode = $false } $color = "White" ; $message = $errorCode switch -wildcard ($errorCode.GetTYpe().Name) { "Bool*" { switch ($errorCode) { $true { $color = "Green" ; $message = " ok " } $false { $color = "Red" ; $message = " failed " } } } "Int*" { switch ($errorCode) { # 0 is never called since `Write-End 0` goes to the bool switch # 0 { $color = "Green"; $message = " ok " } 1 { $color = "Red"; $message = " failed " } 2 { $color = "DarkGreen"; $message = " running " } 3 { $color = "Yellow"; $message = " missed " } 4 { $color = "Gray"; $message = " skipped " } 5 { $color = "Gray"; $message = " unused " } 6 { $color = "Gray"; $message = " unknown " } 7 { $color = "Red"; $message = " dead " } 8 { $color = "Gray"; $message = "not found" } } } # "pwshfwERROR" { # switch ($errorCode) { # ([pwshfwERROR]::OK) { $color = "Green"; $message = " ok " } # ([pwshfwERROR]::FAILED) { $color = "Red"; $message = " failed " } # ([pwshfwERROR]::RUNNING) { $color = "DarkGreen"; $message = " running " } # ([pwshfwERROR]::MISSED) { $color = "Yellow"; $message = " missed " } # ([pwshfwERROR]::SKIPPED) { $color = "Gray"; $message = " skipped " } # ([pwshfwERROR]::UNUSED) { $color = "Gray"; $message = " unused " } # ([pwshfwERROR]::UNKNOWN) { $color = "Gray"; $message = " unknown " } # ([pwshfwERROR]::DEAD) { $color = "Red"; $message = " dead " } # ([pwshfwERROR]::NOTFOUND) { $color = "Gray"; $message = "not found" } # default { $color = "White"; $message = $errorCode } # } # } } $message = "[ " + $message + " ]" Write-Host -NoNewline -ForegroundColor $color $message Write-ToLogFile -NoHeader -Message $message } <# .SYNOPSIS Print a message when entering a function .DESCRIPTION Print a message specifically when entering a function. .EXAMPLE # eenter "" #> function Write-EnterFunction() { # [CmdletBinding()]param( # [string]$message # ) $callStack = Get-PSCallStack if ($callStack.Count -gt 1) { $message = $callStack[1].Command # $callStack[1] | fl * } $message = ">> " + $message + "()" if ($Global:TRACE) { Write-Devel ($message) eindent } } <# .SYNOPSIS Print a message when leaving a function .DESCRIPTION Print a message specifically when entering a function. .EXAMPLE # eenter "" #> function Write-LeaveFunction() { # [CmdletBinding()]param( # [string]$message # ) $callStack = Get-PSCallStack if ($callStack.Count -gt 1) { $message = $callStack[1].Command # $callStack[1] | fl * } $message = "<< " + $message + "()" if ($Global:TRACE) { eoutdent Write-Devel ($message) } } <# .SYNOPSIS Print a message when entering something .DESCRIPTION Print a message and indent output for following messages. It is useful when entering a loop, or a module, or an external script. .EXAMPLE # eenter "" #> function Write-Enter() { [CmdletBinding()]param( [string]$message ) $message = ">> " + $message + "()" Write-Info ($message) eindent } <# .SYNOPSIS Print a message when leaving a something .DESCRIPTION Print a message specifically when entering a function. It is useful when leaving a loop, or a module, or an external script. .EXAMPLE # eenter "" #> function Write-Leave() { [CmdletBinding()]param( [string]$message ) eoutdent $message = "<< " + $message + "()" Write-Info ($message) } <# .SYNOPSIS Print a devel message .DESCRIPTION Used to print content of command #> function Write-Devel() { [CmdletBinding()]param( [string]$message ) if ($Global:DEVEL -eq $false) { return } $fullmessage = $prepend + "DEV: " + $indent + $message Write-Host -NoNewline -ForegroundColor DarkGray ("`n" + $fullmessage) #Write-Debug ($indent + " " + $message) Write-ToLogFile -Message $fullmessage } <# .SYNOPSIS Print a debug message .DESCRIPTION Override Write-Debug() powershell function Mainly used to print Key = Valu pair #> function Write-MyDebug() { [CmdletBinding()]param( [string]$message ) if ($Global:DEBUG -eq $false) { return } $fullmessage = $prepend + "DBG: " + $indent + $message Write-Host -NoNewline -ForegroundColor Gray ("`n" + $fullmessage) #Write-Debug ($indent + " " + $message) Write-ToLogFile -Message $fullmessage } <# .SYNOPSIS Print a verbose message .DESCRIPTION Override Write-Verbose() powershell function #> function Write-MyVerbose() { [CmdletBinding()]param( [string]$message ) if ($VERBOSE -eq $false) { return } $fullmessage = $prepend + $indent + $message Write-Host -NoNewline -ForegroundColor White ("`n" + $fullmessage) #Write-Verbose ($indent + " " + $message) Write-ToLogFile -Message $fullmessage } <# .SYNOPSIS Print a warning message .DESCRIPTION Override Write-Warning() powershell function #> function Write-MyWarning() { [CmdletBinding()]param( [string]$message ) $fullmessage = $prepend + "WRN: " + $indent + $message Write-Host -NoNewline -ForegroundColor Yellow ("`n" + $fullmessage) Write-ToLogFile -Message $fullmessage } <# .SYNOPSIS Print an error message .DESCRIPTION Override Write-Error() powershell function #> function Write-MyError() { [CmdletBinding()]param( [string]$message ) $fullmessage = $prepend + "ERR: " + $indent + $message Write-Host -NoNewline -ForegroundColor Red ("`n" + $fullmessage) Write-ToLogFile -Message ($fullmessage) } <# .SYNOPSIS Print an information message .DESCRIPTION Override Write-Information() powershell function #> function Write-Info() { [CmdletBinding()]param( [string]$message ) $fullmessage = $prepend + $indent + $message Write-Host -NoNewline -ForegroundColor Gray ("`n" + $fullmessage) Write-ToLogFile -Message ($fullmessage) } <# .SYNOPSIS Print a fatal error message then exist script .DESCRIPTION Print an error message before terminate current script .EXAMPLE Write-Fatal "fatal error. Abort." #> function Write-Fatal() { [CmdletBinding()]param( [string]$message ) Write-MyError -ErrorAction:Stop -Message $message Throw " Aborting." } <# .SYNOPSIS Wrapper to PwSh.Fw.Log's Wrte-ToLogFile(). .DESCRIPTION All the Write-*() functions from this module use Write-ToLogFile(). This wrapper is here just in case the PwSh.Fw.Log module is not loaded/available. .PARAMETER Append Append message to the log file. Do not overwrite it. Append = $true is the default. If you want to overwrite or initiate the file, call Write-ToLogFile -message "Logfile initialized" -Append=$false .PARAMETER NoNewline Do not append a new line at the end of file. .PARAMETER NoHeader Do not print header informations : "date hostname scriptname". Usefull to append text to an existing line. .EXAMPLE Write-ToLogFile -message "a log entry" -append #> function Write-ToLogFile() { [CmdletBinding()]param( [switch]$Append, [switch]$NoNewLine, [switch]$NoHeader, [string]$message, [string]$logFile = $Global:LOG ) # old method using ubounded arguments, but I failed to make it work # # Write-Host("`n >> " + $MyInvocation.MyCommand) # Write-Host($MyInvocation.PSBoundParameters | Convertto-Json) # Write-Host($MyInvocation.UnboundArguments | Convertto-Json) # $module = Get-Module PwSh.Fw.Log -ErrorAction SilentlyContinue # if ($null -ne $module) { # PwSh.Fw.Log\Write-ToLogFile $MyInvocation.PSBoundParameters # PwSh.Fw.Log\Write-ToLogFile ($MyInvocation.UnboundArguments).ToString() # } # # Write-Host("`n << " + $MyInvocation.MyCommand) # new method with bounded parameters $module = Get-Module PwSh.Fw.Log -ErrorAction SilentlyContinue if ($null -ne $module) { PwSh.Fw.Log\Write-ToLogFile -Append:$Append -NoNewLine:$NoNewLine -NoHeader:$NoHeader -Message "$Message" -logFile $logFile } } <# .SYNOPSIS Execute a DOS/Shell command. .DESCRIPTION Wrapper for executing a DOS/Shell command. It handle (not yet) logging, (not yet) simulating and (not yet) asking. Please use following syntax : $rc = Execute-Commande "commande.exe" "arguments" to catch return code. Otherwise it will be printed to stdout and its quite ugly. .PARAMETER exe full path to executable .PARAMETER args all arguments enclosed in double-quotes. You may have to escape inner quotes to handle args with special characters. .PARAMETER AsInt Return code will be an int instead of a boolean. .EXAMPLE $rc = Execute-Command "net" "use w: \\srv\share" #> function Execute-Command() { [CmdletBinding()] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "", Justification="Execute-Command is a more intuitive verb for this function and does not conflict with default Invoke-Command cmdlet.")] param( [parameter(mandatory=$true, position=0)][string]$exe, [parameter(mandatory=$false, position=1, ValueFromRemainingArguments=$true)][string]$args, [switch]$AsInt ) $cmd = Get-Command -Name "$exe" switch ($cmd.CommandType) { 'Application' { $exe = "& '" + $exe + "'" break } 'ExternalScript' { $exe = "& '" + $exe + "'" break } 'Cmdlet' { } default { } } Write-MyDebug ($exe + " " + $args) # $rcFile = $([System.IO.Path]::GetTempPath() + [IO.Path]::DirectorySeparatorChar + "rc") $rcFile = $([System.IO.Path]::GetTempPath() + "rc") # edevel("rcFile = $rcFile") # try { # if ($Global:DEVEL) { # if ($AsInt) { # Invoke-Expression ("$exe $args; `$LastExitCode | Out-File '$rcFile'") | Foreach-Object { Write-Devel $_ } # } else { # Invoke-Expression ("$exe $args; `$? | Out-File '$rcFile'") | Foreach-Object { Write-Devel $_ } # } # #return $? # } elseif ($Global:DEBUG) { # if ($AsInt) { # Invoke-Expression ("$exe $args; `$LastExitCode | Out-File '$rcFile'") | Out-Null # } else { # Invoke-Expression ("$exe $args; `$? | Out-File '$rcFile'") | Out-Null # } # #return $? # } else { # if ($AsInt) { # Invoke-Expression ("$exe $args; `$LastExitCode | Out-File '$rcFile'") | Out-Null # } else { # Invoke-Expression ("$exe $args; `$? | Out-File '$rcFile'") | Out-Null # } # #return $? # } if ($AsInt) { $out = Invoke-Expression ("$exe $args; `$LastExitCode | Out-File '$rcFile'") } else { $out = Invoke-Expression ("$exe $args; `$? | Out-File '$rcFile'") } if ($Global:DEVEL) { $out | Foreach-Object { Write-Devel $_ } } elseif ($Global:DEBUG) { $out | Foreach-Object { Write-MyDebug $_ } } $rc = Get-Content "$rcFile" -Raw # # edevel("rc = $rc") # Remove-Item "$rcFile" # # edevel("return $rc") # # if ($null -ne $rc) { return $rc # } else { # return $false # } # return $true # } catch { # return $false # } } <# .SYNOPSIS Wrapper for Import-Module .DESCRIPTION It handle everything to not worry about error messages. * check if module exist in module path * if an absolute filename is given, check if module exist as well as manifest * load-it with an optional $Force parameter * write a warning if module cannot be found .PARAMETER Name Name of the module to load .PARAMETER FullyQualifiedName Absolute path and name of the module to load. It can be either the manifest file (.psd1) or the module file (.psm1) .PARAMETER Force Force a reload if module is already loaded #> function Load-Module { [CmdletBinding( DefaultParameterSetName="NAME" )] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "", Justification="Load-Module is a more intuitive verb for this function and does not conflict with default Get-Module cmdlet.")] Param ( [Parameter(ParameterSetName="NAME",Mandatory,ValueFromPipeLine = $true)] [string]$Name, [Parameter(ParameterSetName="FILENAME",Mandatory,ValueFromPipeLine = $true)] [string]$FullyQualifiedName, [switch]$Force, [ValidateSet('Required', 'Optional')] [string]$Policy = "Required" ) Begin { # eenter($MyInvocation.MyCommand) } Process { switch ($PSCmdlet.ParameterSetName) { "NAME" { $module = Get-Module -ListAvailable $Name if ($null -eq $module) { # fake module to display correct informations # PowerShell < 5 does not return anything $module = @{ name = $Name; path = $null} } break } "FILENAME" { $module = Get-Module -ListAvailable $FullyQualifiedName -ErrorAction Ignore if ($null -eq $module) { # fake module to display correct informations # PowerShell < 5 does not return anything $module = @{ name = (Split-Path -Leaf $FullyQualifiedName); path = $FullyQualifiedName} } break } } # exit if module is already loaded $rc = Get-Module -Name $module.Name if ($null -ne $rc) { if ($Force -eq $false) { ebegin("Module $($module.name) already loaded...") eend $true return $true } } if ($Global:VERBOSE) { if ($Global:DEBUG) { ebegin("Importing module $($module.name) from '$($module.Path)'") } else { ebegin("Importing module $($module.name)") } } switch ($Policy) { 'Required' { $ErrorAction = 'Ignore' # $ErrorAction = 'Continue' } 'Optional' { $ErrorAction = 'Ignore' } } switch ($PSCmdlet.ParameterSetName) { "NAME" { Import-Module -Name $module.name -Global -Force:$Force -DisableNameChecking -ErrorAction $ErrorAction $rc = $? break } "FILENAME" { # -FullyQualifiedName is not supported in PS < 5 if ($PSVersionTable.PSVersion.Major -lt 5) { Import-Module $module.Path -Global -Force:$Force -DisableNameChecking -ErrorAction $ErrorAction } else { Import-Module -FullyQualifiedName $module.Path -Global -Force:$Force -DisableNameChecking -ErrorAction $ErrorAction } $rc = $? break } } switch ($Policy) { 'Required' { if ($rc -eq $false) { efatal("Module $($module.name) was not found and policy is '$Policy'.") } } 'Optional' { } } if ($Global:VERBOSE) { eend $rc } return $rc } End { # eleave($MyInvocation.MyCommand) } } <# .SYNOPSIS Test if a file exist .DESCRIPTION Long description .EXAMPLE An example .NOTES General notes #> function Test-FileExist { [CmdletBinding()] [OutputType([System.Boolean])] Param ( [Parameter(Mandatory,ValueFromPipeLine = $true)] [string]$Name ) Begin { # eenter($MyInvocation.MyCommand) } Process { Test-Path $Name -PathType Leaf } End { # eleave($MyInvocation.MyCommand) } } <# .SYNOPSIS Test if a directory exist .DESCRIPTION Long description .EXAMPLE An example .NOTES General notes #> function Test-DirExist { [CmdletBinding()][OutputType([System.Boolean])]Param ( [Parameter(Mandatory,ValueFromPipeLine = $true)] [string]$Path ) Begin { # eenter($MyInvocation.MyCommand) } Process { Test-Path $Path -PathType Container } End { # eleave($MyInvocation.MyCommand) } } <# .SYNOPSIS Test if a registry property exist .DESCRIPTION There is not yet a builtin function to test existence of registry value. Thanks to Jonathan Medd, here it is. .PARAMETER RegPath Registry path to the key .EXAMPLE Test-RegKeyExist -RegPath HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion .NOTES General notes .LINK https://www.jonathanmedd.net/2014/02/testing-for-the-presence-of-a-registry-key-and-value.html #> function Test-RegKeyExist { param ( [Alias('Path')] [parameter(Mandatory=$true)][ValidateNotNullOrEmpty()]$RegPath ) Test-Path -Path $RegPath -PathType Container } <# .SYNOPSIS Test if a registry property exist .DESCRIPTION There is not yet a builtin function to test existence of registry value. Thanks to Jonathan Medd, here it is. .PARAMETER RegPath Registry path to the key .PARAMETER Name Name of the value to test .EXAMPLE Test-RegValueExist -RegPath HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Value ProgramFilesDir .NOTES General notes .LINK https://www.jonathanmedd.net/2014/02/testing-for-the-presence-of-a-registry-key-and-value.html #> function Test-RegValueExist { param ( [parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()]$RegPath, [parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()]$Name ) try { $rc = Get-ItemProperty -Path $RegPath | Select-Object -ExpandProperty $Name -ErrorAction Stop return $true } catch { return $false } } <# .SYNOPSIS Test if a variable exist .DESCRIPTION This function is silent and only return $true if the variable exist or $false otherwise. .PARAMETER Name a variable name to test .EXAMPLE Test-Variable -Name "myvar" #> function Test-Variable { [CmdletBinding()]Param ( [Parameter(Mandatory,ValueFromPipeLine = $true)][string]$Name ) Begin { # eenter($MyInvocation.MyCommand) } Process { Get-Variable -Name $Name -ErrorAction SilentlyContinue | Out-Null return $? } End { # eleave($MyInvocation.MyCommand) } } <# .SYNOPSIS Serialize an object to a single string .DESCRIPTION Convert an object to a single string to ease display and debug .PARAMETER InputObject an object (currently, only hashtable are supported) .EXAMPLE $ht = @{'key'="value";'key2'="value2"} $ht | ConvertTo-SingleString .NOTES General notes #> function ConvertTo-SingleString { [CmdletBinding()]param( [parameter(Mandatory,ValueFromPipeline = $True)] $InputObject ) Begin { } Process { # $InputObject.GetTYpe() switch ($InputObject.GetTYpe()) { 'Hashtable' { # $serialized = ($InputObject.GetEnumerator() | % { "'$($_.Key)'=`"$($_.Value)`"" }) -join ';' $serialized = Foreach ($k in $InputObject.GetEnumerator()) { switch ($k.Value.GetType()) { 'datetime' { "'$($k.Key)'=[System.DateTime]`"$($k.Value)`"" } default { "'$($k.Key)'=`"$($k.Value)`"" } } } $serialized = $serialized -join(';') } default { eerror("Object type '" + $InputObject.GetTYpe() + "' not supported yet.") return $false } } return "@{" + $serialized + "}" } End { } } <# .LINK http://www.lazywinadmin.com/2015/05/powershell-remove-diacritics-accents.html #> function Remove-StringLatinCharacters { PARAM ( [parameter(ValueFromPipeline = $true)] [string]$String ) PROCESS { [Text.Encoding]::ASCII.GetString([Text.Encoding]::GetEncoding("Cyrillic").GetBytes($String)) } } <# .SYNOPSIS Resolve boolean well-known values .DESCRIPTION Boolean are not just (true | false) value. It can by yes/no or 0/1. Resolve-Boolean handle all of this. .PARAMETER var The variable name to check .EXAMPLE true | Resolve-Boolean .EXAMPLE 0 | Resolve-Boolean .EXAMPLE $test = "yes" if ((Resolve-Boolean -var $test) -eq $true) { echo "yes is true" } .NOTES General notes #> function Resolve-Boolean { [CmdletBinding()][OutputType([boolean])]Param ( [Parameter(Mandatory,ValueFromPipeLine = $true)]$var ) Begin { # eenter($MyInvocation.MyCommand) } Process { switch -regex ($var.GetType()) { 'bool*' { return $var } 'int*' { switch ($var) { 0 { return $false } 1 { return $true } } } 'string' { switch -wildcard ($var) { 'false' { return $false } 'true' { return $true } 'n*' { return $false } 'y*' { return $true } } } } return $false } End { # eleave($MyInvocation.MyCommand) } } <# .SYNOPSIS Get a property value from a file #> function Get-PropertyValueFromFile { [CmdletBinding()]Param ( [Parameter(Mandatory=$true,ValueFromPipeline=$true)] [string]$Filename, [Parameter(Mandatory=$true,ValueFromPipeline=$true)] [string]$Propertyname ) Begin { # eenter($MyInvocation.MyCommand) } Process { $value = (Get-Content $Filename -Raw | ConvertFrom-StringData).$Propertyname # trim quotes $value = $value -replace "'", "" -replace '"', '' return $value } End { # eleave($MyInvocation.MyCommand) } } function ConvertTo-CamelCase { [CmdletBinding()]Param ( [Parameter(Mandatory=$true, ValueFromPipeline=$true)] [AllowNull()][AllowEmptyString()] [string]$String ) Begin { # eenter($MyInvocation.MyCommand) } Process { # convert to Title Case $camelCase = (get-culture).TextInfo.ToTitleCase($String) # transforme accent to normal letters $camelCase = $camelCase | Remove-StringLatinCharacters # remove non alphanumeric characters $camelCase = $camelCase -replace '[^a-zA-Z0-9]', '' # convert 1st letter to lowercase $camelCase = $camelCase.Substring(0,1).ToLower() + $camelCase.Substring(1) return $camelCase } End { # eleave($MyInvocation.MyCommand) } } <# .SYNOPSIS Add a custom path to the PSModulePath environment variable. .DESCRIPTION Add a custom path to the PSModulePath environment variable. .PARAMETER Path Path to add .PARAMETER First If specified, add the Path at the beginning of PSModulePath .EXAMPLE Add-PSModulePath -Path c:\MyProject\MyModules .EXAMPLE "C:\MyProject\MyModules" | Add-PSModulePath -First .NOTES General notes #> function Add-PSModulePath { [CmdletBinding()]Param ( [Parameter(Mandatory,ValueFromPipeLine = $true)][string]$Path, [switch]$First ) Begin { # eenter($Script:NS + '\' + $MyInvocation.MyCommand) } Process { try { if ($First) { $env:PSModulePath = $PATH + [IO.Path]::PathSeparator + $env:PSModulePath } else { $env:PSModulePath = $env:PSModulePath + [IO.Path]::PathSeparator + $PATH } } catch { ewarn($_.Exception.ItemName + ": " + $_.Exception.Message) } # edevel("env:PSModulePath = " + $env:PSModulePath) } End { # eleave($Script:NS + '\' + $MyInvocation.MyCommand) } } Set-Alias -Force -Name eindent -Value Write-Indent Set-Alias -Force -Name eoutdent -Value Write-Outdent Set-Alias -Force -Name etitle -Value Write-Title Set-Alias -Force -Name ebegin -Value Write-Begin Set-Alias -Force -Name eadd -Value Write-Add Set-Alias -Force -Name eend -Value Write-End Set-Alias -Force -Name fenter -Value Write-EnterFunction Set-Alias -Force -Name fleave -Value Write-LeaveFunction Set-Alias -Force -Name eenter -Value Write-Enter Set-Alias -Force -Name eleave -Value Write-Leave #Set-Alias -Force -Name einfo -Value Write-Information Set-Alias -Force -Name einfo -Value Write-Info #Set-Alias -Force -Name everbose -Value Write-Verbose Set-Alias -Force -Name everbose -Value Write-MyVerbose #Set-Alias -Force -Name edebug -Value Write-Debug Set-Alias -Force -Name edebug -Value Write-MyDebug Set-Alias -Force -Name edevel -Value Write-Devel Set-Alias -Force -Name ewarn -Value Write-MyWarning Set-Alias -Force -Name eerror -Value Write-MyError Set-Alias -Force -Name efatal -Value Write-Fatal Set-Alias -Force -Name eexec -Value Execute-Command Set-Alias -Force -Name Execute-Cmd -Value Execute-Command Set-Alias -Force -Name Exec-Command -Value Execute-Command Set-Alias -Force -Name Exec-Cmd -Value Execute-Command Set-Alias -Force -Name fileExist -Value Test-FileExist Set-Alias -Force -Name dirExist -Value Test-DirExist Set-Alias -Force -Name regKeyExist -Value Test-RegKeyExist Set-Alias -Force -Name regValueExist -Value Test-RegValueExist Set-Alias -Force -Name varExist -Value Test-Variable Set-Alias -Force -Name Resolve-Bool -Value Resolve-Boolean Export-ModuleMember -Function * -Alias * |