Functions/Invokation/CommandExecution/RunSpacePool/Invoke-ValentiaAsync.ps1

#Requires -Version 3.0

#-- Public Module Asynchronous / Functions for Remote Execution --#

# valea

<#
.SYNOPSIS
Run Asynchronous valentia execution to remote host
 
.DESCRIPTION
Asynchronous running thread through AsyncPipeLine handling PS Runspace.
Allowed to run from C# code.
 
.NOTES
Author: guitarrapc
Created: 20/June/2013
 
.EXAMPLE
  valea 192.168.1.100 {Get-ChildItem}
--------------------------------------------
Get-ChildItem ScriptBlock execute on 192.168.1.100
 
.EXAMPLE
  valea 192.168.1.100 {Get-ChildItem; hostname}
--------------------------------------------
You can run multiple script in pipeline.
 
.EXAMPLE
  valea 192.168.1.100 .\default.ps1
--------------------------------------------
You can prepare script file to run, and specify path.
 
.EXAMPLE
  valea 192.168.1.100,192.168.1.200 .\default.ps1
--------------------------------------------
You can target multiple deploymember with comma separated. Running Asynchronously.
 
.EXAMPLE
  valea DeployGroupFile.ps1 {ScriptBlock}
--------------------------------------------
Specify DeployGroupFile and ScriptBlock
 
.EXAMPLE
  valea DeployGroupFile.ps1 .\default.ps1
--------------------------------------------
You can prepare script file to run, and specify path.
#>

function Invoke-ValentiaAsync
{
    [CmdletBinding(DefaultParameterSetName = "TaskFileName")]
    param
    (
        [Parameter(Position = 0, mandatory = $true, HelpMessage = "Input target of deploy clients as [DeployGroup filename you sat at deploygroup Folder] or [ipaddress].")]
        [string[]]$DeployGroups,

        [Parameter(Position = 1, mandatory = $true, ParameterSetName = "TaskFileName", HelpMessage = "Move to Brach folder you sat taskfile, then input TaskFileName. exclusive with ScriptBlock.")]
        [ValidateNotNullOrEmpty()]
        [string]$TaskFileName,

        [Parameter(Position = 1, mandatory = $true, ParameterSetName = "SctriptBlock", HelpMessage = "Input Script Block {hogehoge} you want to execute with this commandlet. exclusive with TaskFileName")]
        [ValidateNotNullOrEmpty()]
        [ScriptBlock]$ScriptBlock,

        [Parameter(Position = 2, mandatory = $false, HelpMessage = "Usually automatically sat to DeployGroup Folder. No need to modify.")]
        [ValidateNotNullOrEmpty()]
        [string]$DeployFolder = (Join-Path $script:valentia.RootPath ([ValentiaBranchPath]::Deploygroup)),

        [Parameter(Position = 3, mandatory = $false, HelpMessage = "Input parameter pass into task's arg[0....x].Values")]
        [ValidateNotNullOrEmpty()]
        [hashtable]$TaskParameter,

        [Parameter(Position = 4, mandatory = $false, HelpMessage = "Hide execution progress.")]
        [switch]$Quiet,

        [Parameter(Position = 5, mandatory = $false, HelpMessage = "Input PSCredential to use for wsman.")]
        [PSCredential]$Credential = (Get-ValentiaCredential),

        [Parameter(Position = 6, mandatory = $false, HelpMessage = "Select Authenticateion for Credential.")]
        [System.Management.Automation.Runspaces.AuthenticationMechanism]$Authentication = $valentia.Authentication,

        [Parameter(Position = 7, mandatory = $false, HelpMessage = "Select SSL is use or not.")]
        [switch]$UseSSL = $valentia.UseSSL,

        [Parameter(Position = 8, mandatory = $false, HelpMessage = "Return success result even if there are error.")]
        [bool]$SkipException = $false
    )

    process
    {
        try
        {
        #region Prerequisite
        
            # Prerequisite setup
            $prerequisiteParam = @{
                Stopwatch     = $TotalstopwatchSession
                DeployGroups  = $DeployGroups
                TaskFileName  = $TaskFileName
                ScriptBlock   = $ScriptBlock
                DeployFolder  = $DeployFolder
                TaskParameter = $TaskParameter
            }
            Set-ValentiaInvokationPrerequisites @prerequisiteParam

        #endregion

        #region Process

            # RunSpace execution
            $param = @{
                Credential      = $Credential
                TaskParameter   = $TaskParameter
                Authentication  = $Authentication
                UseSSL          = $UseSSL
                SkipException   = $SkipException
                ErrorAction     = $originalErrorAction
                quiet           = $Quiet
            }
            Invoke-ValentiaRunspaceProcess @param

        #endregion

        }
        catch
        {
            $valentia.Result.SuccessStatus += $false
            $valentia.Result.ErrorMessageDetail += $_
            if (-not $SkipException)
            {
                throw $_
            }
        }
        finally
        {
            # obtain Result
            $resultParam = @{
                StopWatch     = $TotalstopwatchSession
                Cmdlet        = $($MyInvocation.MyCommand.Name)
                TaskFileName  = $TaskFileName
                DeployGroups  = $DeployGroups
                SkipException = $SkipException
                Quiet         = $PSBoundParameters.ContainsKey("quiet") -and $quiet
            }
            Out-ValentiaResult @resultParam

            # Cleanup valentia Environment
            Invoke-ValentiaClean
        }
    }

    begin
    {
        # Initialize Stopwatch
        $TotalstopwatchSession = [System.Diagnostics.Stopwatch]::StartNew()

        # Reset ErrorActionPreference
        if ($PSBoundParameters.ContainsKey('ErrorAction'))
        {
            $originalErrorAction = $ErrorActionPreference
        }
        else
        {
            $originalErrorAction = $ErrorActionPreference = $valentia.preference.ErrorActionPreference.original
        }
    }
}