Kill 1st script from 2nd script

I had a post about this yesterday and was deleted from the migration so I am re-posting.

Basically I have a HelpDesk Tool from a gui powershell script. I wanted a way to have it check if there is an updated version, kill the running copy, copy down the latest and then run the new copy.

In my form load I have this (I am leaving out the part about checking the version because it works fine):

		if ([System.Windows.Forms.MessageBox]::Show("There is a newer version of the HelpDesk Tool available.`nWould you like to update it now?", "Updated Version Available", [System.Windows.Forms.MessageBoxButtons]::YesNo) -eq "Yes")

Then the Updatetool.ps1:

Get-Process "HelpDesk Tool" |   Foreach-Object { $_.CloseMainWindow() | Out-Null } | stop-process –force
sleep 1
copy "\\MyFileServer\HelpDeskTool\HelpDesk Tool.exe" $env:USERPROFILE"\Desktop\"
invoke-item "$env:USERPROFILE\Desktop\HelpDesk Tool.exe"

The problem with this is it seems like the Updatetool script which is called from the Main script is keeping the Main script open until it is done preventing it from killing the Main script.

I had received a response from my deleted post that basically said to run the update script from the start and have it call the Main script. I can do this but was hoping to find a way to do it the way I originally wanted…if possible.

After some searching I tried this:

		if ([System.Windows.Forms.MessageBox]::Show("There is a newer version of the HelpDesk Tool available.`nWould you like to update it now?", "Updated Version Available", [System.Windows.Forms.MessageBoxButtons]::YesNo) -eq "Yes")
			start-job -filepath \\MyFileServer\HelpDeskTool\Updatetool.ps1

and this did kill the process of the Main script (but did nothing else), I think also killed the UpdateTool script as well. Is that because it was called from the Main script which has now been killed?

Any ideas?


So… if Script A calls another script, they’re still all in the same PowerShell process. Because PowerShell is single-threaded, there’s no “background” task that can watch over a “secondary” task. Jobs - as you tried in the second example - don’t run interactively, they run entirely in the background - so they can’t launch a script that people are meant to interact with.

Accept that whatever you do here is going to be a little hack-y :slight_smile: because you’re kind of beyond what PowerShell was envisioned to do.

Another difficulty is that you can’t have one script download a new copy of itself while it’s still running. Well, not easily. I’ve run through a couple of permutations and I’m not coming up with anything that’ll be guaranteed to work that won’t be extremely ugly and involve fifty moving parts and be very delicate. The trick is that whatever process is doing the killing needs to be separate from whatever is being killed. So maybe, instead of running Script B from Script A, Script A actually starts a new PowerShell process that runs Script B (e.g., Start-Process or something). Script A then ends once Script B is running. If Script B detects an update, it again starts a new process (Script C), and ends itself. Script C maybe waits a few seconds for Script B to finish up, updates everything, starts a new process, and ends itself.

The trick is to have each process naturally end itself when the time comes, and start a new process (not just run a script, but a new powershell.exe process) to carry things on.

Easy enough, two separate ps1. main ps1 checks for a string in your actual helpdesk script.

#   do some comparison stuff look for differences, download new helpdeskchild ps1 if required.	
#	 compare (gc .\heldeskchild.Export.ps1) (gc .\heldeskchildver3.Export.ps1)
#	InputObject                                  SideIndicator
#	----------- -------------
#	Generated on:       10/20/2016 11:27 AM =>
#	$version = 3 = >
#	Generated on:       10/20/2016 11:19 AM <=
#	$version = 2                             <=
	if ([System.Windows.Forms.MessageBox]::Show("There is a newer version of the HelpDesk Tool available...", "", [System.Windows.Forms.MessageBoxButtons]::YesNo) -eq "Yes") {
		#do copy stuff, compare again. 
		if (1 -eq 1) {
	$labelHelpdeskmain.Text = 'Seriously, you really should update'

#Event Argument: $_ = [System.Windows.Forms.FormClosedEventArgs]
	$form1.Visible = $false
	iex .\heldeskchild.Export.ps1

The second get-content would obviously be the script on a network share, I just used another to demonstrate. Using exe you could probably compare the properties of the files.

Sorry I did not write back earlier. Apparently my issue was not using Start-Process to start the 2nd script, I am very new to powershell but learning every day. Sometimes I know what I want to ask but have problems formulating the question right :slight_smile:

Launching like this:

iex .\heldeskchild.Export.ps1

on form.close acted weird to me and since I am still new it could have been something I was doing wrong. It seemed like it got to the end and actually ran through my UpdateTool.ps1 script (with the main for still opened), I know this because I counted the sleeps I used for testing, then closed my form and did nothing else.

Here is what worked:

if ([System.Windows.Forms.MessageBox]::Show("There is a newer version of the HelpDesk Tool available.`nWould you like to update it now?", "Updated Version Available", [System.Windows.Forms.MessageBoxButtons]::YesNo) -eq "Yes")
Start-Process powershell -Args '-ExecutionPolicy Bypass -File "\\MyFileserver\HelpDeskTool\Updatetool.ps1"'

and the Updatetool.ps1:

Write-Output "Updating HelpDesk Tool.....please wait"
Get-Process "HelpDesk Tool" |   Foreach-Object { $_.CloseMainWindow() | Out-Null } | stop-process –force
Sleep 1
copy "\\MyFileserver\HelpDeskTool\HelpDesk Tool.exe" $env:USERPROFILE"\Desktop\"
Sleep 1
invoke-item "$env:USERPROFILE\Desktop\HelpDesk Tool.exe"

Thanks to Don Jones for breaking everything down for me and Dan Potter for the example. Lately examples are the best way for me to learn :slight_smile: