src/Suspend-PsActivity.ps1
#requires -version 6 using namespace System.Linq using namespace System.ComponentModel function Suspend-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 @{ NtSuspendProcess = [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}) -ne 2) { if (($nts = $ntdll.NtSuspendProcess.Invoke($_.Handle)) -ne 0) { Write-Verbose "$([Win32Exception]::new( $ntdll.RtlNtStatusToDosError.Invoke($nts) ).Message)" } else { Write-Verbose "Process $($_.Id) is suspended." } } else { Write-Verbose "Process $($_.Id) is already suspended." } $_.Dispose() } } } |