Skip to content
David Kittell
David Kittell

Application & System: Development / Integration / Orchestration

  • Services
    • Application Development
    • Online Application Integration
  • Code
  • Online Tools
  • Tech Support
David Kittell

Application & System: Development / Integration / Orchestration

PowerShell – Download Latest WordPress Plugin XML List

Posted on November 19, 2015November 23, 2015 By David Kittell

This script below is an extension of this script PowerShell Download Latest WordPress Plugin.

This download script uses two XML files, primary XML will serve as the configuration file where the secondary will have the plugins that we currently have installed and then this script will run through the XML and download any free plugins that need an update.

This script will read the latest version of the plugin from WordPress.org and update the XML file’s element and if and do not match it will download the update then update the element in the XML file.

Source Code

<?xml version="1.0" encoding="UTF-8"?>
<pluginconfig>
  <SFTP>
    <FTPHost>ftp://192.168.1.16/html/</FTPHost>
    <FTPUser>UserName</FTPUser>
    <FTPPass>Password</FTPPass>   
    <FTPSource>C:\temp\WordPress\WordPressUpdates\</FTPSource>
  </SFTP>
</pluginconfig>
<?xml version="1.0" encoding="UTF-8"?>
<pluginlist>
  <plugin>
    <title>Akismet</title>
    <url>https://wordpress.org/plugins/akismet/</url>
    <downloadurl>https://downloads.wordpress.org/plugin/akismet.3.1.5.zip</downloadurl>
    <currentversion>3.1.5</currentversion>
    <installedversion>3.1.4</installedversion>
  </plugin>
</pluginlist>
clear

# Variables - Start
$XMLServerConfig = "c:\temp\WordPress\WordPress_Free_Plugin_Config.xml"
$XMLPluginList = "c:\temp\WordPress\WordPress_Free_Plugin_List.xml"
$UpdatedPluginFound = 0
# Variables - Stop


# Plugin Config (XML) - Start
[xml]$pluginconfig = Get-Content $XMLServerConfig

foreach ($obj in $pluginconfig.pluginconfig.SFTP)
{
    $FTPHost = $obj.FTPHost
    $FTPUser = $obj.FTPUser
    $FTPPass = $obj.FTPPass
    $UploadFolder = $obj.FTPSource
}
# Plugin Config (XML) - Start

# Plugin List (XML)
[xml]$pluginlist = Get-Content $XMLPluginList

# Update current version on our XML from WordPress.org - Start
foreach ($obj in $pluginlist.pluginlist.Plugin)
{
    #[System.Console]::Write("`r`nPlugin: {0}", $obj.title)
    #[System.Console]::Write("`r`n     URL: {0}", $obj.url)
    #[System.Console]::Write("`r`n     Installed Version: {0}", $obj.installedversion)

    # Plugin URL
    $URI = $obj.url

    # Plugin Download URL
    $DownloadURL = $obj.downloadurl

    # This is the plugin version to check against
    $PluginVersion = $obj.installedversion
        
    $HTML = Invoke-WebRequest -Uri $URI 

    #$HTML.Links.Count
    $PluginName = $HTML.AllElements | WHERE  -Property itemprop -eq "name" | Select -First 1 -ExpandProperty innerText
    $PluginName = $PluginName.Trim()

    $downloadURL = $HTML.Links | WHERE -Property itemprop -eq "downloadUrl" | SELECT -Property href
    $downloadURLText = $HTML.Links | WHERE -Property itemprop -eq "downloadUrl" | SELECT -Property innerText

    $downloadURL = $downloadURL -replace "@{href=", ""
    $downloadURL = $downloadURL -replace "}", ""
    $downloadURL = $downloadURL.Trim()

    $downloadURLText = $downloadURLText -replace "@{innerText=Download Version ", ""
    $downloadURLText = $downloadURLText -replace "}", ""
    $downloadURLText = $downloadURLText.Trim()

    $pluginlist.pluginlist.Plugin | Where-Object {$_.title -eq $obj.title} | ForEach-Object {$_.currentversion = $downloadURLText}
    $pluginlist.pluginlist.Plugin | Where-Object {$_.title -eq $obj.title} | ForEach-Object {$_.downloadurl = $downloadURL}    

    $pluginlist.Save("C:\temp\WordPress_Free_Plugin_List.xml")   
   
}
# Update current version on our XML from WordPress.org - Stop

# Download latest version if different - start
foreach ($obj in $pluginlist.pluginlist.Plugin)
{
    if($obj.installedversion -eq $obj.currentversion)
    {
        #Write-Output "`r`nLastest Version, move on to the next link"
    }
    else
    {
        [System.Console]::Write("`r`nPlugin: {0}", $obj.title)
        [System.Console]::Write("`r`n     URL: {0}", $obj.url)
        [System.Console]::Write("`r`n     Current Version: {0}", $obj.installedversion)
        [System.Console]::Write("`r`n     Installed Version: {0}", $obj.installedversion)
        Write-Output "`r`nOut Dated Version, will now download"

        # URL Parameter
        $WebURL = $obj.downloadurl
    
        # If directory doesn't exist create the directory
        if((Test-Path $UploadFolder) -eq 0)
            {
                mkdir $UploadFolder;
                #cd $UploadFolder;
            }

        # We assume the file you download is named what you want it to be on your computer
        $FileName = [System.IO.Path]::GetFileName($WebURL)

        # Concatenate the two values to prepare the download
        $FullFilePath = "$($UploadFolder)$($FileName)"

        # Give a basic message to the user to let them know what we are doing
        Write-Output "Downloading '$WebURL' to '$FullFilePath'"
        
        $uri = New-Object "System.Uri" "$WebURL" 
        $request = [System.Net.HttpWebRequest]::Create($uri) 
        $request.set_Timeout(15000) #15 second timeout 
        $response = $request.GetResponse() 
        $totalLength = [System.Math]::Floor($response.get_ContentLength()/1024) 
        $responseStream = $response.GetResponseStream() 
        $targetStream = New-Object -TypeName System.IO.FileStream -ArgumentList $FullFilePath, Create 
        $buffer = new-object byte[] 10KB 
        $count = $responseStream.Read($buffer,0,$buffer.length) 
        $downloadedBytes = $count 
    
        while ($count -gt 0) 
            {         
                [System.Console]::Write("`r`nDownloaded {0}K of {1}K", [System.Math]::Floor($downloadedBytes/1024), $totalLength) 
                $targetStream.Write($buffer, 0, $count) 
                $count = $responseStream.Read($buffer,0,$buffer.length) 
                $downloadedBytes = $downloadedBytes + $count 
            } 
  
        $targetStream.Flush()
        $targetStream.Close() 
        $targetStream.Dispose() 
        $responseStream.Dispose() 

        # Give a basic message to the user to let them know we are done
        Write-Output "`r`nDownload complete"

        # Extract Download - Start
        $Shell = new-object -com shell.application
  
        # Get the name of the Zip file
        $Zip = $Shell.NameSpace($FullFilePath)
     
        #Expand/Extract each file from the zip file    
        foreach($Item in $Zip.items())
            {
                $Shell.Namespace($UploadFolder).copyhere($Item)
            }
        # Extract Download - Stop              

        $pluginlist.pluginlist.Plugin | Where-Object {$_.title -eq $obj.title} | ForEach-Object {$_.installedversion = $obj.currentversion}   
        $pluginlist.Save($XMLPluginList)

        Remove-Item $FullFilePath
    }
}
# Download latest version if different - stop

#Upload Plugins - Start
$webclient = New-Object System.Net.WebClient 
$webclient.Credentials = New-Object System.Net.NetworkCredential($FTPUser,$FTPPass)  

$SrcEntries = Get-ChildItem $UploadFolder -Recurse
$Srcfolders = $SrcEntries | Where-Object{$_.PSIsContainer}
$SrcFiles = $SrcEntries | Where-Object{!$_.PSIsContainer}

# Create FTP Directory/SubDirectory If Needed - Start
foreach($folder in $Srcfolders)
{    
    $SrcFolderPath = $UploadFolder  -replace "\\","\\" -replace "\:","\:"    
    $DesFolder = $folder.Fullname -replace $SrcFolderPath,$FTPHost
    $DesFolder = $DesFolder -replace "\\", "/"
   # Write-Output $DesFolder

    try
        {
            $makeDirectory = [System.Net.WebRequest]::Create($DesFolder);
            $makeDirectory.Credentials = New-Object System.Net.NetworkCredential($FTPUser,$FTPPass);
            $makeDirectory.Method = [System.Net.WebRequestMethods+FTP]::MakeDirectory;
            $makeDirectory.GetResponse();
            #folder created successfully
        }
    catch [Net.WebException]
        {
            try {
                #if there was an error returned, check if folder already existed on server
                $checkDirectory = [System.Net.WebRequest]::Create($DesFolder);
                $checkDirectory.Credentials = New-Object System.Net.NetworkCredential($FTPUser,$FTPPass);
                $checkDirectory.Method = [System.Net.WebRequestMethods+FTP]::PrintWorkingDirectory;
                $response = $checkDirectory.GetResponse();
                #folder already exists!
            }
            catch [Net.WebException] {
                #if the folder didn't exist
            }
        }
}
# Create FTP Directory/SubDirectory If Needed - Stop

# Upload Files - Start
foreach($entry in $SrcFiles)
{
    $SrcFullname = $entry.fullname
    $SrcName = $entry.Name
    $SrcFilePath = $UploadFolder -replace "\\","\\" -replace "\:","\:"
    $DesFile = $SrcFullname -replace $SrcFilePath,$FTPHost
    $DesFile = $DesFile -replace "\\", "/"

   # Write-Output $DesFile


    $uri = New-Object System.Uri($DesFile) 
    $webclient.UploadFile($uri, $SrcFullname)

}
# Upload Files - Stop
Originally Posted on November 19, 2015
Last Updated on November 23, 2015
All information on this site is shared with the intention to help. Before any source code or program is ran on a production (non-development) system it is suggested you test it and fully understand what it is doing not just what it appears it is doing. I accept no responsibility for any damage you may do with this code.

Related

Code PowerShell WordPress XML

Post navigation

Previous post
Next post

Related Posts

Ektron – User Access List

Posted on August 20, 2014October 26, 2015

Similar to Ektron SQL – List All Users If you simply need a list of all of your CMS users whether they are admin or otherwise this script will help SELECT [user_name] AS ‘Username’, ([first_name] + ‘ ‘ + [last_name]) AS ‘Name’ FROM [user_to_group_tbl] utgt LEFT OUTER JOIN [usergroups] ug…

Read More

Compare Number Array Against Column

Posted on February 23, 2015October 26, 2015

I recently needed to see what zip codes in Michigan were missing from a table of zip codes that I have in a database. First I had to get an official list of zip codes for Michigan then came up with this script to figure out which of the official…

Read More

GitLab – 502 Whoops, GitLab is taking too much time to respond

Posted on September 26, 2016

If you get the “502 Whoops, GitLab is taking too much time to respond” message, first thing to try is sudo gitlab-ctl restart IF the restart doesn’t help then try sudo gitlab-ctl reconfigure Typically one of the two will fix the problem. All information on this site is shared with…

Read More

Code

Top Posts & Pages

  • PowerShell - Rename Pictures to Image Taken
  • Front Page
  • C# - Start/Stop/Restart Services
  • MacPorts / HomeBrew - Rip CD tracks from terminal
  • PowerShell - Show File Extensions

Recent Posts

  • Javascript – Digital Clock with Style
  • BASH – Web Ping Log
  • BASH – Picture / Video File Name Manipulation
  • Mac OSX Terminal – Create SSH Key
  • Bash – Rename Picture

Top Posts

  • PowerShell - Rename Pictures to Image Taken
  • C# - Start/Stop/Restart Services
  • MacPorts / HomeBrew - Rip CD tracks from terminal
  • PowerShell - Show File Extensions
  • SQLite - Auto-Increment / Auto Generate GUID
©2025 David Kittell | WordPress Theme by SuperbThemes