Home » Php » php – Separate Powershell Output in a Dropdown Menu

php – Separate Powershell Output in a Dropdown Menu

Posted by: admin February 25, 2020 Leave a comment

Questions:

I am getting my Printer Information from the following Powershell Command:

<?php
$Comment = Shell_Exec ('powershell.exe -Command "Get-Printer -ComputerName servername | select Comment | ConvertTo-Html | Format-Table"');          
?>

and trying to put them into a Dropdown Menu:

<select id="comment">
  <option value="comment"><?php echo $Comment; ?></option>
</select>`

But i can’t find a way to separate the Output with one Value in each Box.

The Output / Data from the shell call looks like this:

Comment                                                         
-------                                                         
2483                                                                                                                 
2066                                                                                                                                               1737
How to&Answers:

If you want to create a select dropdown menu, you need to create several entries like this:

<label for="printer">Choose a printer:</label>

<select id="printer" name="printer">
  <option value="printer-1">Printer 1</option>
  <option value="printer-2">Printer 2</option>
  <option value="printer-x">The last printer</option>
</select>

But in any case, I would avoid your PHP calling some Powershell commands on each page load. This is very very slow and your page won’t be reactive at all.

If you need this list to be updated then consider having a configuration file which is written with a cron task (scheduled task) from time to time. Then your PHP code in the page should just load the array of printers by requiring this configuration file.

For example, you could generate the list of printers by saving it in JSON format that can easily be read by PHP.

The command would become:

powershell.exe -Command "Get-Printer -ComputerName yourprintserver | select Name,DriverName,PortName,Comment | ConvertTo-Json"

Example of output:

[
    {
        "Name":  "PDF-cadwork",
        "DriverName":  "PDF-XChange 4.0 Lite",
        "PortName":  "PDF-XChange4",
        "Comment":  ""
    },
    {
        "Name":  "OKI C9800(PS)",
        "DriverName":  "OKI C9600(PS)",
        "PortName":  "IP_192.168.11.99",
        "Comment":  ""
    },
    {
        "Name":  "OKI C9800(PCL)",
        "DriverName":  "OKI C9800(PCL)",
        "PortName":  "IP_192.168.11.99",
        "Comment":  ""
    },
    {
        "Name":  "Microsoft XPS Document Writer",
        "DriverName":  "Microsoft XPS Document Writer v4",
        "PortName":  "PORTPROMPT:",
        "Comment":  ""
    },
    {
        "Name":  "HP LaserJet M570 PS",
        "DriverName":  "HP Universal Printing PS",
        "PortName":  "IP_192.168.11.96",
        "Comment":  ""
    },
    {
        "Name":  "HP Color LaserJet CM6030 MFP PCL6",
        "DriverName":  "HP Color LaserJet CM6030 MFP PCL6",
        "PortName":  "192.168.11.95",
        "Comment":  ""
    },
    {
        "Name":  "Canon iPF510",
        "DriverName":  "Canon iPF510",
        "PortName":  "IP_192.168.11.97",
        "Comment":  ""
    }
]

As you see, I actually haven’t got the Comment field filled but it would be your case.

Let’s say this file is then saved to printers.json by your scheduled task. To do that, just redirect the result to your file with the > operator:

powershell.exe -Command "Get-Printer -ComputerName yourprintserver | select Name,DriverName,PortName,Comment | ConvertTo-Json" > C:\path-to-php-site\config\printers.json

We can then load it in PHP:

<?php
// Get the list of printers from the automatically updated JSON file.
// Caution: PowerShell creates the file in "UCS-2 LE BOM" format.
//          PHP wants to read UTF-8 so we'll have to convert it.

// Read the JSON created by the scheduled task running PowerShell.
$printers_json_ucs2_le_bom = file_get_contents('printers.json');

// Convert to UTF-8 encoding.
$printers_json_utf8_bom = mb_convert_encoding(
    $printers_json_ucs2_le_bom, // Source content.
    'UTF-8',                    // Destination encoding.
    'UCS-2LE'                   // Source encoding.
);

// Remove the BOM marker which is still there.
$printers_json_utf8 = preg_replace('/\x{FEFF}/u', '', $printers_json_utf8_bom);

// Decode the JSON to a PHP variable.
$printers = json_decode($printers_json_utf8);

/**
 * Get the HTML code to create a select drop down to choose a printer.
 *
 * @param array $printers The list of printers.
 * @param string $name The name of the field in the form.
 * @param string $id THe id of the fiedl in the form.
 * @param string $lable The label to display before the select drop down.
 *
 * @return string The HTML code to put in your form.
 */
function get_printers_select(array $printers, $name = 'printer', $id = 'printer', $label = 'Select your printer')
{
    $html = '';
    if (!empty($label)) {
        $html .= '<label for="' . $id . '">' . htmlspecialchars($label) . "</label>\n";
    }
    $html .= '<select id="' . $id . '" name="' . $name . "\">\n";
    foreach ($printers as $printer) {
        $html .= '  <option value="' . htmlentities($printer->Comment) . '">' .
                 htmlspecialchars($printer->Comment) . "</option>\n";
    }
    $html .= "</select>\n";
    return $html;
}

// Your HTML and <form> should come here...

print get_printers_select($printers);

And this outputs this HTML if I replace $printer->Comment by $printer->Name:

<label for="printer">Select your printer</label>
<select id="printer" name="printer">
  <option value="PDF-cadwork">PDF-cadwork</option>
  <option value="OKI C9800(PS)">OKI C9800(PS)</option>
  <option value="OKI C9800(PCL)">OKI C9800(PCL)</option>
  <option value="Microsoft XPS Document Writer">Microsoft XPS Document Writer</option>
  <option value="HP LaserJet M570 PS">HP LaserJet M570 PS</option>
  <option value="HP Color LaserJet CM6030 MFP PCL6">HP Color LaserJet CM6030 MFP PCL6</option>
  <option value="Canon iPF510">Canon iPF510</option>
</select>