usr/Suspend-PsProcess.ps1

Set-Alias -Name psuspend -Value Suspend-PsProcess
function Suspend-PsProcess {
  <#
    .SYNOPSIS
        Suspends selected processes.
    .DESCRIPTION
        It doesn't matter if you entered a process ID(s) or a process name(s), just
        be aware that it's not possible to enter they both at the same time. Perhaps
        in the future this feature will be implemented, but not currently.
    .EXAMPLE
        Suspend-PsProcess notepad, regedit -Verbose
    .EXAMPLE
        Suspend-PsProcess 3306, 580 -Verbose
    .INPUTS
        [String[]] or [Int32[]]
    .OUTPUTS
        None
  #>

  [CmdletBinding()]param($PSBoundParameters)

  end {
    New-Delegate ntdll {
      int NtSuspendProcess([ptr])
    }

    New-PsProxy $PSBoundParameters -Callback {
      if ([Linq.Enumerable]::Sum([Int32[]](
        Select-Object -InputObject $_.Threads[0] -Property ThreadState, WaitReason
      ).PSObject.Properties.Value.ForEach{$_ -eq 5}) -ne 2) {
        if (($nts = $ntdll.NtSuspendProcess.Invoke($_.Handle)) -ne 0) {
          Write-Verbose (ConvertTo-ErrMessage -NtStatus $nts)
        }
        else {Write-Verbose "Process $($_.Id) is suspended."}
      }
      else {Write-Verbose "Process $($_.Id) is already suspended."}
    }
  }
}

Export-ModuleMember -Alias psuspend -Function Suspend-PsProcess