Skip to main content

How to Create a Batch Script That Runs Only Once

In many IT scenarios, you need a script that performs a specific setup task, like mapping a network drive, creating a folder structure, or optimizing registry settings, but you only want it to happen the very first time the script is launched. If the script runs every single day, it might overwrite user changes or waste system resources. This is known as "First-Run Logic."

This guide will explain several methods for ensuring your Batch script logic executes once and then remains dormant for future launches.

Method 1: The "Sentinel File" Method (Easiest)

This approach relies on a small "flag" file that acts as proof that the script has already finished its job.

@echo off
setlocal

set "Sentinel=%localappdata%\myapp_setup_v1.done"

:: Support a /reset flag to allow re-running the setup
if /i "%~1"=="/reset" (
if exist "%Sentinel%" (
del "%Sentinel%" >nul 2>&1
echo [INFO] Setup flag cleared. Setup will run on next launch.
)
exit /b 0
)

:: 1. Check if the sentinel file already exists
if exist "%Sentinel%" (
echo [INFO] Setup has already been performed. Skipping...
goto :MainApp
)

:: 2. Perform the one-time setup tasks
echo [SETUP] Configuring initial settings...

set "SetupFailed=0"

if not exist "C:\MyData\Backup" mkdir "C:\MyData\Backup"
if %errorlevel% neq 0 set "SetupFailed=1"

if not exist "C:\MyData\Logs" mkdir "C:\MyData\Logs"
if %errorlevel% neq 0 set "SetupFailed=1"

:: 3. Only create the sentinel AFTER all tasks succeed
if "%SetupFailed%"=="0" (
echo Setup completed on %date% at %time% > "%Sentinel%"
echo [SETUP] Initial configuration complete.
) else (
echo [ERROR] Setup encountered errors. Will retry on next launch.
)

:MainApp
echo.
echo [OK] Launching application...

pause
endlocal
tip

Always store your sentinel files in a stable location like %localappdata%. If you put it in %temp%, it might get deleted by Windows cleanup, causing the script to run the setup again unexpectedly.

Method 2: The "Registry Flag" Method

If you want a cleaner solution that doesn't leave files in folders, you can store your "Run Once" status in the Windows Registry.

@echo off
setlocal

set "RegKey=HKCU\Software\MyCustomScript"
set "FlagName=SetupComplete"
set "FlagVersion=1"

:: Support a /reset flag
if /i "%~1"=="/reset" (
reg delete "%RegKey%" /v "%FlagName%" /f >nul 2>&1
echo [INFO] Registry flag cleared.
exit /b 0
)

:: Check if the registry flag exists and matches the current version
for /f "tokens=3" %%v in ('reg query "%RegKey%" /v "%FlagName%" 2^>nul ^| findstr /i "%FlagName%"') do (
if "%%v"=="%FlagVersion%" (
echo [OK] Setup v%FlagVersion% already applied. Skipping.
goto :Finish
) else (
echo [INFO] Previous version detected. Re-running setup for v%FlagVersion%...
)
)

:: Perform one-time setup tasks
echo [SETUP] Applying configuration v%FlagVersion%...

:: Your setup logic here...
echo Setting up environment...

:: Mark as complete with the version number
reg add "%RegKey%" /v "%FlagName%" /t REG_SZ /d "%FlagVersion%" /f >nul 2>&1

if %errorlevel% equ 0 (
echo [SETUP] Configuration applied and flagged.
) else (
echo [ERROR] Could not write registry flag. Setup may run again.
)

:Finish
endlocal
exit /b 0

Method 3: The "Self-Destructing" Script

If the script is truly only needed once (like a post-install cleanup script), the most efficient approach is to have the script delete itself when it finishes.

@echo off
echo [CLEANUP] Running post-installation cleanup...

:: Perform one-time tasks
echo Removing temporary installation files...
if exist "C:\Setup\*.tmp" del /q "C:\Setup\*.tmp"

echo [VERIFY] Checking cleanup results...
dir "C:\Setup\*.tmp" >nul 2>&1
if %errorlevel% neq 0 (
echo [SUCCESS] All temporary files removed.
) else (
echo [WARNING] Some files could not be removed.
)

echo.
echo [INFO] This script will now delete itself.
echo Press any key to confirm, or close the window to cancel.
pause >nul

:: The self-deletion trick:
:: Start a background cmd that waits briefly, then deletes this script
start "" /b cmd /c "timeout /t 2 /nobreak >nul & del "%~f0""
exit /b

How to Avoid Common Errors

Wrong Way: Hardcoding a sentinel in C:\

Modern versions of Windows will block a Batch script from creating a file in C:\ unless it is running as an Administrator.

Correct Way: Use user-specific folders like %appdata% or %localappdata% which never require special permissions.

Problem: Incomplete Setup

If your script crashes halfway through the setup, the sentinel file might not get created, which is the correct behavior: the setup will retry on the next launch. However, if your script creates the sentinel before the setup tasks, a crash would leave the system in a half-configured state with no retry.

Best Practice: Only create the sentinel file as the absolute last step of your setup block, and only after verifying that all tasks succeeded (as shown in Method 1).

Problem: Version upgrades

If you update your setup tasks (v2 adds new folders, v3 changes registry keys), the existing sentinel file from v1 will prevent the new setup from running.

Best Practice: Include a version identifier in your sentinel filename or registry value. When the version changes, the old sentinel no longer matches and the setup runs again (as shown in Method 2).

Best Practices and Rules

1. Re-Run Capability

Always include a /reset parameter in your script so that administrators can manually trigger the setup again if needed (as demonstrated in Methods 1 and 2).

2. User vs. Machine

  • If the task is for the User (like setting a background image), put the sentinel in %localappdata% or use HKCU in the registry.
  • If the task is for the Machine (like installing a driver), put it in %ProgramData% or use HKLM in the registry, and run as Admin.

3. Clear Labeling

Give your sentinel files clear names that include the application name and version. setup.done is too vague. Use myapp_setup_v1.done.

Conclusions

Implementing "First-Run Logic" in Batch script is a smart way to manage deployments and system configurations. Whether you use a simple sentinel file or a registry entry, you ensure that your automation is efficient and non-intrusive. By following the "Fail-Safe" principle and only marking the task as "Done" after a successful exit, you create reliable tools that make Windows management effortless.