Windows - Portable Install & Update via batch file

First, thanks to @Royi for sharing the elements of the script which setup the required directories and environment variables to make this work in a Portable manner. I’ve expanded upon his template for those who want to roll their own portable install (and be able to update it).

The Windows batch file I’ve created does the following:

  • Checks for the presence of the Obsidian-x.y.z.exe installer within the same directory as the batch file
  • If the installer exists, extract the app-64.7z file from the installer (if present) and delete the installer, then extract the contents of the app-64.7z file to .\Obsidian\ and delete the app-64.7z file
  • If the installer is not present, echo in the command window that no Installer was found
  • Check for the presence of the .\Obsidian\ subdirectory
  • If present, create subdirectories for user profile information, set environment variables for user profile information, and start Obsidian
  • If not present, echo with pause that Obsidian is not installed and to put the installer file in this directory

Requirements to make this batch file work:

  • Create a root directory in which to put this batch file
  • Copy 7z.exe. 7z.dll, 7-zip.dll, 7-zip32.dll, License.txt to the newly created directory from a copy of 7-Zip
  • Download the latest Obsidian installer to the directory
  • Create a new batch file containing the following code:
@echo off
%~d0
cd %~dp0

:: Installing Obsidian from Obsidian-VersionNumber.exe
IF EXIST ".\Obsidian-*.exe" (
	FOR /F "TOKENS=*" %%F IN ('DIR /B "Obsidian-*.exe"') DO 7z e "%%~fF" -r app-64.7z
	DEL Obsidian-*.exe /Q
	7z x -aoa -o".\Obsidian\" app-64.7z
	DEL app-64.7z /Q
) ELSE (
	echo Obsidian installer not found.
	echo -------------------------------
)

IF EXIST "Obsidian" (
	:: Creating Folders
	REM if not exist "%~dp0User\AppData" mkdir "%~dp0User\AppData"
	REM if not exist "%~dp0User\AppData\Local" mkdir "%~dp0User\AppData\Local"
	REM if not exist "%~dp0User\AppData\Local\Temp" mkdir "%~dp0User\AppData\Local\Temp"
	if not exist "%~dp0User\AppData\Roaming" mkdir "%~dp0User\AppData\Roaming"
	if not exist "%~dp0User\Desktop" mkdir "%~dp0User\Desktop"
	if not exist "%~dp0User\Documents" mkdir "%~dp0User\Documents"
	REM if not exist "%~dp0User\ProgramData" mkdir "%~dp0User\ProgramData"
	REM if not exist "%~dp0User\Public" mkdir "%~dp0User\Public"

	:: Setting Env Variables
	set HOMEPATH=%~dp0User
	set USERPROFILE=%~dp0User
	set APPDATA=%~dp0User\AppData
	REM set LOCALAPPDATA=%~dp0User\AppData\Local
	set ALLUSERSPROFILE=%~dp0User\ProgramData\Roaming
	set ALLUSERSAPPDATA=%~dp0User\AppData
	REM set ProgramData=%~dp0User\ProgramData
	REM set Public=%~dp0User\Public
	REM set TEMP=%~dp0User\AppData\Local\Temp
	REM set TMP=%~dp0User\AppData\Local\Temp

	:: if not exist "%dp0User\Documents\Obsidian" goto message
	goto message

	:message
	echo PORTABLE Obsidian
	echo -------------------------------
	goto start

	:start
	start .\Obsidian\Obsidian.exe
	goto end
) ELSE (
	echo Obsidian not installed
	echo Please put Obsidian-x.y.z.exe file in this directory
	pause
)

:end
exit

  • Run the batch file (You will need to launch Obsidian with this batch file each time)

Provided Obsidian don’t make changes to their installer filename structure, or the structure of the contents of the installer, this batch file is version agnostic and will appropriately replace files when run with an updated installer in the root directory prior to launching the program.

1 Like

Wow, I’m really digging the Batch File approach. Having to run the Batch File every time is only a very minor inconvenience for most users I would assume. The only caveat I have however is: The Folders you specified, you still require Obsidian to copy / install some Files on the PC it’s running, locally, right? I’m assuming that what I’m about to say is self-evident for most people but: If you were to specify a Non-”%~dp0User” Folder, that nothing would work afterwards? I’m assuming the “dp0User” Folder cannot be anything other than the user Folder that is created on the C Drive.

The goal I’m trying to reach is having a fully Portable installation (or “Standalone” installation?). Where Obsidian is fully contained on a Flash Drive. I read somewhere that “Portable” does not negate the necessity of copying some config files on the PC’s local Hard Drive, but that “Standalone” means everything stays in one location, without requiring copying / installing files locally (I’m not sure what I’m saying is 100% accurate).

There is nothing “installed”, per se - the batch file extracts the files out of the installer and places them in the directory structure it creates.

The folder you create doesn’t necessarily need to be on the local drive - “%~dp0User” translates to “.\ThisDirectory\User\.”

Here’s an example of the directory structure where “ThisDirectory” is “ObsidianPortable”, which is where the batch file lives:

For my install, this lives on a second drive within a subfolder, completely outside of my user directory.

This should work to accomplish your intended goal.

Thank you very much @Malthael_82. Now that several months have passed, is the self-created portable app functioning well? Can it also be applied to the latest versions?

… Dude

Very sleek solution. Great job! Thanks for sharing!!!

New version for everybody - this time instead of having to manually download the installer to update or perform a clean deployment, we automatically check for a new version and download if a newer version exists.

@echo off
%~d0
cd %~dp0

SET /a installed=0
IF EXIST "Obsidian" (
	SET /a installed=1
)
echo Obsidian installed: %installed%

SET /a installer=0

SET /a vermismatch=0

:: --- CONFIGURATION ---
set "repo=obsidianmd/obsidian-releases"
:: ---------------------

:: Fetch latest release data and extract the tag_name
FOR /F "usebackq tokens=*" %%v IN (`pwsh -NoProfile -Command "(Invoke-RestMethod -Uri 'https://api.github.com/repos/obsidianmd/obsidian-releases/releases/latest').tag_name"`) DO ( SET "version=%%v" )

:: Clean up the version string (remove leading "v")
::SET "version=%version:"=%"
SET "version=%version: =%"
SET "version=%version:~1%"

ECHO New Version: %version%
	
IF %installed% EQU 1 (
	FOR /F "usebackq tokens=*" %%i IN (`pwsh -NoProfile -Command "(Get-Item '.\Obsidian\Obsidian.exe').VersionInfo.ProductVersion"`) DO ( SET "installedver=%%i" )
)

IF NOT DEFINED installedver (
	SET "installedver=not"
) ELSE (
	:: Clean up the version string (remove trailing ".0")
	IF "%installedver:~-2%" == ".0" (
		SET installedver=%installedver:~0,-2%
	)
)

SET "installedver=%installedver: =%"

ECHO Installed Version: %installedver%
	
IF "%version%" == "%installedver%" (
	ECHO Installed version same as latest available.
) ELSE (
	SET /a vermismatch=1
)

:: Installing Obsidian from Obsidian-VersionNumber.exe
IF %vermismatch% EQU 1 (
	FOR /F "usebackq tokens=*" %%u IN (`pwsh -NoProfile -Command "(Invoke-RestMethod -Uri 'https://api.github.com/repos/obsidianmd/obsidian-releases/releases/latest').assets | Where-Object { $_.name -like '*Obsidian*.exe' } | Select-Object -ExpandProperty browser_download_url"`) DO ( SET "download_url=%%u" )
)

IF NOT DEFINED download_url (
	ECHO Download path not found
) ELSE (
	ECHO Downloading from: %download_url%
	curl -L -O %download_url%
)

IF EXIST ".\Obsidian-*.exe" (
	SET /a installer=1
	
	ECHO Obsidian installer present: %installer%
	
	FOR /F "TOKENS=*" %%F IN ('DIR /B "Obsidian-*.exe"') DO 7z e "%%~fF" -r app-64.7z
	DEL Obsidian-*.exe /Q
	7z x -aoa -o".\Obsidian\" app-64.7z
	DEL app-64.7z /Q
) ELSE (
	IF %installed% EQU 0 (
		ECHO Obsidian installer not found.
		ECHO Obsidian not installed.
		ECHO Please try again, or manually download the installer and place it in this directory.
		PAUSE
		EXIT
	)
)

IF EXIST "Obsidian" (
	:: Creating Folders
	IF NOT EXIST "%~dp0User" MKDIR "%~dp0User"
	IF NOT EXIST "%~dp0User\AppData" MKDIR "%~dp0User\AppData"
	REM IF NOT EXIST "%~dp0User\AppData\Local" MKDIR "%~dp0User\AppData\Local"
	REM IF NOT EXIST "%~dp0User\AppData\Local\Temp" MKDIR "%~dp0User\AppData\Local\Temp"
	IF NOT EXIST "%~dp0User\AppData\Roaming" MKDIR "%~dp0User\AppData\Roaming"
	IF NOT EXIST "%~dp0User\Desktop" MKDIR "%~dp0User\Desktop"
	IF NOT EXIST "%~dp0User\Documents" MKDIR "%~dp0User\Documents"
	REM IF NOT EXIST "%~dp0User\ProgramData" MKDIR "%~dp0User\ProgramData"
	REM IF NOT EXIST "%~dp0User\Public" MKDIR "%~dp0User\Public"

	:: Setting Env Variables
	SET HOMEPATH=%~dp0User
	SET USERPROFILE=%~dp0User
	SET APPDATA=%~dp0User\AppData
	REM SET LOCALAPPDATA=%~dp0User\AppData\Local
	SET ALLUSERSPROFILE=%~dp0User\ProgramData\Roaming
	SET ALLUSERSAPPDATA=%~dp0User\AppData
	REM SET ProgramData=%~dp0User\ProgramData
	REM SET Public=%~dp0User\Public
	REM SET TEMP=%~dp0User\AppData\Local\Temp
	REM SET TMP=%~dp0User\AppData\Local\Temp

	:: IF NOT EXIST "%dp0User\Documents\Obsidian" GOTO message
	GOTO :message

	:message
	ECHO PORTABLE Obsidian
	ECHO -------------------------------
	GOTO :start

	:start
	START .\Obsidian\Obsidian.exe
	:: pause
	GOTO :end
) ELSE (
	ECHO Obsidian not installed
	ECHO Please put Obsidian-x.y.z.exe file in this directory
	PAUSE
)

:end
EXIT

Hi, I used the @Malthael_82 posts on this thread and asked AI to generate a step by step instructions.
If something is wrong, please correct it by commenting.


What You’ll Need

  • A Windows PC with PowerShell installed (comes with Windows 10/11)

  • 7-Zip installed on your system

  • An internet connection (for the auto-download script)


Step 1 — Create Your Portable Folder

Create a new folder anywhere you want Obsidian to live. It can be on your local drive, an external drive, or a USB stick. For this guide we’ll call it:

ObsidianPortable\

This folder is self-contained — everything Obsidian needs will live inside it.


Step 2 — Copy 7-Zip Files Into the Folder

Locate your 7-Zip installation (usually C:\Program Files\7-Zip\) and copy these files directly into your ObsidianPortable\ folder:

  • 7z.exe

  • 7z.dll

  • 7-zip.dll

  • 7-zip32.dll

  • License.txt

These are required because the script uses 7-Zip to extract Obsidian from its installer.


Step 3 — Create the Batch File

Inside ObsidianPortable\, create a new text file and name it ObsidianPortable.bat (make sure the extension is .bat, not .txt).

Open it with Notepad and paste the following script — this is the April 30th automated version that checks for updates and downloads automatically:

@echo off
%~d0
cd %~dp0

SET /a installed=0
IF EXIST "Obsidian" (
	SET /a installed=1
)
echo Obsidian installed: %installed%

SET /a installer=0

SET /a vermismatch=0

:: --- CONFIGURATION ---
set "repo=obsidianmd/obsidian-releases"
:: ---------------------

:: Fetch latest release data and extract the tag_name
FOR /F "usebackq tokens=*" %%v IN (`pwsh -NoProfile -Command "(Invoke-RestMethod -Uri 'https://api.github.com/repos/obsidianmd/obsidian-releases/releases/latest').tag_name"`) DO ( SET "version=%%v" )

:: Clean up the version string (remove leading "v")
SET "version=%version: =%"
SET "version=%version:~1%"

ECHO New Version: %version%
	
IF %installed% EQU 1 (
	FOR /F "usebackq tokens=*" %%i IN (`pwsh -NoProfile -Command "(Get-Item '.\Obsidian\Obsidian.exe').VersionInfo.ProductVersion"`) DO ( SET "installedver=%%i" )
)

IF NOT DEFINED installedver (
	SET "installedver=not"
) ELSE (
	IF "%installedver:~-2%" == ".0" (
		SET installedver=%installedver:~0,-2%
	)
)

SET "installedver=%installedver: =%"

ECHO Installed Version: %installedver%
	
IF "%version%" == "%installedver%" (
	ECHO Installed version same as latest available.
) ELSE (
	SET /a vermismatch=1
)

:: Installing Obsidian from Obsidian-VersionNumber.exe
IF %vermismatch% EQU 1 (
	FOR /F "usebackq tokens=*" %%u IN (`pwsh -NoProfile -Command "(Invoke-RestMethod -Uri 'https://api.github.com/repos/obsidianmd/obsidian-releases/releases/latest').assets | Where-Object { $_.name -like '*Obsidian*.exe' } | Select-Object -ExpandProperty browser_download_url"`) DO ( SET "download_url=%%u" )
)

IF NOT DEFINED download_url (
	ECHO Download path not found
) ELSE (
	ECHO Downloading from: %download_url%
	curl -L -O %download_url%
)

IF EXIST ".\Obsidian-*.exe" (
	SET /a installer=1
	
	ECHO Obsidian installer present: %installer%
	
	FOR /F "TOKENS=*" %%F IN ('DIR /B "Obsidian-*.exe"') DO 7z e "%%~fF" -r app-64.7z
	DEL Obsidian-*.exe /Q
	7z x -aoa -o".\Obsidian\" app-64.7z
	DEL app-64.7z /Q
) ELSE (
	IF %installed% EQU 0 (
		ECHO Obsidian installer not found.
		ECHO Obsidian not installed.
		ECHO Please try again, or manually download the installer and place it in this directory.
		PAUSE
		EXIT
	)
)

IF EXIST "Obsidian" (
	:: Creating Folders
	IF NOT EXIST "%~dp0User" MKDIR "%~dp0User"
	IF NOT EXIST "%~dp0User\AppData" MKDIR "%~dp0User\AppData"
	IF NOT EXIST "%~dp0User\AppData\Roaming" MKDIR "%~dp0User\AppData\Roaming"
	IF NOT EXIST "%~dp0User\Desktop" MKDIR "%~dp0User\Desktop"
	IF NOT EXIST "%~dp0User\Documents" MKDIR "%~dp0User\Documents"

	:: Setting Env Variables
	SET HOMEPATH=%~dp0User
	SET USERPROFILE=%~dp0User
	SET APPDATA=%~dp0User\AppData
	SET ALLUSERSPROFILE=%~dp0User\ProgramData\Roaming
	SET ALLUSERSAPPDATA=%~dp0User\AppData

	GOTO :message

	:message
	ECHO PORTABLE Obsidian
	ECHO -------------------------------
	GOTO :start

	:start
	START .\Obsidian\Obsidian.exe
	GOTO :end
) ELSE (
	ECHO Obsidian not installed
	ECHO Please put Obsidian-x.y.z.exe file in this directory
	PAUSE
)

:end
EXIT

Save the file.


Step 4 — Run the Batch File

Double-click ObsidianPortable.bat.

The script will automatically:

  1. Check the latest Obsidian version on GitHub

  2. Compare it with what’s currently installed (if anything)

  3. Download the installer if needed

  4. Extract Obsidian into the Obsidian\ subfolder

  5. Create the User\ folder structure for your profile data

  6. Set environment variables so Obsidian thinks the portable folder is its home

  7. Launch Obsidian


Step 5 — Understand the Resulting Folder Structure

After the first run, your ObsidianPortable\ folder will look like this:

ObsidianPortable\
├── ObsidianPortable.bat       ← Your launcher (run this every time)
├── 7z.exe / 7z.dll / etc.    ← 7-Zip files
├── Obsidian\                  ← Obsidian app files (extracted)
│   └── Obsidian.exe
└── User\
    ├── AppData\
    │   └── Roaming\           ← Settings, plugins, themes stored here
    ├── Desktop\
    └── Documents\
        └── Obsidian Vaults\   ← Your vaults live here

Everything — settings, plugins, vaults — stays inside ObsidianPortable\. Nothing touches your Windows user profile.


Step 6 — Launching Obsidian Going Forward

Always launch Obsidian by running ObsidianPortable.bat, never by clicking Obsidian.exe directly. The batch file is what sets the correct environment variables to keep everything portable and self-contained.


Updating Obsidian

Simply run ObsidianPortable.bat again. It will automatically detect if a newer version is available, download it, extract it over the existing installation, and launch the updated version. No manual steps needed.


Tips

  • Moving to another PC or drive? Just copy the entire ObsidianPortable\ folder. Run the .bat file and everything works as-is.

  • No admin rights needed — since nothing is “installed” in the traditional sense, the script just extracts files.

  • Vaults can be placed anywhere inside User\Documents\ or pointed to any external folder when you set them up in Obsidian.

So this is one using Windows 10

my system uses powershell instead of pwsh (which is PowerShell 7+).

So, Replace pwsh with powershell in the batch file

Open ObsidianPortable.bat in Notepad and do Find & Replace (Ctrl+H):

  • Find: pwsh

  • Replace with: powershell

Using powershell instead of pwsh works on Windows 11. If you are behind a proxy, you can add the configuration at the beginning of the script.

@echo off
%~d0
cd %~dp0

set HTTP_PROXY=socks5://127.0.0.1:1080
set HTTPS_PROXY=socks5://127.0.0.1:1080

...