Executing powershell script from PHP with arguments - php

I have been wracking my brain and my pc on this one, hoping someone can help me out here.
I have a PHP site that needs to execute a powershell script which in turn executes and executable.
the PHP that calls the .ps1 is
define('updaterPath','C:\\artemis\\DbUpdateUtility1.0.12.2');
define('outputLocation',updaterPath.'\\Output');
$CMD = updaterPath . '\\ArtemisXmlUtil.exe';
$action = 'import';
$args= ' -f' . outputLocation;
$psScriptPath = '.\\get-process.ps1';
$query = shell_exec("powershell -command $psScriptPath -cmd '$CMD' -action '$action' -paras '$args' < NUL");
my .ps1 script is:
param(
[string]$CMD,
[string]$action,
[string]$paras
)
& $CMD $action $paras
Right now, when I echo the full command, it looks perfect and can be copied and pasted into powershell and runs successfully, but when I try to actually execute it from php, it runs with only the $CMD variable and ignores the $action and $paras.
I tried concactenating the variables all into 1 string, but that fails as not even being able to see the executable.
the full command shouls look like:
C:\artemis\DbUpdateUtility1.0.12.2\ArtemisXmlUtil.exe import -fC:\artemis\DbUpdateUtility1.0.12.2\Output

Ok, figured this one out on my own.
The problem is how the command was being executed. Using the "&" forced powershell to ignore the parameters being pass into the script. The correct way, since the command is an executable anyhow, was to build the entire command as a string and pass it all at once to the ps1 file and then change the ps1 file to use the invoke-expression commandlet.
param(
[string]$CMD
)
Invoke-expression $CMD

Related

Running a program using shell_exec in PHP, how to know if process is done?

Hi I am running a python script inside PHP using the shell_exec command,
However how would I know if the execution of the python has been completed already?
Here is portion of my code
$py_path = 'app/public/engines/validation/delta';
chdir($py_path);
$py_var = 'python scraped_data.py';
$exec = shell_exec($py_var);
How would I know if the python is finished its processing?
I wanted to know because I have a series of processes to run but it needs the first process to be completed first.
Thank You,
If you check php.net description of shell_exec() is:
shell_exec — Execute command via shell and return the complete output as a string
So you can edit your python script to output true or 1 once script is finished.
then you can simply code something like this:
$py_path = 'app/public/engines/validation/delta';
chdir($py_path);
$py_var = 'python scraped_data.py';
$exec = shell_exec($py_var);
If($exec){
//Execute another script or do what you wish
}

Running Windows Powershell from PHP unaware of Current Profile

I have a few functions and variables defined for all machine users like so:
Set-Content $Profile.AllUsersCurrentHost (Get-Content path/to/myprofile.ps1)
Let's call one of my defined functions Do-Stuff.
This works very well. And anytime Powershell console is called up, and you type "Do-Stuff"+ENTER, it works.
Now I have tried to call this function from PHP a few ways, and I'm having a couple of problems. Consider this:
$res = shell_exec( 'Powershell Do-Stuff');
print_r($res);
What I get is this error:
Do-Stuff: The term 'Do-Stuff' is not recognized as the name of a
cmdlet, function, script file, or operable program....
I've tried also:
$res = shell_exec( 'Powershell -File path/to/script.ps1');
print_r($res);
If the file script.ps1 does contain Do-Stuff or any of the other defined functions, what I get is the same type of error message.
Now what this tells me is that the calling PHP script is NOT recognized as a Windows machine user, and the currently loaded $Profile is NOT being applied.
So what's the solution to this? How can I get the loaded profile for current user or all users to be applied to the running PHP script?
I have a workaround for this issue, using -NoProfile, then dot-sourcing the Profile file.
In the below example, the profile file is includes.ps1:
$cmdlet = 'Do-Stuff';
$cmd = 'Powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "& { . \includes.ps1; '.$cmdlet.' }"';
shell_exec($cmd);
It may prove useful for you to enclose this in a reusable function:
<?php
function run_ps_command($cmdlet, $async=true){
$cmd = 'Powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "& { . \Includes.ps1; '.$cmdlet.' }"';
if($async){
$WshShell = new COM("WScript.Shell");
$res = $WshShell->Run( $cmd, 0, false);
}else{
$res = shell_exec($cmd);
}
return $res;
}
?>
The $async argument allows you to run this command without having PHP wait for the output of the PowerShell script. The advantage is that PHP code execution is faster, the disadvantage is: you've no idea if your script ran successfully, or got into any trouble on the way ;)

Calling Perl script with PHP, passing variables and put result into a file

I am near losing my mind cause of a perl script I want to call via PHP.
I have a PHP Form where I put in a MySQL Query which gets stored in a file and choosing some variables.
If I call any SHELL command like "top" ... everything works fine, but as soon as I try to call my perl script with variables, there are no results at all.
The file where the results should get stored stays empty.
That's the calling part from the PHP File:
if (isset($_POST['submit'])) {
$file = 'query.sql';
$query = $_POST['query'];
file_put_contents($file, $query);
$command = "perl /home/www/host/html/cgi/remote-board-exec.pl -sqlfileexec query.sql > /home/www/host/html/cgi/passthrutest.txt";
exec($command, &$ausgabe, $return_var);
There is no error message and i already tried debug things, but nothing helped :(
Are you sure that perl is being executed? Perhaps you ought to replace the command with 'which perl' just to make sure, and to use the full path to Perl. Another idea is to make sure your:
perl script is executable (use chmod)
ensure it has '#!/usr/bin/perl' (or wherever your path to perl is)
change the command to "/home/www/host/cgi/remote-board-exec.pl..." without the perl command
dump the contents of your output array ($ausgabe) as if the command fails to execute you may find out what is happening.

Passing Admin username & password using shell_exec

I have a Powershell script which when I run directly on the Web Server (Windows 2008R2, IIS) completes successfully. I am now trying to launch the script from a php page. The script launches and I can see the process in Task Manager just fine.
When I call the script using shell_exec from a php page, it fails with the error
"Exception calling "FindOne" with "0" argument(s): "An operations error occurred."
I can see from Task Manager that the script is running as the user IUSR. I'm pretty sure that this is the reason the script is failing, as to complete successfully it needs to be run as a domain admin.
I am calling the script with the following command
$username = the currently logged in user on the page (authenticated against AD)
$newPword1 = new user password
$query = shell_exec("powershell -command $psScriptPath '$username' '$newPword1' < NUL");
Powershell Script:
#*=============================================================================
#* PARAMETER DECLARATION
#*=============================================================================
param([string]$username,[string]$pword)
#*=============================================================================
#* INITIALISE VARIABLES
#*=============================================================================
# Increase buffer width/height to avoid Powershell from wrapping the text before
# sending it back to PHP (this results in weird spaces).
$pshost = Get-Host
$pswindow = $pshost.ui.rawui
$newsize = $pswindow.buffersize
$newsize.height = 3000
$newsize.width = 400
$pswindow.buffersize = $newsize
#*=============================================================================
#* SCRIPT BODY
#*=============================================================================
$root = [ADSI]'LDAP://<server>/<DNtoOU>'
$searcher = new-object System.DirectoryServices.DirectorySearcher($root)
$searcher.filter = "(&(objectCategory=person)(sAMAccountName=$username))"
$user = $searcher.findone()
$userDN = $user.path
$user=[ADSI]$($userDN)
$user.SetPassword($pword)
$user.setinfo()
write-host "success"
Is it possible to pass a Domain Admin username/password to run powershell as using the above command, thereby allowing the script to run successfully?
One of several ways is to use PowerShellRunAs.
Edit: It is documented, you can use the powershell script as-is or modify it to suit your needs (e.g. not using a password file).
In more detail, instead of this:
shell_exec("powershell -command $psScriptPath …")
You could use this:
shell_exec("powershell -command "Start-Process powershell.exe -argumentlist '-command $psScriptPath …' -Credential 'TheDomain\TheUser'")
But to avoid the password prompt, use PowerShellRunAs as per the documentation:
shell_exec("powershell -command "Start-Process powershell.exe -argumentlist '-command $psScriptPath …' -Credential (.\PowerShellRunAs.ps1 -get contoso\svc_remoterestart \\fileserver\share\file.pwd)")
Alternatively, you could incorporate the start-process … -credential … into your own script. That way you can keep your shell_exec call simple as before, and only a limited part of your script will run under the user with different (higher) privileges.
Should you use the script as is, remember to first run it with -set instead of -get, in order to set the password file.

Rails, PHP and parameters

I working in Rails and I need to call to an PHP-script.
I can connect to the script like this:
system('php public/myscript.php')
But I need to send some parameters with it.
How do I do that?
Thanks
You can provide command-line arguments to your PHP script:
system('php public/myscript.php arg1 arg2')
They will be available from your PHP code like this:
echo $argv[0]; // public/myscript.php
echo $argv[1]; // arg1
echo $argv[2]; // arg2
You can just specify the parameters on the command line, such as system('php -f public/myscript.php argument1 argument2 [...]') and they will be available in the $argv[] array, starting from $argv[1]. See the doc page here for more info.
Yes its right way to use system('php public/myscript.php arg1 arg2') as SirDarius answered .
but system command will return the true or false in that case.
system() will return TrueClass or FalseClass and display output, try it on console .
I suggest , You can use the open method on any URL to call it, so you can call your PHP script using that:
require 'open-uri'
open('YOUR PHP SCRIPT PATH WITH PARAMETER') do |response|
content = response.read
end

Categories