Search code examples
phppowershellpowercli

Call PowerCLI script from PHP


I want to build a small webinterface to grant our users certain permissions for handling linked clones. On the webserver (Windows Datacenter 2008 R2 running IIS), I have installed PowerCLI. The website runs under my user-account (domain admin), to rule out any permission issues.

My PHP file looks like this:

$PowerCliCommand="C:\\WINDOWS\\system32\\windowspowershell\\v1.0\\powershell.exe -PSConsoleFile \"C:\\Progra~2\\VMware\\Infrastructure\\vSphere PowerCLI\\vim.psc1\" -file C:\inetpub\lcmgmt\listlcs.ps1";
echo $PowerCliCommand . "<br>";
exec($PowerCliCommand, $Output, $ErrorReturned);
echo "<pre>";
print_r($Output);

print_r($ErrorReturned);
echo "</pre>";

I call the consolefile from \progra~2, as \program files (x86) kept bugging me with issues.

The output of PHP in my browser is as follows:

C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -PSConsoleFile C:\Progra~2\VMware\Infrastructure\vSphere PowerCLI\vim.psc1" -file C:\inetpub\lcmgmt\listlcs.ps1
Array 
(   
    [0] => Connect-VIserver : The term 'Connect-VIserver' is not recognized as
> the name of
    [1] =>  a cmdlet, function, script file, or operable program. Check the spelling of th
    [2] => e name, or if a path was included, verify that the path is correct and try agai
    [3] => n.
    [4] => At C:\inetpub\lcmgmt\listlcs.ps1:4 char:2
    [5] => +  Connect-VIserver -server "MyVSserver"

The PowerShell script called looks like this:

Connect-VIserver -server "MyVSserver"
$VDICluster=get-cluster -Name "MyCluster"
get-vm -location  $VDICluster -name "Server*"

When calling the full command (the first line in my PHP output) from a command prompt on the webserver, running on my account (the same account used in IIS), everything works fine, I get the information on my linked clones. As you can see the browser output reports that the PowerCLI commands are unknown. I'm completely lost, anybody has experience on this?


Solution

  • It appears the VMware PowerCLI installer has not added itself correctly to the user/machine environment variables, which are used to populate $Env:PSModulePath when PowerShell loads. The paths stored here determine where PowerShell can look for modules, and also aid cmdlet autoloading.

    To resolve this in a way that persists across sessions, you can run the following:

    $Current = [Environment]::GetEnvironmentVariable('PSModulePath','Machine')
    $Current += ';C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Modules'
    [Environment]::SetEnvironmentVariable('PSModulePath',$Current,'Machine')
    

    The gets the existing content of PSModulePath at a SYSTEM wide level, as you'd see here:

    enter image description here

    and appends the VMware PowerCLI module path to it, finally setting it by calling the SetEnvironmentVariable method.