Public/Install-SMBeat.ps1

#Requires -Version 5.1

function Install-SMBeat {
    <#
    .SYNOPSIS
        Copies the SMBeat module into WindowsPowerShell\Modules (local or remote).
    #>

    [CmdletBinding(DefaultParameterSetName = 'Local')]
    param(
        [Parameter(ParameterSetName = 'ComputerName', ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [string[]]$ComputerName,

        [Parameter(ParameterSetName = 'Session')]
        [System.Management.Automation.Runspaces.PSSession[]]$Session,

        [pscredential]$Credential,
        [System.Management.Automation.Runspaces.AuthenticationMechanism]$Authentication,
        [switch]$UseSSL,
        [int]$Port,
        [System.Management.Automation.Remoting.PSSessionOption]$SessionOption,
        [int]$ThrottleLimit = 32
    )

    begin {
        Assert-SMBeatRemotingExclusive -ComputerName $ComputerName -CimSession $null -Session $Session
        $sourceRoot = $script:SMBeatModuleRoot
        $copyNames = @('SMBeat.psd1', 'SMBeat.psm1', 'Public', 'Private', 'Scripts', 'en-US', 'LICENSE')
    }

    process {
        if ($PSCmdlet.ParameterSetName -eq 'Local') {
            $dest = Get-SMBeatInstallDestination
            if (-not (Test-Path -LiteralPath $dest)) {
                New-Item -ItemType Directory -Path $dest -Force | Out-Null
            }
            foreach ($name in $copyNames) {
                $from = Join-Path $sourceRoot $name
                if (Test-Path -LiteralPath $from) {
                    Copy-Item -LiteralPath $from -Destination $dest -Recurse -Force
                }
            }
            Get-Item -LiteralPath $dest
            return
        }

        $sessionsToClose = @()
        $targets = $Session
        if ($PSCmdlet.ParameterSetName -eq 'ComputerName') {
            $newParams = @{ ComputerName = $ComputerName; ErrorAction = 'Stop' }
            if ($Credential) { $newParams['Credential'] = $Credential }
            if ($PSBoundParameters.ContainsKey('Authentication')) { $newParams['Authentication'] = $Authentication }
            if ($UseSSL) { $newParams['UseSSL'] = $true }
            if ($Port) { $newParams['Port'] = $Port }
            if ($SessionOption) { $newParams['SessionOption'] = $SessionOption }
            $targets = @(New-PSSession @newParams)
            $sessionsToClose = $targets
        }

        try {
            foreach ($s in $targets) {
                try {
                    $dest = Invoke-Command -Session $s -ScriptBlock {
                        $path = Join-Path $env:ProgramFiles 'WindowsPowerShell\Modules\SMBeat'
                        New-Item -ItemType Directory -Path $path -Force | Out-Null
                        $path
                    }
                    foreach ($name in $copyNames) {
                        $from = Join-Path $sourceRoot $name
                        if (Test-Path -LiteralPath $from) {
                            Copy-Item -LiteralPath $from -Destination $dest -ToSession $s -Recurse -Force
                        }
                    }
                    [PSCustomObject]@{
                        ComputerName = $s.ComputerName
                        Path         = $dest
                        Success      = $true
                    }
                }
                catch {
                    $record = New-SMBeatErrorRecord -Message $_.Exception.Message -ComputerName $s.ComputerName -Exception $_.Exception
                    $PSCmdlet.WriteError($record)
                }
            }
        }
        finally {
            if ($sessionsToClose.Count -gt 0) {
                Remove-PSSession -Session $sessionsToClose -ErrorAction SilentlyContinue
            }
        }
    }
}