[CmdletBinding()]param(
    [string[]]$Command,
    [string[]]$Remotes = 'all',
    [string[]]$MoreArgs,
    [switch]$NotPowerShell,
    [switch]$RawOutput
)

$script:ansible_cli=@('ansible')
if( (Test-Path './ansible.cfg') -or (Test-Path '/opt/ansible/hosts') -and (Test-Path '/opt/ansible/ssh_key_for_ansible') ) {
    $ansible_cli += '-i', '/opt/ansible/hosts', '--private-key=/opt/ansible/ssh_key_for_ansible'
}
if( $Command ) {
    $ansible_cli += '-a'
    $ansible_cli += 'ANSIBLE_PYTHON_INTERPRETER=auto_silent '
    $ansible_cli += '-a'
    if( $NotPowerShell ) {
        $ansible_cli += $(($Command -join '; ').Replace("'","\`$(printf '\x27')").Replace('"',"\`$(printf '\x22')"))
    } else {
        $ansible_cli += "pwsh -encodedcommand $(ConvertTo-Base64 $($Command -join '; '))"
    }
}
if( -not $RawOutput ) {
    $ansible_cli += '--one-line'
}
$ansible_cli += $Remotes
$ansible_cli += $MoreArgs

$local:expr = $('& "'+$($ansible_cli -join '" "')+'"')
Write-Verbose $expr
$local:SaveConsoleColor = [Console]::ForegroundColor
$env:ANSIBLE_DEPRECATION_WARNINGS='false'
$local:sw = [System.Diagnostics.Stopwatch]::StartNew()
Invoke-Expression $expr | ForEach-Object {
    if( $RawOutput ) { return $_ };
    $local:res = $_.Split('|') + @('', '', '', '')
    $res = [PSCustomObject]([ordered]@{
        Machine = $res[0].Trim();
        Status = @($res[1].Trim(), "$($res[2])".Trim())
        RunTime = $sw.Elapsed
        Output = "$($res[3])".Trim() -split '\\n';
    })
    $res.PSObject.TypeNames.Insert(0,"AnsibleOutput")
    if( $res.Status -match '^\w+!:' ) {
      [Console]::ForegroundColor = [ConsoleColor]::Red
    } else {
      [Console]::ForegroundColor = [ConsoleColor]::Yellow
    }
    
    $res
}

[Console]::ForegroundColor = $SaveConsoleColor