Resources/New-ProjectTemplate/Functions.psm1

$Script:Config = Import-PowerShellDataFile -Path "$PSScriptRoot\config.psd1"

function UnProtect-Config
{
    <#
    .SYNOPSIS
       Intenta descifrar una cadena protegida.
    .DESCRIPTION
       Intenta descifrar una cadena que fue protegida utilizando la función Protect-String en el módulo Carbon.
    .EXAMPLE
        Intenta descifrar una cadena en claro
       'Hola Mundo' | UnProtect-Config
    .EXAMPLE
        Intenta descifrar una cadena en cifrada con Protect-String
       'AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAApY8XQBGb6Ue5Ph226jh4+QQAAAACAAAAAAADZgAAwAAAABAAAAAL/8TJ4/sKEVvTQtG0050zAAAAAASAAACgAAAAEAAAAIn/ihLL1Jvmk1/8INDyaScQAAAAxL0oSRmBcNDU1I3viGyGChQAAAAmGDfc8qJVsdjklGLypSZgs35hdQ==' | UnProtect-Config
    .INPUTS
       Cadena de texto cifrada o descrifada.
    .OUTPUTS
       Cadena de texto descrifada (si estaba cifrada). Si la cadena no estaba cifrada se retorna la misma cadena de entrada.
    #>

     [OutputType([string])]
     param
     (
         [Parameter(Mandatory,ValueFromPipeline)]
         [ValidateNotNullOrEmpty()]
         [string]
         $Text
     )

     try{
        ($Text | Unprotect-String) | Write-Output
     }
     catch [System.FormatException]{
        $Text | Write-Output
     }
}

function Start-TranscriptLogFile
{
    <#
    .SYNOPSIS
       Envía la salida de la sesión de PowerShell a un archivo de texto.
    .DESCRIPTION
       Envía la salida de la sesión de PowerShell a un archivo de texto en la subcarpeta Logs. Se crea un achivo por día calendario.
    .EXAMPLE
       Inicializa la transcripción al archivo predeterminado en la carpeta Logs.
       Initialize-Transcript
    .EXAMPLE
       Inicializa la transcripción al archivo MyAwesomeLog.log en la carpeta Logs.
       Initialize-Transcript -FileName 'MyAwesomeLog'
    .INPUTS
       Cadena de texto con el nombre del archivo a generar (omita oara utilizar el nombre predeterminado).
    .OUTPUTS
       Ruta de acceso del archivo donde se está transcribiendo la sesión.
    #>


    [CmdletBinding()]
    [OutputType([string])]
    Param
    (
         [Parameter(ValueFromPipeline)]
         [string]
         $FileName = [System.IO.Path]::GetFileNameWithoutExtension($MyInvocation.ScriptName),

         [Parameter()]
         [bool]
         $Append = $true
    )

    $LogFolderPath = Join-Path -Path $MyInvocation.PSScriptRoot -ChildPath 'Logs'
    $LogFileName = '{0}_{1:yyyy-MM-dd}.log' -f $FileName, (Get-Date)
    New-Item -Path $LogFolderPath -ItemType 'Directory' -ErrorAction SilentlyContinue | Out-Null
    $TranscriptFileName = Join-Path -Path $LogFolderPath -ChildPath $LogFileName
    $TranscriptParams = @{Path=$TranscriptFileName;Force=$true;Append=$Append}
    $TranscriptParams | ConvertTo-Json | Write-Verbose
    Start-Transcript @TranscriptParams | Out-Null            
    $Script:TranscriptStarted = $true
    $TranscriptFileName | Write-Output
}

function Stop-TranscriptLogFile
{
    if ($Script:TranscriptStarted){
        Stop-Transcript
    }
}

function Invoke-SqlCommand 
{
    <#
    .SYNOPSIS
       Ejecuta una instrucción SQL.
    .DESCRIPTION
       Ejecuta una instrucción SQL y retorna el resultado de la ejecución como un DataTable.
    .EXAMPLE
       Ejecuta una instrucción SQL conectándose a la base de datos especificada en el parámetro $ConnectionString.
       $Result = 'select getdate() as CurrentDate' | Invoke-SqlCommand -ConnectionString 'Data Source=(local);Initial Catalog=master;Integrated Security=True' -CommandType Text
       # Acceder al resultado
       # $Result.CurrentDate
    .EXAMPLE
       Ejecuta una instrucción SQL que utiliza parámetros.
       'select * from sys.databases where name = @name' | Invoke-SqlCommand -ConnectionString 'Data Source=(local);Initial Catalog=master;Integrated Security=True' -CommandType Text -ArgumentList @{name='master'}
    .INPUTS
        
    .OUTPUTS
       DataTable con los resultados de la ejecución de la instrucción SQL.
    #>

     [CmdletBinding(DefaultParametersetName='FromString')]
     [OutputType([System.Data.DataTable])]
     param
     (
         [Parameter(Mandatory, ParameterSetName='FromString') ]
         [ValidateNotNullOrEmpty()]         
         [string]         
         $ConnectionString,

         [Parameter(Mandatory, ParameterSetName='FromConnection') ]
         [ValidateNotNull()]
         [System.Data.SqlClient.SqlConnection]         
         $SqlConnection, 

         [Parameter(Mandatory,ValueFromPipeline)]
         [ValidateNotNullOrEmpty()]
         [string]
         $CommandText,

         [Parameter()]
         [System.Data.CommandType]
         $CommandType = [System.Data.CommandType]::StoredProcedure,

         [Parameter()]
         [PSObject]
         $ArgumentList = $null,

         [Parameter()]
         [int]
         $CommandTimeout = 30
     )
 
    if ($PsCmdlet.ParameterSetName -eq 'FromString'){
        $SqlConnection = New-Object -TypeName System.Data.SqlClient.SqlConnection -ArgumentList $ConnectionString
    }

    $SqlCommand = New-Object -TypeName System.Data.SqlClient.SqlCommand -ArgumentList $CommandText,$SqlConnection
    $SqlCommand.CommandTimeout = $CommandTimeout
    $SqlCommand.CommandType = $CommandType

    if ($SqlConnection.State -ne [System.Data.ConnectionState]::Open){
        $SqlConnection.Open()
    }

    if ($ArgumentList -ne $null)
    {
        $Enumerator = $ArgumentList.GetEnumerator()
        $Enumerator | ForEach-Object {
            $SqlCommand.Parameters.AddWithValue($_.Key, $_.Value) | Out-Null
        }
    }
   
    $SqlDataAdapter = New-Object -TypeName System.Data.SqlClient.SqlDataAdapter -ArgumentList $SqlCommand
    $SqlDataSet = New-Object -TypeName System.Data.DataSet
    $SqlDataAdapter.Fill($SqlDataSet) | Out-Null
    $SqlDataSet.Tables[0] | Write-Output
    
    if ($PsCmdlet.ParameterSetName -eq 'FromString'){
        $SqlConnection.Dispose()
    }
}