Last active
September 4, 2024 01:09
-
-
Save stakach/396a623cc102679136af29ded5a4d004 to your computer and use it in GitHub Desktop.
powershell code for cleaning up all processes and child processes launched as part of the script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if (-not [System.Management.Automation.PSTypeName]'JobObject'.Type) { | |
Add-Type @" | |
using System; | |
using System.Runtime.InteropServices; | |
public class JobObject | |
{ | |
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] | |
public static extern IntPtr CreateJobObject(IntPtr lpJobAttributes, string lpName); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
public static extern bool AssignProcessToJobObject(IntPtr hJob, IntPtr hProcess); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
public static extern bool TerminateJobObject(IntPtr hJob, uint uExitCode); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
public static extern bool CloseHandle(IntPtr hObject); | |
} | |
"@ | |
} | |
# Create a Job Object | |
$jobHandle = [JobObject]::CreateJobObject([IntPtr]::Zero, "TestJobObject") | |
if ($jobHandle -eq [IntPtr]::Zero) { | |
throw "Failed to create Job Object: $([System.ComponentModel.Win32Exception]::new([Runtime.InteropServices.Marshal]::GetLastWin32Error()).Message)" | |
} | |
try { | |
# Start the child process (launch some processes from this, i.e. msinfo32 etc and then ctrl-c this script) | |
$childProcess = Start-Process -FilePath "cmd.exe" -PassThru | |
# Assign the process to the job object | |
$processHandle = (Get-Process -Id $childProcess.Id).Handle | |
if (-not [JobObject]::AssignProcessToJobObject($jobHandle, $processHandle)) { | |
throw "Failed to assign process to Job Object: $([System.ComponentModel.Win32Exception]::new([Runtime.InteropServices.Marshal]::GetLastWin32Error()).Message)" | |
} | |
# Wait for either Ctrl-C or the process to exit | |
while (!$childProcess.HasExited) { | |
Start-Sleep -Milliseconds 500 | |
} | |
} finally { | |
# Clean up - explicitly terminate all processes in the job | |
Write-Host "Terminating job object and exiting." | |
if (-not [JobObject]::TerminateJobObject($jobHandle, 0)) { | |
Write-Host "Failed to terminate Job Object: $([System.ComponentModel.Win32Exception]::new([Runtime.InteropServices.Marshal]::GetLastWin32Error()).Message)" | |
} | |
if (-not [JobObject]::CloseHandle($jobHandle)) { | |
Write-Host "Failed to close Job Object handle: $([System.ComponentModel.Win32Exception]::new([Runtime.InteropServices.Marshal]::GetLastWin32Error()).Message)" | |
} | |
exit 1 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment