Private/Remoting.ps1

#Requires -Version 5.1

function Assert-SMBeatRemotingExclusive {
    param(
        [string[]]$ComputerName,
        $CimSession,
        $Session
    )

    $count = 0
    if ($ComputerName -and $ComputerName.Count -gt 0) { $count++ }
    if ($CimSession) { $count++ }
    if ($Session) { $count++ }

    if ($count -gt 1) {
        throw 'The parameters ComputerName, CimSession, and Session cannot be used together.'
    }
}

function Get-SMBeatRemoteSplat {
    param(
        $Bound
    )

    $splat = @{}
    foreach ($name in @('ComputerName', 'Credential', 'CimSession', 'Session', 'Authentication', 'UseSSL', 'Port', 'SessionOption', 'ThrottleLimit')) {
        if ($Bound.ContainsKey($name) -and $null -ne $Bound[$name]) {
            $splat[$name] = $Bound[$name]
        }
    }
    return $splat
}

function Test-SMBeatHasRemoteTarget {
    param($Bound)

    $Bound.ContainsKey('ComputerName') -or $Bound.ContainsKey('CimSession') -or $Bound.ContainsKey('Session')
}

function Get-SMBeatInvokeCommandParams {
    param(
        [string[]]$ComputerName,
        $Session,
        [pscredential]$Credential,
        $Authentication,
        [switch]$UseSSL,
        [int]$Port,
        $SessionOption,
        [int]$ThrottleLimit,
        [scriptblock]$ScriptBlock,
        [object[]]$ArgumentList
    )

    $params = @{
        ScriptBlock = $ScriptBlock
        ErrorAction = 'Continue'
    }

    if ($ThrottleLimit -gt 0) {
        $params['ThrottleLimit'] = $ThrottleLimit
    }

    if ($null -ne $ArgumentList) {
        $params['ArgumentList'] = $ArgumentList
    }

    if ($Session) {
        $params['Session'] = $Session
        return $params
    }

    $params['ComputerName'] = $ComputerName

    if ($Credential) {
        $params['Credential'] = $Credential
    }
    if ($null -ne $Authentication) {
        $params['Authentication'] = $Authentication
    }
    if ($UseSSL) {
        $params['UseSSL'] = $true
    }
    if ($Port -gt 0) {
        $params['Port'] = $Port
    }
    if ($SessionOption) {
        $params['SessionOption'] = $SessionOption
    }

    return $params
}

function Invoke-SMBeatRemoteCommand {
    [CmdletBinding()]
    param(
        [string[]]$ComputerName,
        $Session,
        [pscredential]$Credential,
        $Authentication,
        [switch]$UseSSL,
        [int]$Port,
        $SessionOption,
        [int]$ThrottleLimit = 32,
        [Parameter(Mandatory = $true)]
        [scriptblock]$ScriptBlock,
        [object[]]$ArgumentList
    )

    $params = Get-SMBeatInvokeCommandParams -ComputerName $ComputerName -Session $Session -Credential $Credential -Authentication $Authentication -UseSSL:$UseSSL -Port $Port -SessionOption $SessionOption -ThrottleLimit $ThrottleLimit -ScriptBlock $ScriptBlock -ArgumentList $ArgumentList
    Invoke-Command @params
}

function New-SMBeatErrorRecord {
    param(
        [Parameter(Mandatory = $true)]
        [string]$Message,
        [string]$ComputerName,
        [string]$ErrorId = 'SMBeat.RemoteError',
        [System.Management.Automation.ErrorCategory]$Category = [System.Management.Automation.ErrorCategory]::OperationStopped,
        $Exception
    )

    if ($null -eq $Exception) {
        $Exception = New-Object System.Exception $Message
    }

    New-Object System.Management.Automation.ErrorRecord $Exception, $ErrorId, $Category, $ComputerName
}