Here is my pure batch script version that resulted from the same DosTips discussion and collaborative effort that npocmaka referenced.
@echo off
:getPID [RtnVar]
::
:: Store the Process ID (PID) of the currently running script in environment variable
:: RtnVar. If called without any argument, then simply write the PID to stdout.
::
setlocal disableDelayedExpansion
:getLock
set "lock=%temp%\%~nx0.%time::=.%.lock"
set "uid=%lock:\=:b%"
set "uid=%uid:,=:c%"
set "uid=%uid:'=:q%"
set "uid=%uid:_=:u%"
setlocal enableDelayedExpansion
set "uid=!uid:%%=:p!"
endlocal & set "uid=%uid%"
2>nul ( 9>"%lock%" (
for /f "skip=1" %%A in (
'wmic process where "name='cmd.exe' and CommandLine like '%%<%uid%>%%'" get ParentProcessID'
) do for %%B in (%%A) do set "PID=%%B"
(call )
))||goto :getLock
del "%lock%" 2>nul
endlocal & if "%~1" equ "" (echo(%PID%) else set "%~1=%PID%"
exit /b
npocmaka's solution installs an exe file (compiled JScript) in the same folder as the batch script.
On my machine, my pure batch getPID runs 20% faster than npocmaka's exe! This is because the exe first determines its own process PID, which takes significant time, before it uses WMI to determine the desired parent PID. My script generates a unique ID (much faster) which gets incorporated into the WMIC call that determines the desired parent PID.
In both solutions, the bulk of the time is spent within WMI where it determines the parent PID of a specific process.