3
votes

I have a powershell script which outputs a video file duration. Running this script gives me the expected result.

$Folder = 'C:\my\path\to\folder'
$File = 'sample1_1280_720.mp4'
$LengthColumn = 27
$objShell = New-Object -ComObject Shell.Application 
$objFolder = $objShell.Namespace($Folder)
$objFile = $objFolder.ParseName($File)
$Length = $objFolder.GetDetailsOf($objFile, $LengthColumn)
Write-Output $Length

In a php file, I'm trying to save this output to a variable.

<?php
$var = shell_exec("powershell -File C:\my\path\to\psFile.ps1 2>&1");
echo "<pre>$var</pre>";
?>

The string output I get from shell_exec is the text you see when you start powershell from cmd. Windows PowerShell Copyright (C) 2016 Microsoft Corporation. All rights reserved. Any suggestions on how to extract the video duration?

1
What happens if you add -NoLogo to your PowerShell command in the shell_exec()? - Jeff Zeitlin
"powershell -NoLogo -File ..." - gives the same output - Thomas
This suggests that something about the way shell_exec() is handling the command line you're passing it is ... odd. If you add code to your script to output the results to a file, does the file get created and does it contain what you expect it to? - Jeff Zeitlin
Yes, this was my backup plan which I've successfully tested. Piped it with | Out-File -FilePath C:\... -Append. The result creates a file if not exists and appends otherwise. - Thomas

1 Answers

2
votes

Using your PS code

$Folder = 'C:\my\path\to\folder'
$File = 'sample1_1280_720.mp4'
$LengthColumn = 27
$objShell = New-Object -ComObject Shell.Application
$objFolder = $objShell.Namespace($Folder)
$objFile = $objFolder.ParseName($File)
$Length = $objFolder.GetDetailsOf($objFile, $LengthColumn)
$Length

I'm able to get the file length using PS -File and -Command. I added a few other flags you may want or need. You shouldn't need to use redirection 2>&1 to get your variable from PS to PHP. It is most likely the reason you are getting the logo.

function PowerShellCommand($Command)
{
    $unsanitized = sprintf('powershell.exe -NonInteractive -NoProfile -ExecutionPolicy Bypass -Command "%s"', $Command);

    return shell_exec($unsanitized);
}

function PowerShellFile($File)
{
    $unsanitized = sprintf('powershell.exe -NonInteractive -NoProfile -ExecutionPolicy Bypass -File "%s"', $File);

    return shell_exec($unsanitized);
}

// Can use relative paths
echo PowerShellCommand("./psFile.ps1");
// Be sure to escape Windows paths if needed
echo PowerShellFile("C:\\my\\path\\to\\folder\\psFile.ps1");

Returning $Length in all three ways work for me

$Length
return $Length
Write-Output $length