NOT NOW | DON'T ASK AGAIN

Claim Your Free Report Before You Forget...

Weekly tech delivered straight to your inbox. Sign up and receive our free report: 20 Tips For Becoming a Technology Power User.


Privacy Policy | More Information

PCMech.com helps normal people get their geek on. We talk about computers, technology, the Internet, social media - anything that makes a geek feel warm and fuzzy inside.

home | about | newsletters |forums | contact | advertising | membership

Helping Normal People Get Their Geek On And Live The Digital Lifestyle

Windows Batch Script To Backup Data

Posted May 12, 2008 by Jason Faulkner  

As I have briefly mentioned in my previous posts, for my day job I am the primary technical resource for a small business and as a “side gig” I manage web servers for hosting companies. One of the great benefits to this is I have become quite adept at developing command line scripts, or “batch” scripts.

One of the most common, and well suited, applications for a command line script is data backup. Command line scripts can be automated to run at any time without any human interaction and are only limited by… well, nothing.

Why Command Line Scripts?

Having experience with both commercial and free backup programs, I always find command line scripts to be, by far, the most effective tool for the job. Here are a few reasons why:

  • Native Commands: What better way to backup data than by using the functions made available through the program which creates the data. Whether this is the operating system itself via a simple file copy command or a database command to produce a restorable binary file, the source program knows how best to back itself up.
  • Ultimate Control: Since a command line script follows a simple step-by-step procedure, you know exactly what is happening and can easily modify the behavior.
  • Fast: Since everything is a native command, nothing is subject to interpretation. Again, you are using commands provided by the program itself, so overhead is kept to a minimum.
  • Powerful: I have yet to see a backup task which cannot be accomplished through a command line script… and I have done some funky stuff. Albeit, some research and “trial and error” may be required, unless you need something incredibly unique, typically the built in functions and features of the scripting language you are using is more than sufficient.
  • Free and Flexible: Obviously, a command line script does not cost anything (outside the time to develop it), so the emphasis I want to make is command line scripts can be copied to and implemented on other systems and quickly adapted with little to no time or cost. Compare this to the cost of purchasing licenses for backup software on several servers and/or desktop machines.

A Quick Overview Of The Backup Batch Script

Since a lot of people do not have the need/time/desire to learn command line scripting, it is considered somewhat of a “black art”. So to demonstrate the power of the command line, I am providing a simple Windows batch script to backup your important data. This configurable and customizable script does not
require any knowledge (or willingness to learn) of the Windows batch scripting language.

What the backup script does:

  1. Creates full or daily incremental (see below for a definition) backups of files and folders you specify in a separate configuration text file (see below).
    • When a folder is provided, that folder and all sub-folders are backed up.
    • When a file is provided, just that file is backed up.
  2. Compresses (zips) the backed up files. After all files to be backed up are copied, they are compressed to save space. 7-Zip is required to be installed on your system for this to work.
  3. Dates the compressed file and moves it to a storage location. After the backup files are compressed, the resulting archive is given a file name according to the current date and then moved to a configured storage location, such as an external drive or network location.
  4. Cleans up after itself. After all tasks are completed, the batch script cleans up all the temporary files it created.

Requirements:

Windows 2000/XP/2003/Vista,
7-Zip (it’s free).

Configuration file:

The configuration file is simply a text file which contains files and folders to backup, entered one backup item per line. This file must be named “BackupConfig.txt” and be located in the same folder as the backup script. Here is an example of a BackupConfig.txt file (note, the first line is always ignored):

# Enter file and folder names, one per line.
C:\Documents and Settings\Jason Faulkner\Desktop C:\Documents and Settings\Jason Faulkner\My Documents\Important Files C:\Scripts\BackupScript.bat

The example above would backup the Windows user Jason Faulkner’s desktop (and all folders on the desktop), the folder called “Important Files” inside of My Documents (and all folders inside “Important Files”) and the file “BackupScript.bat” inside the C:\Scripts directory.

Types of backups:

  • Full backup: A complete copy of all files and folders (including sub-folders) are included in the backup.
  • Incremental backup: When a folder is provided, only files created or modified on the current date are
    backed up. When a file is provided, it is always backed up, regardless of when it was modified.

The Data Backup Windows Batch Script

I want to emphasize this script is very basic, as all it does is create backups by a utilizing a simple file copy. There are some configuration options you can set:

  • The backup storage location where the resulting compressed backup files are stored.
  • The day of the week the full backup is run (any other day would run an incremental backup).
  • Location of where 7-Zip is installed on your computer. The script is automatically set to look in the default location.

If you have any suggestions or feature requests, please comment below. I would really love to do a follow up article to this post which features an updated script based on reader input.

If you need instructions on how to “use” this script or set up a scheduled task, take a look at the links below the script source.

Without further ado, here it is:
Note: Since the quotes do no display correctly below (and as a result can mess up the script), I have included a plain text link below the script which you can use to get an accurate source to copy from.

@ECHO OFF

REM BackupScript
REM Version 1.01, Updated: 2008-05-21
REM By Jason Faulkner (articles[-at-]132solutions.com)

REM Performs full or incremental backups of folders and files configured by the user.

REM Usage—
REM   > BackupScript

SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

REM —Configuration Options—

REM Folder location where you want to store the resulting backup archive.
REM This folder must exist. Do not put a ‘\’ on the end, this will be added automatically.
REM You can enter a local path, an external drive letter (ex. F:) or a network location (ex. \\server\backups)
SET BackupStorage=C:\Backup

REM Which day of the week do you want to perform a full backup on?
REM Enter one of the following: Sun, Mon, Tue, Wed, Thu, Fri, Sat, *
REM Any day of the week other than the one specified below will run an incremental backup.
REM If you enter ‘*’, a full backup will be run every time.
SET FullBackupDay=*

REM Location where 7-Zip is installed on your computer.
REM The default is in a folder, ‘7-Zip’ in your Program Files directory.
SET InstallLocationOf7Zip=%ProgramFiles%\7-Zip

REM +———————————————————————–+
REM | Do not change anything below here unless you know what you are doing. |
REM +———————————————————————–+

REM Usage variables.
SET exe7Zip=%InstallLocationOf7Zip%\7z.exe
SET dirTempBackup=%TEMP%\backup
SET filBackupConfig=BackupConfig.txt

REM Validation.
IF NOT EXIST %filBackupConfig% (
  ECHO No configuration file found, missing: %filBackupConfig%
  GOTO End
)
IF NOT EXIST “%exe7Zip%” (
  ECHO 7-Zip is not installed in the location: %dir7Zip%
  ECHO Please update the directory where 7-Zip is installed.
  GOTO End
)

REM Backup variables.
FOR /f “tokens=1,2,3,4 delims=/ ” %%a IN (’date /t’) DO (
  SET DayOfWeek=%%a
  SET NowDate=%%d-%%b-%%c
  SET FileDate=%%b-%%c-%%d
)

IF {%FullBackupDay%}=={*} SET FullBackupDay=%DayOfWeek%
IF /i {%FullBackupDay%}=={%DayOfWeek%} (
  SET txtBackup=Full
  SET swXCopy=/e
) ELSE (
  SET txtBackup=Incremental
  SET swXCopy=/s /d:%FileDate%
)

ECHO Starting to copy files.
IF NOT EXIST “%dirTempBackup%” MKDIR “%dirTempBackup%”
FOR /f “skip=1 tokens=*” %%A IN (%filBackupConfig%) DO (
  SET Current=%%~A
  IF NOT EXIST “!Current!” (
    ECHO ERROR! Not found: !Current!
  ) ELSE (
    ECHO Copying: !Current!
    SET Destination=%dirTempBackup%\!Current:~0,1!%%~pnxA
    REM Determine if the entry is a file or directory.
    IF “%%~xA”==”" (
      REM Directory.
      XCOPY “!Current!” “!Destination!” /v /c /i /g /h /q /r /y %swXCopy%
    ) ELSE (
      REM File.
      COPY /v /y “!Current!” “!Destination!”
    )
  )
)
ECHO Done copying files.
ECHO.

SET BackupFileDestination=%BackupStorage%\Backup_%FileDate%_%txtBackup%.zip

REM If the backup file exists, remove it in favor of the new file.
IF EXIST “%BackupFileDestination%” DEL /f /q “%BackupFileDestination%”

ECHO Compressing backed up files. (New window)
REM Compress files using 7-Zip in a lower priority process.
START “Compressing Backup. DO NOT CLOSE” /belownormal /wait “%exe7Zip%” a -tzip -r -mx5 “%BackupFileDestination%” “%dirTempBackup%\”
ECHO Done compressing backed up files.
ECHO.

ECHO Cleaning up.
IF EXIST “%dirTempBackup%” RMDIR /s /q “%dirTempBackup%”
ECHO.

:End
ECHO Finished.
ECHO.

ENDLOCAL

Plain text source is available here: Jason Faulkner’s Backup Script

If you need help getting started with implementing this script, here are a couple of links to help you out:

This is the same script I use to backup my computer daily (with a couple of modifications of course), so I know it works very well. I hope you find it useful.

Enjoy.

Categories: Featured, Optimization

Fire Your Computer Guy!

A computer technician spills the beans and makes available the knowledge he has charged clients hundreds in service fees for. It is Computer Secrets Unleashed. Find Out More.

About the Author

Jason Faulkner is the man who brings you our daily tips. He is based in Atlanta, Georgia.

19 Comment(s)

  1. LVG said:
    5/13/2008 2:24 am

    I’ve always loved the power of scripting in DOS but only knew basic short functions. The higher level stuff can get quite complicated like an acutal application.

    Windows scripting replaced DOS batch stuff, but I’m not a programmer!

    [Reply]

    Jason Faulkner reply on May 13, 2008 11:39 am:

    Actually, batches have not been replaced by Windows Script.

    A Windows Script to do the same thing requires to you create objects and send events to the shell object (MUCH more complicated) whereas Batch Scripts are simply an “automated” command line your script is “dumped” to (with fairly limited control (if,for,etc.) structures).

    Yes, Windows Script can do a lot more complex stuff than Batch Scripts alone, but by no means is it a replacement. It just boils down to some jobs being more suited for one script versus the other.

    [Reply]

  2. John said:
    5/14/2008 9:55 pm

    I’m a 70 year old trying to catchup to all this modern IT stuff, I have an external hard drive and can’t find a simple backup system. I read all articles that you send me including the above and I wish there was a simple program working in the background that backed up everything. I have tried several commercial products but they try to do to much. I tried LINUX but APT’s p***** me off. Keep up the good work. John

    [Reply]

  3. Nimrod said:
    5/15/2008 5:34 am

    This thing is new to me but I think this is really interesting! Right now I’m learning to write macros in ms excel and a little about html and vbscript. I mean, I’m quite interested with stuffs like this. I’d like to learn more about this windows scripting. Can you help me out with this? Where can I find sources about it? ..perhaps some kind of tutorial on how to write it?

    thanks.

    [Reply]

    Jason Faulkner reply on May 17, 2008 3:25 pm:

    I learned all this through experience over the years, so I don’t really know where to point you outside of the help documentation (from the command prompt: ‘for /?’, ‘if /?’, etc.).

    Google is always your friend or perhaps a “For Dummies” style book would be a good starting place.

    [Reply]

  4. Leif said:
    5/15/2008 6:31 am

    Love it… The no mess no fuss option.
    One of the best dos scripts ive seen, i especially liked the 7 zip compressing, would never of thought of that.

    [Reply]

  5. John said:
    5/17/2008 9:44 pm

    REM > BackupScript
    Neat trick for last run timestamp. What were you going to do with it? Might be better located at end of script.

    SET NowDate=%%d-%%b-%%c
    SET FileDate=%%b-%%c-%%d
    US date format may need local tweaking.

    SET Current=%%~A
    IF NOT EXIST “!Current!” (
    Wow! never new you could substitute ! for % or is something less obvious happening here.

    SET swXCopy=/s /d:%FileDate%
    What about files that changed between last run (yesterday) and midnight this morning?

    REM Determine if the entry is a file or directory.
    IF “%%~xA”==”" (
    Fails if list not include directory entry like:
    C:\path\to\. or C:\path\to - dir /b/s/a:-d does not do this.

    John

    [Reply]

    Jason Faulkner reply on May 19, 2008 9:17 am:

    John, good questions:

    >>SET swXCopy=/s /d:%FileDate%
    >>What about files that changed between last run (yesterday) and midnight this morning?

    The batch file will only copy files modified on the current day, so you would need to have a scheduled task set to run at something like 11:59PM (the “FileDate” variable gets set to the current day) so all the files that day are picked up.

    >>REM Determine if the entry is a file or directory.
    >>IF “%%~xA”==”” (
    >>Fails if list not include directory entry like:
    >>C:\path\to\. or C:\path\to - dir /b/s/a:-d does not do this.

    The configuration file is supposed to include the full directory path or full file name. If you include a “relative” path it will not work… most systems operate like this anyway, so this requirement is not unique.

    [Reply]

  6. JDK said:
    5/20/2008 6:05 pm

    I have 7-Zip installed under the default folder(C:\Program Files\7-Zip). When I try to run it, I am getting the following message.

    “The system cannot find the path specified.
    7-Zip is not installed in the location: dir7Zip
    Please update the directory where 7-Zip is installed.
    Finished.”

    I have verified and reinstalled 7-Zip but no luck. Please let me know if I need to change anything in the script.

    Thanks,

    JDK

    [Reply]

    Jason Faulkner reply on May 21, 2008 2:00 pm:

    It looks like the “ProgramFiles” environment variable is not set on your machine (odd). Here is the fix:

    Replace this line:
    SET InstallLocationOf7Zip=%ProgramFiles%\7-Zip

    With this:
    SET InstallLocationOf7Zip=C:\Program Files\7-Zip

    Basically, we are just hard coding it… of course, this assumes C:\Program Files\7-Zip is indeed where 7-Zip is installed (which should be the case according to your comment).

    [Reply]

    Jase reply on July 13, 2008 10:52 pm:

    try changing “Program Files” to “Progra~1″ We are working with DOS afterall so the DOS file naming conventions apply, (ie 8.3 character names no spaces/reserved characters etc…)

    [Reply]

  7. JDK said:
    5/21/2008 8:57 pm

    Thanks Jason, Now,I have setup “Program Files” environment variable and I got the same output. I have also hard coded and I still don’t see 7-Zip.

    Here I have added an extra line echo %exe7Zip% to show you that, it reads the path correctly but it still fails. See below.

    REM Usage variables.
    SET exe7Zip=%InstallLocationOf7Zip%\7z.exe
    SET dirTempBackup=%TEMP%\backup
    SET filBackupConfig=BackupConfig.txt
    echo %exe7Zip%

    With this added in the script, here is my output.

    C:\Scripts>BackupScript.bat
    C:\Program Files\7-Zip\7z.exe
    The system cannot find the path specified.
    7-Zip is not installed in the location: C:\Program Files\7-Zip
    Please update the directory where 7-Zip is installed.
    Finished.

    Question:
    Why this line has double quotation and the other one doesn’t have it?
    IF NOT EXIST “%exe7Zip%”

    IF NOT EXIST %filBackupConfig%

    I removed the quotation and it still didn’t work.
    I hope that this not something to do with copy and paste from the site. Thanks again for your help.

    JDK

    [Reply]

  8. JDK said:
    5/21/2008 10:42 pm

    It is copy and paste. My bad luck! Now, I am stuck at the last stage. This is where it’s getting an error. Is it possible if you can have a link to the script so people can download it instead of copy and paste? If I am missing the link, please let me know.

    Here is the message.

    C:\Scripts>BackupScript.bat
    Starting to copy files.
    Copying: C:\Documents and Settings\jdk\My Documents\home1
    41 File(s) copied
    Done copying files.

    Compressing backed up files. (New window)
    The system cannot find the file a.
    Done compressing backed up files.

    Cleaning up.

    Finished.

    I am not sure if it’s still caused by copy&paste or this command is not getting executed correctly. I am sure the script is fine and it’s just my bad luck!
    “%exe7Zip%” a -tzip -r -mx5 “%BackupFileDestination%” “%dirTempBackup%\”

    The temp files are getting copied to C:\Documents and Settings\jdk\Local Settings\Temp\backup and then the error message window pops up and it displays the following message:
    “Windows cannot find ‘a’. Make sure you typed the name correctly and then try again. To search for a file, click the Start button, and then click Search”

    Once I click “OK”, then it removes the the above directory “backup”.

    Sorry for cluttering the message board. I just started learning scripting and I have a long way to go. Thanks again for your help.

    [Reply]

    Jason Faulkner reply on May 22, 2008 9:05 am:

    I think it is definitely the copy-paste. I have posted a plain text source link below the script in the article. Try copy and pasting from it.

    [Reply]

  9. JDK said:
    5/22/2008 6:18 pm

    I saved your .txt file to .bat and I still got the same error message “The system cannot find the file a.”.

    After going through more testing, I was able to run your script but I had to make a minor change. The line where it was giving an error is START “Compressing Backup. DO NOT CLOSE!”. It doesn’t like exclamation mark. Once I removed it, the script worked.

    Thanks for your help.

    Jdk

    [Reply]

  10. rld said:
    5/23/2008 12:03 pm

    I can get the script to work, but when I look at my backup zip it creates in the storage Backup folder, it’s not backing up anything and I have the file path’s to folders and directories I want to backup in the BackupConfig.txt file. What am I doing wrong there?
    This is a pretty cool script.

    [Reply]

  11. rld said:
    5/23/2008 12:18 pm

    Disregard previous post. Found out what I was doing wrong with typing my path’s in the config text file. Brain froze for a moment but it’s all good now. Thanks for the script Jason and your help with this too JD.

    [Reply]

  12. SamO said:
    5/24/2008 10:07 pm

    Two questions:

    1) Why 7-Zip? Why not just use the “Compact” command?

    2) I’m certainly no expert on batch files but the script seems overly complex. Why can’t use xcopy with the files you would like to copy. Then use compact to compress them to another destination and lastly delete the copies?

    Are there any books or more in depth references you could provide where people could learn more about this? Thanks for the article it is a good read and refreshing to see people interested in returning to the command line in such a GUI driven computing environment.

    [Reply]

    Jason Faulkner reply on May 26, 2008 12:49 pm:

    Samo,

    1. 7-Zip is much (much much) more robust and faster than compact. Additionally, it is the tool I prefer, so that is why I used it in the script. If you prefer to use compact instead, just modify the compression command.

    2. Xcopy performs erratically if you are only copying a single specific file. Copy performs predictably when you are only copying a single file, which is why I used both commands depending on the task needed.

    Again, feel free to modify the script however you see fit so it suits your needs.

    As for additional references, please read my comment above to ‘Nimrod’.

    [Reply]

  13. Kush said:
    6/4/2008 10:34 pm

    Hi Jason,

    Hi,

    I need help with xcopy. I have a script that copies user “My Documents” folder to a mapped drive. When I run the batch file while logged in, it backs up to the specified destination. But when I put the batch file with the logon script and when a user logs on, it copies the admin “My Document” folder not the user ” My Document” folder who is currently logged in.

    We have a VB script that runs when user logs in and that VB script then calls the batch file at last. It is a function in the VB script that calls the batch file.

    Here is the batch file that I have modified

    @echo off
    ATTRIB +A “%userprofile%\My Documents\*.*” /S
    xcopy “%userprofile%\My Documents\*.*” “Z:\%username%” /C/E/H/R/K/D/M/Y/I
    exit

    As I said the batch file works fine when logged on and executed. But it only copies the admin folder “My Document” when run in batch file. I have given full permission of the Z: drive to Everyone. Please help what I am doing wrong.

    [Reply]

    Jason Faulkner reply on June 10, 2008 11:31 pm:

    The variable %UserProfile% will resolve to the profile of the Windows user who launched the process.
    If you have a task set to run as the Administrator, the batch file will be launched as Administrator, hence the variable %UserProfile% will resolve to the Administrator’s profile.

    [Reply]

  14. Eric said:
    6/5/2008 2:43 am

    One problem when i run this bat.
    The files insides the folder is not copied to dirTempBackup and it prompts Invalid switch - /g

    Any idea ? Thanks.

    Starting to copy files.
    Copying: C:\AnalyseAgentData\Input\geam\_Default_LOT
    Invalid switch - /g
    Done copying files.

    Compressing backed up files. (New window)
    Done compressing backed up files.

    Cleaning up.

    Finished.

    [Reply]

    Jason Faulkner reply on June 10, 2008 11:26 pm:

    You can remove the “/g” switch from the XCOPY command. All it does is allow copying of encrypted files. Depending on your version of Windows, it may not be a valid option anyway.

    [Reply]

  15. lizaoreo said:
    6/10/2008 1:15 pm

    I’m trying to get this to work with IZARc’s command line interface rather than 7-Zip but keep running into trouble. Everything seems to work except the compression line which I’ve modified to read:

    START “Compressing Backup. DO NOT CLOSE!” /belownormal /wait “%exeIZArc%” -a -cx -r %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_Backup.zip “%BackupFileDestination%” $”%dirTempBackup%\”

    I think that’s how it should be, but it keeps coming back and saying “Cannot find -a”

    Any ideas?

    [Reply]

    Jason Faulkner reply on June 10, 2008 11:27 pm:

    One commenter above was getting that error and he fixed it by removing the ‘!’ after DO NOT CLOSE.

    [Reply]

    lizaoreo reply on June 12, 2008 11:54 am:

    Thanks, I saw that post, but it just didn’t click. That fixed my issue and if anyone’s interested in using this with IZArc, here’s the line for use. You’ll have to update the other references to 7-zip of course.

    REM Compress files using IZArc in a lower priority process.
    START “Compressing Backup. DO NOT CLOSE” /belownormal /wait “%exeIZArc%” -a -r -p -cx “%BackupFileDestination%” “%dirTempBackup%\”
    ECHO Done compressing backed up files.

    Thanks for your help and script Jason.

    [Reply]

  16. Will said:
    6/14/2008 11:31 am

    What about exclusions? e.g. .DLL files.

    [Reply]

    Jason Faulkner reply on June 14, 2008 7:32 pm:

    Just add this switch to the end of the XCOPY line:

    /exclude:.dll+.ocx

    This would exclude all DLL and OCX files from being copied to the backup.

    [Reply]

  17. Ikhlaq said:
    6/20/2008 4:43 am

    Is it possible for someone to help me on this;

    At work we are running a server on Windows 2003 Server R2. We run (everyday apart the weekends) a scheduled task to back up some important files, which are placed in a folder corresponding to what day they were run (e.g. todays backup will go in friday). The folders are very, very big and uncompressed (about 1.5gb). If I zip the folder manually, the folder will come down drastically (to about 30mb).

    My question is; is it possible to produce a batch script which will work out what day it is today and go into today’s folder, compress all of the backup files, make the output into 1 compressed zip file which will name it todays date and delete the old files?

    Sorry I know its a bit of a long one, but if anyone can help will be appreciated big time! Thanks!

    [Reply]

    Jason Faulkner reply on June 20, 2008 10:27 pm:

    Absolutely. There is a variable set in the script already called ‘DayOfWeek’. Just redirect your zipped file to to include the ‘DayOfWeek’ variable.
    For example, change the ‘BackupFileDestination’ variable line to something like this:

    SET BackupFileDestination=%BackupStorage%\%DayOfWeek%\Backup_%FileDate%_%txtBackup%.zip

    [Reply]

    Ikhlaq reply on June 24, 2008 8:40 am:

    thanks mate, didnt realise it was there!

    [Reply]

  18. Prabhu said:
    6/24/2008 6:59 am

    im getting an error “No configuration file found, missing: BackupConfig.txt”.. how to resolve it

    [Reply]

    Jason Faulkner reply on June 24, 2008 12:20 pm:

    There has to be a file named ‘BackupConfig.txt’ in the same directory as the batch script. The article has instructions on how to use this file.

    [Reply]

  19. Mike said:
    6/29/2008 12:21 am

    I also had the *Cannot find a* error. And as you mentioned, removing the exclamation mark from the phrase *DO NOT CLOSE* solved the issue. Nice script! Works well and unobtrusively. Thanks for sharing!!

    [Reply]

    Jason Faulkner reply on June 29, 2008 9:25 am:

    Since a lot of people seem to be having this issue, I’ve changed the script to remove the ‘!’.
    Thanks for the feedback.

    [Reply]

1 Trackback(s)

  1. Backup Platinum Review: Nice and Easy » PCMech on May 15, 2008

Post a Comment

Members


Search

Lijit Search

Featured Product of The Week

Build Your Own Network

Build Your Own Network

Free Weekly Newsletter

Weekly tech delivered straight to your inbox. Sign up and receive our free report: 20 Tips For Becoming a Technology Power User.

Name:
Email:
 

Now Playing on PCMech Video

Feature ImageIs Blocking Ads Right?

Feature ImageA Word On Instant Messaging

See All Videos | PCMech Channel Youtube Channel