Skip to content

Automated WordPress Installation With Windows & WP CLI

Introduction

This post is very similar to my friend’s previous post based around an automated WordPress installation, however just to quote him “It won’t work on Windows, so sell it and buy a Mac.” I wanted to explore if a similar process could be implemented for Windows.

Granted bash can still be run on Windows, with command line interpreters such as Cygwin or a virtual machine but who really wants to bloat their PC with third party programs?

Using Batch alongside WP-CLI we can automate the installation of WordPress as well as various other housekeeping tasks.

Getting ready!

For this to work you will need to install php , composer and WP-CLI, forget about their guide as we are going manual for this (it’s Windows after all)!

I won’t cover how to install php as there are plenty of tutorials on how to achieve this, plus installing php is out of the scope of this post.

To install wp-cli you first have to download the phar file you can do that here wp-cli.phar place this file in a logical place for instance mine is C:\wp-cli\wp-cli.phar now you can run this in the cmd by typing php C:\wp-cli\wp-cli.phar however, that is far too long to type out.

To fix this we have to set up a batch file in the same directory, this will act as an alias for the phar file. Name the file wp.bat and paste the following into the contents of the file.

@ECHO OFF
php "%~dp0wp-cli.phar" %*

Once you have WP-CLI where you want it, you will need to allow windows to access its commands globally, to do this we will need to amend the Path environment variable.environment

Navigate to your System’s Properties by either Pressing and holding down the start key and pressing Pause/Break, alternatively you can open the start menu, right click computer and select properties.

On the left, click advanced system properties, this will load a system properties dialog box from here select the tab labeled Advanced. Click Environment Variables, under the System variables section scroll down to the variable named Path and edit it.

Under the variables value append the path to your WP-CLI’s folder, not forgetting the ; at the end of each path for example mine is ;C:\wp-cli

When you add in the path be sure there are no spaces between the previous and added path! (Credit to Peter Sorensen)

Confirm all of the dialogs and test it out.

Go to the command line and type wp you should see a list of commands if not you may require a reboot or your path maybe incorrect!

Getting Set!

Ok, so you have WP-CLI Installed and you’re getting ready to automate the WordPress installation on Windows!

This next part is a little more specialized and tailor made to each PC however I have added my code to show you the concept feel free to use it don’t forget to edit the paths!

Pretty urls did prove to be a pain to get working while making this script fortunately I found a great fix by specifying a new environment variable WP_CLI_CONFIG_PATH I was able to enable apache’s mod_rewrite more about wp-cli’s config here

WP_CLI_CONFIG_PATH=%USERPROFILE%\.wp-cli\config.yml

You will need to create the config.yml file in the designated path and enable apache’s mod_rewrite by adding the following to the file:

apache_modules:
   - mod_rewrite

To use the code below will require you to setup an “alias”, which in short means updating your PATH environment variable to include the folder where you store the script. This way you can access the file anywhere you are in the file system like so: install projectname “install” is the name I gave my bat file and “projectname” is the name of the new project.

If you want to use this code for your own benefit remember to change the Important variables to match your local hosting solution.


@echo off

:: FOR THIS SCRIPT TO GENERATE PRETTY URLS YOU MUST ADD WP_CLI_CONFIG_PATH=%USERPROFILE%\.wp-cli\config.yml to your user/system environment variables
:: in config.yml you must specify apache_modules: - mod_rewrite
    
:: Important variables

SET ROOT=C:\www
SET DBUSER=root
SET DBPASS=root
SET USER=ltconsulting
SET EMAIL=wpadmin@indigotree.co.uk

:: Password Generator
Setlocal EnableDelayedExpansion
Set _RNDLength=10
Set _Alphanumeric=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
Set _Str=%_Alphanumeric%987654321
:_LenLoop
IF NOT "%_Str:~18%"=="" SET _Str=%_Str:~9%& SET /A _Len+=9& GOTO :_LenLoop
SET _tmp=%_Str:~9,1%
SET /A _Len=_Len+_tmp
Set _count=0
SET _RndAlphaNum=
:_loop
Set /a _count+=1
SET _RND=%Random%
Set /A _RND=_RND%%%_Len%
SET _RndAlphaNum=!_RndAlphaNum!!_Alphanumeric:~%_RND%,1!
If !_count! lss %_RNDLength% goto _loop
Set PASSWORD=!_RndAlphaNum!

:: Was an argument passed?
IF [%1] == [] GOTO fatal

echo.
echo.
echo   __      __                   __  ____                                
echo  /\ \  __/\ \                 /\ \/\  _`\                              
echo  \ \ \/\ \ \ \    ___   _ __  \_\ \ \ \ \ \_ __    __    ____    ____  
echo   \ \ \ \ \ \ \  / __`\/\`'__\/'_` \ \ ,__/\`'__\/'__`\ /',__\  /',__\ 
echo    \ \ \_/ \_\ \/\ \L\ \ \ \//\ \L\ \ \ \/\ \ \//\  __//\__, `\/\__, `\
echo     \ `\___x___/\ \____/\ \_\\ \___,_\ \_\ \ \_\\ \____\/\____/\/\____/
echo      '\/__//__/  \/___/  \/_/ \/__,_ /\/_/  \/_/ \/____/\/___/  \/___/ 
echo.

echo --------------------------------------------------------------------------------
echo Install WordPress 4.0
echo.

:: Navigate to the local project folder
cd %ROOT%
    
:: Set the name of the new install
SET NAME=%1

:: Set the name of the new install
SET DBNAME=wp_%NAME%
    
echo.
echo --------------------------------------------------------------------------------
echo Installing WordPress..
echo.
    
:: Create directory
mkdir %NAME%
    
:: Go into directory
cd %NAME%
    
:: Download WordPress
call wp core download
    
:: Generate wp-config
:: We need to escape the php we pass in to the wp-config or we will get syntax errors
(echo define^^^('WP_DEBUG', true^^^);^
& echo define^^^('DISALLOW_FILE_EDIT', true ^^^);) | wp core config --dbname=%DBNAME% --dbuser=%DBUSER% --dbpass=%DBPASS% --extra-php
    
:: Create DB
call wp db create
    
:: Install wordpress
call wp core install --url="http://localhost/%NAME%" --title="%NAME%" --admin_user="%USER%" --admin_password="%PASSWORD%" --admin_email="%EMAIL%"
    
echo.
echo --------------------------------------------------------------------------------
echo Cleaning Plugins
echo.
    
:: Discourage search engines
call wp option update blog_public 0
    
:: show only 6 posts on an archive page
call wp option update posts_per_page 6

:: Delete akismet and hello dolly
call wp plugin delete akismet
call wp plugin delete hello

:: Add our own plugins here

echo.
echo --------------------------------------------------------------------------------
echo Installing Lt-theme
echo.

:: set pretty urls
:: we set pretty urls here to give it some time to complete before flushing the permalinks later
:: unfortunatly call does not work on this command so we have to open and run in a seperate cmd window
start cmd /c wp rewrite structure /%%postname%%/ --hard

:: Add and activate your own themes here

:: Clear Window
cls
    
:: ASCII ART

echo.
echo.
echo.
echo   __      __                   __  ____                                
echo  /\ \  __/\ \                 /\ \/\  _`\                              
echo  \ \ \/\ \ \ \    ___   _ __  \_\ \ \ \ \ \_ __    __    ____    ____  
echo   \ \ \ \ \ \ \  / __`\/\`'__\/'_` \ \ ,__/\`'__\/'__`\ /',__\  /',__\ 
echo    \ \ \_/ \_\ \/\ \L\ \ \ \//\ \L\ \ \ \/\ \ \//\  __//\__, `\/\__, `\
echo     \ `\___x___/\ \____/\ \_\\ \___,_\ \_\ \ \_\\ \____\/\____/\/\____/
echo      '\/__//__/  \/___/  \/_/ \/__,_ /\/_/  \/_/ \/____/\/___/  \/___/ 
echo.
echo --------------------------------------------------------------------------------
echo Installation is complete. Your username/password have been added to your clipboard and are listed below.
echo.
echo Username: %USER%
echo Password: %PASSWORD%
echo.

echo have a nice day :)

echo.

:: Add to clipboard
echo Username: %USER% Password: %PASSWORD% | clip
    
:: start the project in browser
start http://localhost/%NAME%

:: unfortunatly call does not work on this command so we have to open and run in a seperate cmd window
start cmd /c wp rewrite flush --hard

pause
    
goto:eof

:fatal
echo.
echo --------------------------------------------------------------------------------
echo Please specify a name for your WordPress Install
echo.
goto:eof
    
:END

Extra credit

You can add your own themes from github/bitbucket using git clone!


:: Go to themes directory
cd wp-content/themes

:: pull down the theme
call git clone https://github.com/vafour/vafpress-framework-theme-boilerplate.git new-theme

:: Navigate into the theme
cd new-theme

:: Remove the generated git folder
rmdir /s /q .git
    
:: Run package installers if your theme requires it
:: call npm install
:: call gulp

cd %ROOT%/%NAME%
:: Activate the theme
call wp theme activate lt-theme

Go!

It doesn’t stop with installation you can perform many other tasks such as backups, plugin management, manage posts and many other commands the full list can be found here: WP-CLI

I have recently used this same technique to transfer WordPress sites from my development machine to a server.

By using 7zip’s command line interface I can zip my files up send them to a server where a php file unzips the files to the root. (Useful stuff!)

In an ideal world I would use git to manage my files, however some hosting companies don’t have git integration or web hooks yet.

Hopefully this post will give you a good understanding of how powerful and flexible WP-CLI can be.

Please feel free to take this and expand on it!

Comments

  1. David Hewitt

    Peter Sorensen

    Thanks for the guide! Two things that tripped me up:

    1. Make sure there’s no space between the added path and the previous path (/previous_path;C:\wp-cli\bin;)
    2. If grabbing via Git, you may need to run `composer install` in the wp-cli folder in order to install it’s dependencies.

  2. David Hewitt

    David Hewitt

    Hi Peter,

    Glad you liked the guide!

    I have updated the post and credited you. Thanks!

  3. David Hewitt

    Steve

    Hi David,

    Thanks for the AWESOME guide.
    When trying to implement a couple of advanced features, I ran into an issue with Windows.

    I cannot run this for example:
    call wp post delete $(wp post list –post_type=page –posts_per_page=1 –post_status=publish –pagename=”sample-page” –field=ID –format=ids)

    Any idea how to use that on a Windows?

    Thanks!

    1. David Hewitt

      David Hewitt

      Glad you enjoyed it.

      Batch unfortunately doesn’t have a nice way to do this.. (no surprise there)

      There’s a few errors in your code the arguments need to be specified with two dashes like so:

      --post_name="sample-page"

      Also it’s post_name not pagename

      wp cli post list

      The Batch equivalent for doing this task is:

      for /f %%i in ('wp post list --post_type^="page" --posts_per_page^=1 --post_status^="publish" --post_name^="sample-page" --field^=ID --format^=ids') do set PAGE=%%i
      
      call wp post delete %PAGE% --force

      The first call runs our list command which echos the id for the sample page and sets it to the variable PAGE we need to escape the arguments equals with a ^.

      Finally we call the post delete command passing in that variable.

      if your goal is to just remove the sample posts/pages that come with WordPress it might be simpler to run.

      call wp post delete 1 --force
      call wp post delete 2 --force
    2. David Hewitt

      Steve

      Thanks for the answer! That seems to do the trick.

      Well I was basically copying this line from your colleague’s post:
      https://indigotree.co.uk/automated-wordpress-installation-with-bash-wp-cli/

      It’s probably a bit outdated or simply written for Mac rather than Windows so that’s where the pagename came from.

      Now I’m trying to set the page for posts and page on front options, but for some reason it doesn’t work.

      I have this: (after the homepage was created successfully)

      :: set homepage as front page
      call wp option update show_on_front page
      
      :: set front to be the new page we created
      for /f %%i in ('wp post list --post_type^="page" --posts_per_page^=1 --post_status^="publish" --post_name^="home" --field^=ID --format^=ids') do set HOMEPAGE=%%i
      
      call wp option update page_on_front %HOMEPAGE%

      The Batch syntax is the default syntax for the windows command line / bat files?
      Isn’t there an option add-in the above type of code via PHP with WP-CLI? That would be a bit easier for me 🙂
      (Or I would have to get a Mac heh)

      Thanks!

    3. David Hewitt

      David Hewitt

      No problem glad it helped.

      Had to look this up and it turns out pagename does also work so guess i was wrong there :/

      It looks like you are missing the quotes for “page” you need this to set the option in the back end.

      call wp option update show_on_front "page"
      
      for /f %%i in ('wp post list --post_type^="page" --posts_per_page^=1 --post_status^="publish" --pagename^="home" --field^=ID --format^=ids') do set HOMEPAGE=%%i
      
      call wp option update page_on_front %HOMEPAGE%

      It is possible to write out these commands using php via Symphony’s command line service in fact internally we are working on our own phar which will allow us all to run these commands using php regardless of the operating system you have.

    4. David Hewitt

      steve

      Hi David,

      Sweet. I tried with no quotes, and with single quotes, but that seems to work properly!
      I’ve used it to create multiple pages and assign 2 (blog/homepage) to their respective default wp options.

      Is there any way you’d recommend to learn that syntax?
      I’m used to develop websites and use WP-CLI occasionally, but would love to learn how to extend these kinds of automation scripts.

  4. David Hewitt

    Jonathan Perlman

    Hey.

    I’m using this script in a windows lab environment and everything works except the flushing of the permalinks. When my students go to the “hello world” single post, they’re getting a 404.

    I make them go to settings and permalinks then save the page and then they can see the “hello world” single post and any page they create.

    Here are my permalink related lines.

    
    :: set pretty urls
    :: we set pretty urls here to give it some time to complete before flushing the permalinks later
    :: unfortunatly call does not work on this command so we have to open and run in a seperate cmd window
    start cmd /c wp rewrite structure "/%%year%%/%%monthnum%%/%%day%%/%%postname%%/" --hard
    
    :: unfortunatly call does not work on this command so we have to open and run in a seperate cmd window
    start cmd /c wp rewrite flush --hard
    

    Thanks for your help!

    1. David Hewitt

      David Hewitt

      Hi Jonathan,

      Remove the quotes around the structure:

      start cmd /c wp rewrite structure /%%year%%/%%monthnum%%/%%day%%/%%postname%%/ --hard

      Another problem could be that you do not have mod_rewrite enabled.
      At the top of the example I explain how to set this up. more information here

      :: FOR THIS SCRIPT TO GENERATE PRETTY URLS YOU MUST ADD WP_CLI_CONFIG_PATH=%USERPROFILE%\.wp-cli\config.yml to your user/system environment variables
      :: in config.yml you must specify apache_modules: – mod_rewrite

      you can check the config is setup correctly by going to the terminal and typing wp --info

  5. David Hewitt

    Ross

    Hey David, I just rolled my own before stumbling across this…

    I thought I’d give a pointer to something I had just resolved, you can actually use call on this line:

    `start cmd /c wp rewrite structure /%%postname%%/ –hard`

    It because you need to double escape the % when using `call`, so this would be:

    `call wp rewrite structure /%%%%postname%%%%/`

    Ugly, for sure haha.. 🙂

    Thanks anyway for the article, a couple of things I can pinch from here!

Have Your Say

Your email address will not be published. Required fields are marked *