0

I am creating a process where an AWS instance can be started if currently stopped, then backed up on-premises via an rsync-based script, and then stopped when done. I also want the script to be executable via a web interface. Given that the backup process potentially takes several hours, the web interface must start a process that quickly takes the user to a landing page and doesn't stop the backup process if the browser tab or window is closed.

I have written the substantive code to accomplish this, but am running into problems when executing the code via PHP. I am on a Windows Server 2012 R2 running PHP 7.3.29, using PowerShell 7 and AWS Tools for PowerShell 4.1.18.

I have been trying to route around issues with spaces, quotes, and passing parameters, so the current implementation involves a few steps of indirection.

Here is the PHP code that kicks off the process:

exec('C:\scripts\Active_Unscheduled_Scripts\Instance_Backups\start_backup_and_stop_MSSC_Test_2.bat');

Here is the Windows batch file it executes:

Start ""  "C:\scripts\Active_Unscheduled_Scripts\Instance_Backups\backup_and_stop_MSSC_Test_2.ps1"

Here is the PowerShell script it executes:

Try 
{
    Invoke-Expression "C:\'Program Files'\PowerShell\7\pwsh.exe C:\scripts\Active_Unscheduled_Scripts\Instance_Backups\backup_and_stop_master.ps1 `'[instance ID redacted]`' `'MSSC Test 2`'"
    'Step 0 completed successfully' | Out-File C:\scripts\errors.txt -Append
}

Catch
{
    'Step 0 Error ' + $error[0] | Out-File C:\scripts\errors.txt -Append
    Exit
}

Here is the PowerShell script it executes in the Try:

$instanceId = $args[0]
$instanceName = $args[1]

[functioning email notification code, aka Step 1, removed for brevity]

Set-Variable -Scope global -Name status -Value ""

Try
{
    $status = Get-EC2InstanceStatus -InstanceId $instanceId -IncludeAllInstances $true -Region us-east-2
    $status.Status.Status.Value | Out-File C:\scripts\status.txt -Append
    $status.InstanceState.Name.Value | Out-File C:\scripts\status.txt -Append
    'Step 2 completed successfully' | Out-File C:\scripts\errors.txt -Append
}

Catch 
{
    ('Step 2 Error ' + $error[0]) | Out-File C:\scripts\errors.txt -Append  
    Exit
}

When I open up a Command Prompt and run start_backup_and_stop_MSSC_Test_2.bat, everything works as I expect. I receive the kickoff email (removed above) that confirms the parameter values, errors.txt is filled with Step 1 completed successfully Step 2 completed successfully Step 0 completed successfully, and status.txt is filled with not-applicable and stopped.

However, when I execute the process via PHP, I get the kickoff email, but errors.txt is filled with Step 1 completed successfully Step 2 Error The type initializer for 'Amazon.Runtime.Internal.Settings.PersistenceManager' threw an exception. Step 0 completed successfully

There are practically no Google results for this error. The one substantive post on the error concerns the Region parameter on a different commandlet, which I'm explicitly passing in even though it's not required.

Neil Wehneman
  • 154
  • 1
  • 12
  • How is php executed? What user is running php? And does that user have a profile loaded? – MisterSmith Feb 02 '22 at 21:07
  • The user running the PHP script is ScriptRunner, the user we generally use for running scripts. (So says get_current_user().) It is the same user I've been logged in as I installed PowerShell 7.0 and AWS Tools for PowerShell. The PHP is executed by a user navigating to a web page served up by Apache 2.4 running on the Windows Server 2012 R2. I specifically access the web page from my primary workstation, rather than from my remote connection to the server itself. I don't understand what you mean by "Does that user have a profile loaded?" What type of profile should I be looking for? – Neil Wehneman Feb 02 '22 at 21:21
  • 1
    By "user profile" they mean the executing user's OS profile. If the Apache is running as a service account, and within the service you are able to tell PHP to execute a line of code as another user, depending on how the service actually executes something on behalf of another user, the executing user's profile may not be loaded in favor of the web service's user profile in the child process. AWS config is (by default) tied to configurations under `%USERPROFILE%\.aws` for each user. You need to confirm whether the `ScriptRunner` user profile is getting loaded when the script is run or not. – codewario Feb 02 '22 at 21:41

0 Answers0