Update an installation of PHP on Windows
It will come as no surprise that I operate my website on Windows and WordPress so it should come as no surprise that it also uses PHP. Part of running the server using PHP requires it to be updated from time to time so after toying with the idea for ages, I’ve finally got round to writing some PowerShell to do the job for me. Typically I could download and prepare the PHP installation in about 5 minutes so my site and server wouldn’t be offline for long but I see no reason to waste 5 minutes when I can run a script and it be done in less than 30 seconds.
So here’s a PowerShell script that will automatically update your existing installation of PHP on Windows 2012 R2.
It archives your current installation of PHP (identifying it by its version), downloads the latest release, unpacks it to a directory, copies over any additional files and extensions etc. from your existing installation of PHP, stops IIS, moves the new files and starts up IIS again. With a blank folder, it can also jsut download and unpack PHP in order to “install” it for use in debugging etc.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# Download the latest version of PHP and return the download file location. Function Get-LatestPHPVersion() { param( [System.IO.DirectoryInfo]$OutputFolder = 'D:\Temp', [int]$MajorVersion = 7, [int]$MinorVersion = 1, [int]$CompilerVersion = 14, [string]$BitVersion = 'x64' # x64 or x86 ) $Site = 'http://windows.php.net' $WindowsPHPDownloads = (Invoke-WebRequest -Uri $Site/download/).Links If ($LatestPHPVersion = $WindowsPHPDownloads | Where-Object {$_.href -match "php-$MajorVersion.$MinorVersion.(\d+)-nts-Win32-VC$CompilerVersion-$BitVersion.zip"}) { $Link = [uri]"$Site$($LatestPHPVersion.href)" $OutputFile = "$OutputFolder\$($Link.Segments[-1])" Invoke-WebRequest -Uri $Link -Method Get -OutFile $OutputFile -PassThru | Out-Null Return $OutputFile } Else { Return $null } } # Your existing installation of PHP. $PHPFolder = 'C:\PHP' # The temporary location for the new version of PHP to be extracted to. $TempPHPLocation = 'D:\TEMP\PHP' # Where the backups of the existing installation of PHP will be copied to (as a .zip) $BackupLocation = "D:\TEMP" If (Test-Path $PHPFolder\php.exe) { # Get current PHP version so we can name the backup file. $CurrentPHPVersionOutput = & $PHPFolder\php.exe --% -v $PHPVersionReg = [regex] '\d\.\d\.\d+' $CurrentPHPVersion = $PHPVersionReg.Match($CurrentPHPVersionOutput).Value # Backup the existing installation of PHP Write-Output "Backing up existing installation from `"$PHPFolder`" to `"$BackupLocation\PHP-$CurrentPHPVersion-NTS-x64$(Get-Date -Format "yyyMMdd").zip`"" Compress-Archive -Path $PHPFolder -DestinationPath "$BackupLocation\PHP-$CurrentPHPVersion-NTS-x64-$(Get-Date -Format "yyyMMdd").zip" -CompressionLevel Optimal -Force } # Download the latest version of PHP - this is always the non-thread-safe version. If you need something different, change the function. Write-Output "Downloading latest version of PHP...." #$NewPHPVersionArchive = Get-LatestPHPVersion -MajorVersion 5 -MinorVersion 6 -CompilerVersion 11 -BitVersion 'x86' $NewPHPVersionArchive = Get-LatestPHPVersion -MajorVersion 7 -MinorVersion 1 # default is VC14 x64 # If the download was successful, expand the zip file to the temporary location. If ($NewPHPVersionArchive) { Expand-Archive -Path $NewPHPVersionArchive -DestinationPath $TempPHPLocation -Verbose } Else { # IF the download fails, don't continue. Write-Error "No link from http://windows.php.net/ matched the desired version of PHP." -ErrorAction Stop } # Get the files from the new installation of PHP $Source = @(Get-ChildItem -Path $TempPHPLocation -Recurse) # Get the files from the existing installation of PHP - could be empty so force an array using @() $Destination = @(Get-ChildItem -Path $PHPFolder -Recurse) # Compare the lists of files to see what is different in each. # We do this since some files might be manually installed - we need these in the new version. $Differences = Compare-Object -ReferenceObject $Source -DifferenceObject $Destination # We're always going to be short of files such as php.ini so this is always copied from the existing version to the new version. Write-Output "Copying missing files to new PHP version..." Foreach ($Item in $Differences) { If ($Item.SideIndicator -eq '=>') { # Copy the missing item to the relative path in the new location. Copy-Item -Path $Item.InputObject.FullName -Destination $($Item.InputObject.FullName.Replace($PHPFolder, $TempPHPLocation)) -Verbose } Else { # If there's a new file in the new version that wasn't in the old version, let the console know. Write-Warning "$($Item.InputObject.FullName) is a new file in the latest PHP version." } } # Stop the W3SVC so there's no in-use versions of the CGI module. Write-Warning "Stopping World Wide Web Publishing Service" Stop-Service w3svc # Copy all of the files from the new version of PHP to the target folder. # We don't delete anything first in order to avoid issues with files not picked up in differences! Write-Output "Copying new PHP version..." Get-ChildItem -Path $TempPHPLocation -Recurse | Move-Item -Destination $PHPFolder -Force # Start the W3SVC again so sites are available again. Start-Service w3svc Write-Output "Done." |
It’s functional for me but might need some work for your use.