src/Resume-PsActivity.ps1

#requires -version 6
using namespace System.Linq
using namespace System.ComponentModel

function Resume-PsActivity {
  [CmdletBinding(DefaultParameterSetName='Name')]
  param(
    [Parameter(Mandatory, ParameterSetName='Name', Position=0)]
    [ValidateNotNullOrEmpty()]
    [ValidateScript({!!($script:ps = Get-Process $_ -ErrorAction 0)})]
    [String]$Name,

    [Parameter(Mandatory, ParameterSetName='Id', Position=0)]
    [ValidateScript({!!($script:ps = Get-Process -Id $_ -ErrorAction 0)})]
    [Int32]$Id
  )

  process {
    $ntdll = New-Delegate ntdll -Signature @{
      NtResumeProcess = [Func[IntPtr, Int32]]
      RtlNtStatusToDosError = [Func[Int32, Int32]]
    }

    $ps.ForEach{
      if ([Enumerable]::Sum([Int32[]](
        Select-Object -InputObject $_.Threads[0] -Property ThreadState, WaitReason
      ).PSObject.Properties.Value.ForEach{$_ -eq 5}) -eq 2) {
        if (($nts = $ntdll.NtResumeProcess.Invoke($_.Handle)) -ne 0) {
          Write-Verbose "$([Win32Exception]::new(
            $ntdll.RtlNtStatusToDosError.Invoke($nts)
          ).Message)"

        }
        else { Write-Verbose "Process $($_.Id) is resumed." }
      }
      else { Write-Verbose "Process $($_.Id) is already active." }
      $_.Dispose()
    }
  }
}