Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save maxali/a812abce59df139692899f542a21017b to your computer and use it in GitHub Desktop.
Save maxali/a812abce59df139692899f542a21017b to your computer and use it in GitHub Desktop.
# code snippet from this Stackoverflow answer https://stackoverflow.com/a/33574883
Function Test-IfAlreadyRunning {
<#
.SYNOPSIS
Kills CURRENT instance if this script already running.
.DESCRIPTION
Kills CURRENT instance if this script already running.
Call this function VERY early in your script.
If it sees itself already running, it exits.
Uses WMI because any other methods because we need the commandline
.PARAMETER ScriptName
Name of this script
Use the following line *OUTSIDE* of this function to get it automatically
$ScriptName = $MyInvocation.MyCommand.Name
.EXAMPLE
$ScriptName = $MyInvocation.MyCommand.Name
Test-IfAlreadyRunning -ScriptName $ScriptName
.NOTES
$PID is a Built-in Variable for the current script''s Process ID number
.LINK
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)]
[ValidateNotNullorEmpty()]
[String]$ScriptName
)
#Get array of all powershell scripts currently running
$PsScriptsRunning = get-wmiobject win32_process | where{$_.processname -eq 'powershell.exe'} | select-object commandline,ProcessId
#Get name of current script
#$ScriptName = $MyInvocation.MyCommand.Name #NO! This gets name of *THIS FUNCTION*
#enumerate each element of array and compare
ForEach ($PsCmdLine in $PsScriptsRunning){
[Int32]$OtherPID = $PsCmdLine.ProcessId
[String]$OtherCmdLine = $PsCmdLine.commandline
#Are other instances of this script already running?
If (($OtherCmdLine -match $ScriptName) -And ($OtherPID -ne $PID) ){
Write-host "PID [$OtherPID] is already running this script [$ScriptName]"
Write-host "Exiting this instance. (PID=[$PID])..."
Start-Sleep -Second 7
Exit
}
}
} #Function Test-IfAlreadyRunning
#Main
#Get name of current script
$ScriptName = $MyInvocation.MyCommand.Name
Test-IfAlreadyRunning -ScriptName $ScriptName
write-host "(PID=[$PID]) This is the 1st and only instance allowed to run" #this only shows in one instance
read-host 'Press ENTER to continue...' # aka Pause
#Put the rest of your script here
@LinuxOnTheDesktop
Copy link

I have made use of this code. Thank you for providing it. However, as of Powershell version I-don't-know-what, it stopped working. Or rather: I replaced get-wmiobject, which is depreciated, with Get-CimObject and now I find that the latter . . has been dropped entirely from PowerShell. Ouch!

@maxali
Copy link
Author

maxali commented Feb 27, 2023

@LinuxOnTheDesktop it seems that way and its been documented here

@LinuxOnTheDesktop
Copy link

@maxali: thanks. So, the code needs rewriting (and I myself lack the knowledge - I am not good at PowerShell - to do it).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment