Examples/Process_Killer.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
Import-Module "..\AnyBox.psd1"

# Define the computer name prompt; the field must not be empty and the computer must be online.
$p = @(New-Prompt -Group 0 -Name 'pcName' -Message 'Computer Name:' -MessagePosition 'Left' -DefaultValue 'Localhost' `
                  -ValidateNotEmpty -ValidateScript { Test-Connection $_ -Count 1 -Quiet -ea 0})

# Define the process filter prompt
$p += @(New-Prompt -Group 0 -Name 'pFilter' -Message ' Process Name:' -MessagePosition 'Left' -DefaultValue '*' `
                    -ValidateNotEmpty)

# Define the 'Refresh' button.
$b = @(New-Button -Text 'Refresh' -IsDefault -OnClick {

  # Run 'Test-ValidateInput' to enforce
  # the validation parameters set on the 'pcName' prompt.
  $input_test = Test-ValidInput -Prompts $Prompts -Inputs $form.Result
  if (-not $input_test.Is_Valid) {
    $null = Show-AnyBox @childWinParams -Message $input_test.Message -Buttons $(New-AnyBoxButton -Text 'OK' -IsDefault)
    $form['data_grid'].ItemsSource = $null
  }
  else {
    [string]$msg = $null
    try {
      # Get all running process matching the filter.
      # '$_.pcName' will access the text in the 'pcName' prompt.
      # '$_.pFilter' will access the text in the 'pFilter' prompt.
      $new_data = @(Get-WmiObject -cn $_.pcName -Class 'Win32_Process' `
                                  -Filter "Name LIKE '$($_.pFilter.Replace('*', '%'))'" -ea Stop |
                    select ProcessId, ProcessName, CommandLine)

      if ($new_data.Length -eq 0) {
        $form['data_grid'].ItemsSource = $null
        $msg = 'No processes match the provided filter.'
      }
      else {
        # Update the grid with matching processes.
        $form['data_grid'].ItemsSource = $new_data
      }
    }
    catch {
      $msg = $_.Exception.Message
    }

    # If an error occurs, show another AnyBox.
    # Show a child window with @childWinParams.
    if ($msg) { Show-AnyBox @childWinParams -Message $msg -Buttons 'OK' }
  }
})

$b += New-AnyBoxButton -Template 'SaveGrid'

$b += @(New-Button -Text 'Kill' -OnClick {
  # Run 'Test-ValidateInput' to enforce
  # the validation parameters set on the 'pcName' prompt.
  $input_test = Test-ValidInput -Prompts $Prompts -Inputs $form.Result
  if (-not $input_test.Is_Valid) {
    $null = Show-AnyBox @childWinParams -Message $input_test.Message -Buttons $(New-AnyBoxButton -Text 'OK' -IsDefault)
    $form['data_grid'].ItemsSource = $null
  }
  else {
    # Access selected grid rows with 'grid_select'.
    [array]$toKill = @($_.grid_select | select ProcessId, ProcessName)

    if ($toKill.Length -eq 0) {
      $null = Show-AnyBox @childWinParams -Message 'Select processes to kill.' -Buttons 'OK'
    }
    else {
      # Confirm before killing the selected processes.
      $answer = Show-AnyBox @childWinParams -Message 'Are you sure you want to kill the following processes?' `
                  -GridData $toKill -Buttons 'Cancel', 'Confirm'

      if ($answer['Confirm'])
      {
        [string]$pcName = $_.pcName

        $killed = @($toKill | foreach {
          [int]$code = 0
          [string]$msg = $null

          try {
            $code = ([wmi]"\\$pcName\root\cimv2:Win32_Process.Handle='$($_.ProcessId)'").Terminate().ReturnValue
            if ($code -eq 0) {
              $msg = 'Successfully closed.'
            }
          }
          catch {
            $code = -1
            $msg = $_.Exception.Message
          }

          $_ | select ProcessId, ProcessName, @{Name='Code';Expression={$code}}, @{Name='Message';Expression={$msg}}
        })

        [string]$msg = $null
        try {
          $new_data = @(Get-WmiObject -cn $_.pcName -Class 'Win32_Process' `
                                      -Filter "Name LIKE '$($_.pFilter.Replace('*', '%'))'" -ea Stop |
                        select ProcessId, ProcessName, CommandLine)

          if ($new_data.Length -eq 0) {
            $form['data_grid'].ItemsSource = $null
          }
          else {
            $form['data_grid'].ItemsSource = $new_data
          }
        }
        catch {
          $msg = $_.Exception.Message
        }

        # Output the results in child AnyBox with a DataGrid.
        $null = Show-AnyBox @childWinParams -GridData $killed -Buttons 'OK'

        # If an error occurred, show it in a child AnyBocx.
        if ($msg) { $null = Show-AnyBox @childWinParams -Message $msg -Buttons 'OK' }
      }
    }
  }
})

$grid_data = @(Get-WmiObject -Class Win32_Process -ea Stop | select ProcessId, ProcessName, CommandLine)

Show-AnyBox -ResizeMode 'CanResizeWithGrip' -Title 'Process Killer' -MaxHeight 1000 -MaxWidth 1200 -Topmost `
  -AccentColor 'Black' -Buttons $b -Prompts $p -GridData $grid_data -HideGridSearch -SelectionMode 'MultiRow' |
    Out-Null