Output stream on powershell for SSH calls - php

My PHP script (in Linux) is not printing my values on screen, however it prints a Warning message.
e.g.
This is my php code:
$stream = ssh2_exec($connection, 'powershell "c:\remoteScript.ps1" -$NotificationID "5359f76f888ddf35b889dedf"');
$string = stream_get_contents($stream);
echo "Powershell output: ". $string;
This is my powershell code:
Write-Warning "This is a test"
And this is what PHP is writing:
Powershell output: WARNING: You should update your PowerShell to
PowerShell 2.0 version.
QUESTION: How can I catch the the stream returned by Powershell?

SOLUTION: we need to tell ssh2_exec whether to wait/block until the remote process finishes search for "block" on this page to see an example.
$stream = ssh2_exec($connection, 'powershell \'C:\scripts\remoteVeeamClientSummary.ps1\' -Client \''. $Client. '\' -NotificationID \''. $NotificationID. '\'');
stream_set_blocking($stream, true);
return stream_get_contents($stream);
and powershell:
Write-Output $result

Related

Php exec Powershell script Azure AZ commands do not run, all the other functions do

My PHP script
exec('powershell.exe -ExecutionPolicy Unrestricted -NoProfile -InputFormat none -file "..\..\scripts\addcustomer.ps1"', $output);
AZ function in the script:
$file = “$PSScriptRoot\Azure\pass.txt”
$azureuser = “user#contoso.com”
$Password = Get-Content $file | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential($azureuser, $Password)
Login-AzAccount -Credential $credential
New-AzDnsRecordSet -Name "$name" -RecordType A -ZoneName "contoso.co" -ResourceGroupName "RG" -Ttl 3600 -DnsRecords (New-AzDnsRecordConfig -IPv4Address "$ipaddress")
The $output does not display any output of this function. I confirm that if I run the script manually, everything works.
Many thanks.
Use exec($your_command, $output, $error_code) and see what $error_code contains. It may just be because powershell.exe isn't in the PATH env variable in PHP.
Try to put the full path to your PowerShell executable, typically something like this:
<?php
// A default powershell path in case "where powershell" doesn't work.
define('POWERSHELL_EXE', 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe');
// Find the path to powershell with the "where" command.
$powershell_exe = exec('where powershell');
if ($powershell_exe === false) {
$powershell_exe = POWERSHELL_EXE;
}
// Also check that the path to your script can be found.
// If it doesn't then you can use realpath() to get the
// full path to your script.
$cmd = $powershell_exe .
' -ExecutionPolicy Unrestricted -NoProfile -InputFormat none' .
' -file "..\..\scripts\addcustomer.ps1"';
$last_line = exec($cmd, $full_output, $error_code);
// Then check if $last_line !== false and check $error_code to see
// what happened.
var_export([
'$cmd' => $cmd,
'$last_line' => $last_line,
'$full_output' => $full_output,
'$error_code' => $error_code,
]);
Another important point: Has the user running your PHP code enought rights to do what you are doing in your PS1 script?
You may need to run your PowerShell script with elevation privilege or another user. I never did that but perhaps this topic could help:
PHP command to execute powershell script as admin

PHP exec, output errors only

I am using PHP exec to run a Powershell script to create a new user that is being submitted via a HTML form. What I am looking to do is output only errors from this command on the webpage so any IT team member can see if anything went wrong. Here is what I have:
$psPath = 'c:\\Windows\\System32\WindowsPowerShell\v1.0\\powershell.exe -version 5';
$psDIR = "d:\\wamp64\\www\\includes\\";
$psScript = "NewHire.ps1";
$runCMD = $psPath. ' -ExecutionPolicy RemoteSigned '.$psDIR.$psScript
$createuser = exec($runCMD.' 2>&1', $out);
When I do a var_dump($out), it shows both the output and errors. I tried changing it to exec($runCMD.' &1', $out) but it shows output only. If I try exec($runCMD.' 2>', $out), it doesn't run my command. Is there a way I can display errors only in the $out varible?
Try this,
exec($runCMD."2>&1 1>/dev/null ",$out);
maybe this might help
public static function exec_alt($cmd)
{
exec($cmd, $output);
if (!$output) {
/**
* FIXME: for some reason exec() returns empty output array #mine,'s machine.
* Somehow proc_open() approach (below) works, but doesn't work at
* test machines - same empty output with both pipes and temporary
* files (not we bypass shell wrapper). So use it as a fallback.
*/
$output = array();
$handle = proc_open($cmd, array(1 => array('pipe', 'w')), $pipes, null, null, array('bypass_shell' => true));
if (is_resource($handle)) {
$output = explode("\n", stream_get_contents($pipes[1]));
fclose($pipes[1]);
proc_close($handle);
}
}
return $output;
}
if you on windows 7, you might need to:
Disabling User Account Control (UAC)
run
UserAccountControlSettings.exe
at
C:\Windows\System32\UserAccountControlSettings.exe
and select "Never notify"
Found out this works for stderr only:
exec($runCMD.' >&2' , $out);

sudo_exec returns nothing

I try to ping www.google.de with shell_exec and store the result into a variable but i get no result back from shell_exec.
<?php
$ping = 'sudo ping -c 4 ';
$url = 'www.google.de';
$command = $ping . $url;
$ping_result = shell_exec($command);
$datei = fopen("/var/www/myProject/result_ping","w") or die ("Could not open file!");
sleep(10);
if ($datei == false)
{
$ping_result = "Cannot open file!";
}
else
{
fwrite ($datei , $ping_result);
fclose ($datei);
}
echo $command; //Output: sudo ping -c 4 www.google.de
echo $ping_result; //Output: nothing
?>
The file result_ping has all rights (chmod 777).
Maybe the webserver is not allowed to execute ping?
Add 2>&1 to your command to ensure you're not getting an error message that shell_exec would filter off:
$command = $ping . $url . ' 2>&1';
shell_exec will return NULL in case of error. With that modification you redirect any error message to normal output, thus forcing shell_exec show every message you would normally get on a console session.

strikethrough characters on php stream output

I am using php ssh2_exec to execute a ps aux command on a remote Linux server... The server initiating the connection is Ubuntu 14.04 and the server I am communicating with is Centos 6.6.
Both systems are fully updates and I am using the following versions of PHP and Apache on the Ubuntu system:
apache2 2.4.7-1ubuntu4.5
libapache2-mod-php5 5.5.9+dfsg-1ubuntu4.11
php5 5.5.9+dfsg-1ubuntu4.11
I am using the following code to send the command and capture the stream:
echo '<pre>';
$stream = ssh2_exec($connection, $command);
stream_set_blocking($stream, true);
$stream_out = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO);
while($line = fgets($stream_out)) {
flush();
echo $line."<br />";
}
echo '</pre>';
echo '<br />';
unset($connection);
$command is defined as: $command = "ps aux |sed '/[.*]/d'";
The command runs, but the returned text, while showing the processes running on the remote system, is stricken through text... Below is a link to an image of what is happening.
https://www.joeman1.com/images/stikethoughtest.png
(I would have posted the image, but Im new around here and need some reputation ;)).
This does not happen when I use php -f on the command line, just in a browser - IE, Firefox, and Chrome was tested.
Any ideas on how to resolve this? If you need more information, please let me know.
Thanks!
Joe
Try checking your HTML Source. Or:
<?php
echo '<pre>';
$stream = ssh2_exec($connection, $command);
stream_set_blocking($stream, true);
$stream_out = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO);
while($line = fgets($stream_out)) {
flush();
// convert the string to HTML Entities
// Since you're getting data from a stream, no telling what might come out.
echo htmlentities($line)."<br />";
}
echo '</pre>';
echo '<br />';
unset($connection);
?>

allow php invoked by exec() to write to console

I invoked a php file by exec() doing this :
<?php
$cmd = "php -q nah.php";
exec($cmd);
echo "lalal";
?>
and the nah.php has this :
<?php
echo "yaya";
sleep(3);
?>
It does sleep for 3 seconds but the file can echo out to the command.
How can I do echo the output from nah.php
If you want to capture the output of another process, then you can use backticks
$output=`command line`;
or capture it with exec()
exec('command line', $output);
However, both of these techniques only give the output when the external process has run to completion. If you want to grab the output as it happens, you can use popen (or proc_open for more control), e.g. something like this
$handle = popen('command line 2>&1', 'r');
while (!feof($handle))
{
$read = fread($handle, 2096);
echo $read;
}
pclose($handle);
The 2>&1 at the end of the command line is a handy idiom if running within a shell like bash. It redirects stderr to stdout, so any errors the command generates will be returned to PHP. There are more advanced ways to capture stderr, this just makes it easy.
Change your first script to:
<?php
$cmd = "php -q nah.php";
echo `$cmd`;
echo "lalal";
exec() creates a new console and executes the php file there, it returns the output in an array (One element per line return) that is passed in as a second argument. So if you change your code to:
<?php
$output = array();
$cmd = "php -q nah.php";
exec($cmd, $output);
$lines = count($output);
for($i = 0; $i < $lines; $i++)
echo $output[$i];
echo "lalal";
?>

Categories