Windows utility for updating multiple Kodi clients

I wanted a batch script that would allow me to update and clean more than one Kodi box at the same time. I also wanted a quick and easy method to see which of my Kodi boxes were showing up on the network and if they were updated. I manage my files manually in Windows (as a matter of preference) and have more than one MySQL database. Up till now my process of adding content ended with bringing up multiple web interfaces and using those kick off a library update. Now I can just open a single batch file that is already setup to perform the tasks I want. I designed the script to be very flexible and easy to configure.

I’m not sure how many people other than myself are in need of such a thing but if you have more than one Kodi box and manage your files in Windows, this script may save you some time and effort. To use it you only need to copy the text in full and paste it into a text file that is named as <something>.bat (If your hiding file extensions you may need to unhide those long enough to change the file extension). You will need to edit some information in the beginning of the file to add in the IP addresses of your Kodi boxes, which you want to do library updates on, as well as how many total clients and if you want the clean library dialog box to show.

@ECHO off
SETLOCAL enabledelayedexpansion
:: Created by DarwinDesign
:: The "num.clients=<x>" value should be set at the largest "kodi.<x>.ip=" number your using
:: The "clean.dialogs" set whether a library clean displays the progress dialog box in the GUI. This can only be "true" or "false".
:: Any unused kodi.<x>.ip= varibles must have a hard return after "=" or just comment out or remove the line.
:: If something doesn't look right check to make sure there is not a trailing space.
:: A setting of "yes" for the update variables is the only trigger. If not setting it to yes you don't need that line.
::
SET num.clients=5
SET clean.dialogs=false
::
:: John RPi
SET kodi.1.ip=http://osmc:osmc@192.168.254.224:80
SET Kodi.1.video.update=yes
SET Kodi.1.audio.update=yes
:: Cave Vero
SET kodi.2.ip=http://osmc:osmc@192.168.254.190:80
SET Kodi.2.video.update=no
SET Kodi.2.audio.update=no
:: Living Room
SET kodi.3.ip=http://osmc:osmc@192.168.254.221:80
SET Kodi.3.video.update=yes
SET Kodi.3.audio.update=no
:: Donna
SET kodi.4.ip=http://osmc:osmc@192.168.254.226:80
:: June
SET kodi.5.ip=http://osmc:osmc@192.168.254.222:80
::
:: All "SET kodi.<x>.ip=" linues need to be above this line.
::
:: Sets variables for the start of the json requests.
FOR /L %%I IN (1,1,%num.clients%) DO (
	IF NOT [!kodi.%%I.ip!] == [] (
		SET "kodi.%%I.curl=curl -s --connect-timeout 2 -X POST -H "content-type:application/json" !kodi.%%I.ip!/jsonrpc -d"
	)
)
:: Sets client names. Empty ip's are set to "null" then ask Kodi for names and bad responces set ip address as the name.
FOR /L %%I IN (1,1,%num.clients%) DO (
	IF NOT [!kodi.%%I.ip!] == [] (
		SET "k=null"
		FOR /f "tokens=* usebackq" %%I IN (`!kodi.%%I.curl!  "{""jsonrpc"":""2.0"",""method"":""Settings.GetSettingValue"",""params"":{""setting"":""services.devicename""},""id"":1}"`) DO SET "k=%%I"
		IF "!k!" == "null" (
		FOR /F "tokens=4 delims=@:" %%c IN ("!kodi.%%I.ip!") DO SET "kodi.%%I.name.pad=%%c .............."
		) ELSE (
			FOR /F "delims=" %%x IN ('echo !k!') DO (
				SET V=%%x
				CALL SET V=%%V:"=µ%%
				FOR /F "tokens=7 delims=:,{µ" %%a IN ('CALL ECHO.%%V%%') DO SET "kodi.%%I.name.pad=%%a .............."
			)
		)
	) ELSE (
		SET "kodi.%%I.name.pad=null"
	)
)
SET "k="
:MENU
CLS
ECHO _______________________________________________________
ECHO _____ Kodi Utilities _____
ECHO.
ECHO   1 - Update Video Libraries
ECHO   2 - Update Music Libraries
ECHO   3 - Client Information
ECHO   V - Clean Video Libraries
ECHO   M - Clean Music Libraries
ECHO   9 - EXIT
ECHO _______________________________________________________
CHOICE /N /C:123456VM9 /M " _____ Make A Selection _____"
IF "%errorlevel%"=="1" GOTO UPDATEVIDEO
IF "%errorlevel%"=="2" GOTO UPDATEMUSIC
IF "%errorlevel%"=="3" GOTO VERSION
IF "%errorlevel%"=="4" GOTO MENU
IF "%errorlevel%"=="5" GOTO MENU
IF "%errorlevel%"=="6" GOTO MENU
IF "%errorlevel%"=="7" GOTO CLEANVIDEO
IF "%errorlevel%"=="8" GOTO CLEANMUSIC
IF "%errorlevel%"=="9" GOTO EOF
GOTO MENU
:UPDATEVIDEO
SET title=Update Video Libraries
SET json="{""jsonrpc"":""2.0"",""id"":1,""method"":""VideoLibrary.Scan""}"
SET json.responce=OK
GOTO VLIBRARYSTART
:UPDATEMUSIC
SET title=Update Music Libraries
SET json="{""jsonrpc"":""2.0"",""id"":1,""method"":""AudioLibrary.Scan""}"
SET json.responce=OK
GOTO ALIBRARYSTART
:CLEANVIDEO
SET title=Clean Video Libraries
SET json="{""jsonrpc"":""2.0"",""id"":1,""method"":""XBMC.GetInfoBooleans"",""params"":{""booleans"":[""library.isscanning""]}}"
SET json.responce=true
FOR /L %%I IN (1,1,%num.clients%) DO (
	IF "!Kodi.%%I.video.update!"=="yes" IF NOT "!kodi.%%I.name.pad%!" == "null" (
		!kodi.%%I.curl! "{""jsonrpc"":""2.0"",""id"":1,""method"":""VideoLibrary.Clean"",""params"":{""showdialogs"":%clean.dialogs%}}"  --max-time 0.1 >nul
	)
)
GOTO VLIBRARYSTART
:CLEANMUSIC
SET title=Clean Music Libraries
SET json="{""jsonrpc"":""2.0"",""id"":1,""method"":""XBMC.GetInfoBooleans"",""params"":{""booleans"":[""library.isscanning""]}}"
SET json.responce=true
FOR /L %%I IN (1,1,%num.clients%) DO (
	IF "!Kodi.%%I.audio.update!"=="yes" IF NOT "!kodi.%%I.name.pad%!" == "null" (
		!kodi.%%I.curl! "{""jsonrpc"":""2.0"",""id"":1,""method"":""AudioLibrary.Clean"",""params"":{""showdialogs"":%clean.dialogs%}}"  --max-time 0.1 >nul
	)
)
GOTO ALIBRARYSTART
:VLIBRARYSTART
CLS
ECHO _______________________________________________________
ECHO _____ %title% _____
ECHO.
FOR /L %%I IN (1,1,%num.clients%) DO (
	IF "!Kodi.%%I.video.update!"=="yes" (
		SET "k="
		FOR /f "tokens=* usebackq" %%J IN (`!kodi.%%I.curl! %json%`) DO SET k=%%J
		ECHO !k! | findstr /c:"%json.responce%" >nul
		IF !errorlevel!==1 (
			SET status.%%I=error
			SET finished.%%I=1
			ECHO   !kodi.%%I.name.pad:~,15! ^(No response^)
		) ELSE (
			SET status.%%I=running
			SET finished.%%I=0
			ECHO   !kodi.%%I.name.pad:~,15! ^(started^)
		)
	) ELSE (
		SET finished.%%I=1
	)
)
ECHO _______________________________________________________
TIMEOUT /t 5 >nul
GOTO UPDATESTATUS
:ALIBRARYSTART
CLS
ECHO _______________________________________________________
ECHO _____ %title% _____
ECHO.
FOR /L %%I IN (1,1,%num.clients%) DO (
	IF "!Kodi.%%I.audio.update!"=="yes" (
		SET "k="
		FOR /f "tokens=* usebackq" %%J IN (`!kodi.%%I.curl! %json%`) DO SET k=%%J
		ECHO !k! | findstr /c:"%json.responce%" >nul
		IF !errorlevel!==1 (
			SET status.%%I=error
			SET finished.%%I=1
			ECHO   !kodi.%%I.name.pad:~,15! ^(No response^)
		) ELSE (
			SET status.%%I=running
			SET finished.%%I=0
			ECHO   !kodi.%%I.name.pad:~,15! ^(started^)
		)
	) ELSE (
		SET finished.%%I=1
	)
)
ECHO _______________________________________________________
TIMEOUT /t 5 >nul
GOTO UPDATESTATUS
:UPDATESTATUS
CLS
ECHO _______________________________________________________
ECHO _____ %title% _____
ECHO.
FOR /L %%I IN (1,1,%num.clients%) DO (
	IF "!status.%%I!"=="running" (
		SET "k="
		FOR /f "tokens=* usebackq" %%J IN (`!kodi.%%I.curl! "{""jsonrpc"":""2.0"",""id"":1,""method"":""XBMC.GetInfoBooleans"",""params"":{""booleans"":[""library.isscanning""]}}"`) DO SET k=%%J
		ECHO !k! | findstr /c:"true" >nul
		IF !errorlevel!==0 (
			ECHO   !kodi.%%I.name.pad:~,15! ^(!status.%%I!^)
		) ELSE (
			SET finished.%%I=1
			SET status.%%I=complete
			ECHO   !kodi.%%I.name.pad:~,15! ^(!status.%%I!^)
		)
	)
)
SET "finished=0"
FOR /L %%I IN (1,1,%num.clients%) DO SET /a "finished=!finished.%%I! +!finished!"
IF "!finished!"=="%num.clients%" (GOTO UPDATEDONE)
ECHO _______________________________________________________
ECHO _____ Press X to stop checking status _____
CHOICE /c xr /n /t 5 /d r
if %errorlevel%==1 GOTO CANCELED
if %errorlevel%==2 GOTO UPDATESTATUS
:CANCELED
FOR /L %%I IN (1,1,%num.clients%) DO (
	IF "!status.%%I!"=="running" (
		SET status.%%I=cancel
	)
)
GOTO UPDATEDONE
:UPDATEDONE
CLS
ECHO _______________________________________________________
ECHO _____ %title% _____
ECHO.
FOR /L %%I IN (1,1,%num.clients%) DO (
	IF "!status.%%I!"=="complete" (ECHO   !kodi.%%I.name.pad:~,18! ^(succeeded^))
	IF "!status.%%I!"=="cancel" (ECHO   !kodi.%%I.name.pad:~,18! ^(Schrodingers cat^))
	IF "!status.%%I!"=="error" (ECHO   !kodi.%%I.name.pad:~,18! ^(failed^))
	SET "finished=" 
	SET "finished.%%I=" 
	SET "status.%%I=" 
)
ECHO _______________________________________________________
ECHO _____ Press the any key to continue _____
PAUSE >nul
GOTO MENU
:VERSION
CLS
ECHO _______________________________________________________
ECHO _____ Kodi Version Info _____
ECHO.
FOR /L %%I IN (1,1,%num.clients%) DO (
	IF NOT "!kodi.%%I.name.pad%!" == "null" (
		SETLOCAL enabledelayedexpansion
		IF "!kodi.%%I.video.update%!" == "yes" (SET "u=*") ELSE (SET "u= ")
		IF "!kodi.%%I.audio.update%!" == "yes" (SET "t=*") ELSE (SET "t= ")
		FOR /f "tokens=* usebackq" %%J IN (`!kodi.%%I.curl!  "{""jsonrpc"":""2.0"",""method"":""Application.GetProperties"",""params"":{""properties"":[""version""]},""id"":1}"`) DO SET k=%%J
		ECHO !k! | findstr /c:"version" >nul
		IF !errorlevel!==1 (ECHO !u!!t! !kodi.%%I.name.pad:~,15! ^(No response^)
		) ELSE (
			FOR /F "delims=" %%x IN ('echo !k!') DO (
			SET V=%%x
			CALL SET V=%%V:"=µ%%
			FOR /F "tokens=8,10,12,14 delims=:,{µ" %%a IN ('CALL ECHO.%%V%%') DO (
				ECHO !u!!t! !kodi.%%I.name.pad:~,15! Kodi %%a.%%b Revision^:%%c ^(%%d^)
				)
			)
		)
		ENDLOCAL
	)
)
ECHO _______________________________________________________
ECHO _____ Press the any key to continue _____
PAUSE >nul
GOTO MENU
:EOF

3 Likes

Love your script but you have me curious … Why do you have more than one SQL server for you media… and also for video have you every tried Ember Media Manager. I have 3 PI’s setup myself one dedicated SQL and Web hosting for PHPmyadmin and Ampache. and 2 TV PI’s living and bedroom… Also run Webmin on all 3 for Maintenance, I’m Always trying to improve so I’m just curious

Thanks
James

Thanks. I have two databases, not two MySQL servers. Kodi doesn’t have any kind of a system where one can maintain more than one watched status in a single library. So on most of my Kodi boxes there is two profiles that are each set to to a different database name but pointing to the same server for the video, but both are pointing to the same music database. The upside to this is that when I’m on my profile I’m looking at what I’ve watched and am watching and ditto for the better half. In my in progress list I don’t have to have to see The Marvelous Mrs. Maisel and the other half doesn’t have to wade through all the sci-fi I’m watching. On any device I can just switch profiles to get to the other database. It works out pretty well but the downside is that they have to be updated separately. With this script I have it updating on two machines that are always set to each of the profiles which has been working out well so far.

I run a Plex server and purchased a lifetime pass. I don’t have much bad to say about it other than the interface is not to my preference. For my own use on my LAN I have a strong preference to Kodi. I have the Plex server for some others to access my library. It works great for that. You have easy setup, no messing around you just stick it on a phone or smart TV, and transcoding for when the connection is suboptimal. I know I can do PKC but that is too much mucking about. My MySQL server is also more reliable and never requires a reboot or bugs me about updates. I name my files good enough for Kodi to pick them up and Plex’s auto library update almost always picks it up the same so I don’t have to really manage that other than the occasional phone call with “dad did Plex go down again?” which is when Plex gets restarted.

EDIT: Sorry, realized after posting that you asked about Ember and not Emby. I have not. I use the old shareware version of FileBot to move and rename my files. I really like the program. The attitude of the dev and what he wants to purchase the no longer shareware version, not so much. I also use tiny media manager for some of my content. Mostly movies and old shows I will run through TMM so the artwork is the same everywhere. Currently airing shows I normally don’t bother. I haven’t gone looking at media managers in a while, I thought last I heard Ember had kind of died. If this isn’t the case and there is some compelling reason it is better than TMM I’d be interested in checking it out.

Ember has sorta died and I have tried TMM but I like the interface of Ember much better and it’s move commands… I use it for Video and Tv Shows and I use Music bee to deal with music and sometimes Media monkey depending on what I’m trying to do… I’ve actually got 3 Data bases The 2 default kodi ones and one I have a Web program called Ampache compile for my Audio collection That I host back out to the internet and stream from while at work… kind of like Pandora with no adds or costs. It will also do the videos but I haven’t a need to stream them outside of home.

As for the Profile/DB trick you use … Pretty cool… I don’t have a need or worry for that but I do kinda get alot of questions at work and people requesting access to my stream… It has logins and the like plus you can put it in a democratic mode and users can pick music for a group stream of create their own select one.

Thanks for the in site of your setup…

JC

When I first looked at TMM it seemed to be a bit over complicated and too much of a learning curve. Once I actually spent the time to set it up and actually use it I found it to be less complicated than I thought and I ended up being pretty happy with how it worked. It can move and rename files as well. I just don’t normally use that feature as you can’t really get any faster or easier (initial setup excepted) than FileBot.

I run all my music through MusicBrainz Picard to add their tags that help Kodi to scan everything correctly. It has an exclusion list in the preferences so you can keep it from trying to fix specific tags.

I think you have to have a Plex Pass to use it but there is an app call Plexamp that is just the Music part of a Plex Library. It not only lets you stream your music remotely but you can also cache selected tracks and playlists as well so you have access offline as well. I’ve only played with it a little but it worked quite well.